feat: add deadlock protection for prep state updates and implement status transition logic in POS KDS order component
This commit is contained in:
parent
bf343df752
commit
4badd35b54
@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import pos_order
|
||||
from . import pos_prep_display
|
||||
from . import pos_prep_state
|
||||
|
||||
22
models/pos_prep_state.py
Normal file
22
models/pos_prep_state.py
Normal file
@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from odoo import models, api
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class PosPreparationState(models.Model):
|
||||
_inherit = 'pos.prep.state'
|
||||
|
||||
def change_state_status(self, todos, prep_display_id):
|
||||
if self:
|
||||
# Sort IDs to guarantee consistent locking order and avoid deadlocks
|
||||
sorted_ids = tuple(sorted(self.ids))
|
||||
self.env.cr.execute('SELECT id FROM pos_prep_state WHERE id IN %s FOR UPDATE', [sorted_ids])
|
||||
return super().change_state_status(todos, prep_display_id)
|
||||
|
||||
def change_state_stage(self, stages, prep_display_id):
|
||||
if self:
|
||||
# Sort IDs to guarantee consistent locking order and avoid deadlocks
|
||||
sorted_ids = tuple(sorted(self.ids))
|
||||
self.env.cr.execute('SELECT id FROM pos_prep_state WHERE id IN %s FOR UPDATE', [sorted_ids])
|
||||
return super().change_state_stage(stages, prep_display_id)
|
||||
@ -43,6 +43,50 @@ patch(Order.prototype, {
|
||||
return [{ text: String(parsed), colorIndex: 0 }];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
async changeStateStageAnimation(states) {
|
||||
if (states.length === this.props.order.states.length) {
|
||||
await new Promise((resolve, reject) => {
|
||||
this.state.changeStageTimeout = setTimeout(async () => {
|
||||
try {
|
||||
this.lastStageChange = await this.prepDisplay.changeStateStage(states);
|
||||
this.clearChangeTimeout();
|
||||
resolve();
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
} else {
|
||||
this.lastStageChange = await this.prepDisplay.changeStateStage(states);
|
||||
}
|
||||
},
|
||||
async changeOrderlineStatus(state) {
|
||||
if (this.actionInProgress) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.actionInProgress = true;
|
||||
const lastStage = this.prepDisplay.lastStage.id;
|
||||
if (this.props.order.stage.id === lastStage) {
|
||||
return;
|
||||
}
|
||||
const newState = !state.todo;
|
||||
state.todo = newState;
|
||||
if (state.prep_line_id.combo_line_ids.length > 0) {
|
||||
this.getChildPreparationLineStates(state.prep_line_id).forEach((state_line) => {
|
||||
state_line.todo = newState;
|
||||
});
|
||||
}
|
||||
|
||||
if (this.props.order.states.some((state) => state.todo)) {
|
||||
await this.prepDisplay.syncStateStatus(this.props.order.states);
|
||||
} else {
|
||||
await this.changeStateStageAnimation(this.props.order.states);
|
||||
}
|
||||
} finally {
|
||||
this.actionInProgress = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user