191 lines
7.6 KiB
Python
191 lines
7.6 KiB
Python
import logging
|
|
from odoo import models, fields, api
|
|
from odoo.addons.pos_enterprise.utils.date_utils import compute_seconds_since
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PosPreparationState(models.Model):
|
|
_inherit = 'pos.prep.state'
|
|
|
|
kds_accumulated_time = fields.Integer(string="KDS Accumulated Time", default=0)
|
|
|
|
@api.model
|
|
def _load_pos_preparation_data_fields(self):
|
|
fields_list = super()._load_pos_preparation_data_fields()
|
|
if fields_list:
|
|
fields_list.append('kds_accumulated_time')
|
|
return fields_list
|
|
|
|
def _update_kds_report(self, pdis_state, old_last_stage_change=None):
|
|
"""
|
|
Synchronous KDS report update.
|
|
Optimized to minimize database calls and avoid redundant aggregations.
|
|
"""
|
|
if not pdis_state.prep_line_id:
|
|
return
|
|
|
|
order_line = pdis_state.prep_line_id.pos_order_line_id
|
|
if not order_line:
|
|
return
|
|
|
|
order = order_line.order_id
|
|
stage = pdis_state.stage_id
|
|
if not stage:
|
|
return
|
|
|
|
display = stage.prep_display_id
|
|
if not display:
|
|
return
|
|
|
|
stage_ids = display.stage_ids.ids
|
|
if not stage_ids:
|
|
return
|
|
|
|
first_stage_id = stage_ids[0]
|
|
last_stage_id = stage_ids[-1]
|
|
second_last_stage_id = stage_ids[-2] if len(stage_ids) > 1 else False
|
|
|
|
# Determine if this is a completion or a reset
|
|
is_completed = False
|
|
if len(stage_ids) > 1:
|
|
if stage.id == last_stage_id:
|
|
is_completed = True
|
|
elif second_last_stage_id and stage.id == second_last_stage_id and not pdis_state.todo:
|
|
is_completed = True
|
|
else:
|
|
if not pdis_state.todo:
|
|
is_completed = True
|
|
|
|
is_reset = (stage.id == first_stage_id and pdis_state.todo)
|
|
|
|
if not (is_completed or is_reset):
|
|
return
|
|
|
|
display_id = display.id
|
|
order_id = order.id
|
|
order_name = order.name or order.pos_reference or "Order"
|
|
|
|
KdsLineReport = self.env['pos.kds.report.line'].sudo()
|
|
KdsOrderReport = self.env['pos.kds.report.order'].sudo()
|
|
|
|
try:
|
|
if is_reset:
|
|
_logger.info("KDS Reset: Order %s on display %s", order_name, display.name)
|
|
line_report = KdsLineReport.search([
|
|
('pos_order_line_id', '=', order_line.id),
|
|
('prep_display_id', '=', display_id)
|
|
], limit=1)
|
|
if line_report:
|
|
line_report.write({'state': 'in_prep'})
|
|
pdis_state.kds_accumulated_time = line_report.preparation_time
|
|
|
|
order_report = KdsOrderReport.search([
|
|
('pos_order_id', '=', order_id),
|
|
('prep_display_id', '=', display_id)
|
|
], limit=1)
|
|
|
|
if order_report:
|
|
order_report.write({'state': 'in_prep'})
|
|
return
|
|
|
|
# --- Completed ---
|
|
prep_time = order_line.preparation_time
|
|
svc_time = order_line.service_time
|
|
|
|
# Fallback timing logic
|
|
if prep_time == -1:
|
|
if old_last_stage_change:
|
|
prep_time = int(compute_seconds_since(old_last_stage_change))
|
|
else:
|
|
prep_time = int(compute_seconds_since(pdis_state.last_stage_change))
|
|
|
|
if svc_time == -1:
|
|
if is_completed and stage.id == last_stage_id and old_last_stage_change:
|
|
svc_time = int(compute_seconds_since(old_last_stage_change))
|
|
else:
|
|
svc_time = 0
|
|
|
|
prep_time = max(0, prep_time)
|
|
svc_time = max(0, svc_time)
|
|
comp_time = prep_time + svc_time
|
|
|
|
line_report = KdsLineReport.search([
|
|
('pos_order_line_id', '=', order_line.id),
|
|
('prep_display_id', '=', display_id)
|
|
], limit=1)
|
|
|
|
vals = {
|
|
'pos_order_id': order_id,
|
|
'pos_order_line_id': order_line.id,
|
|
'product_id': order_line.product_id.id,
|
|
'prep_display_id': display_id,
|
|
'preparation_time': prep_time,
|
|
'service_time': svc_time,
|
|
'completion_time': comp_time,
|
|
'completion_datetime': fields.Datetime.now(),
|
|
'state': 'done',
|
|
}
|
|
|
|
if line_report:
|
|
# Accumulate if it was already existing (e.g. from a previous completion before reset)
|
|
# Note: We only accumulate if the current session's time is valid.
|
|
new_prep = line_report.preparation_time + prep_time
|
|
new_svc = line_report.service_time + svc_time
|
|
new_comp = new_prep + new_svc
|
|
|
|
_logger.info("KDS Re-Completed (Accumulating): Order %s, Line %s: %ss + %ss = %ss",
|
|
order_name, order_line.product_id.name, line_report.completion_time, comp_time, new_comp)
|
|
|
|
line_report.write({
|
|
'preparation_time': new_prep,
|
|
'service_time': new_svc,
|
|
'completion_time': new_comp,
|
|
'completion_datetime': vals['completion_datetime'],
|
|
'state': 'done',
|
|
})
|
|
# Update local comp_time for order report update below
|
|
comp_time = new_comp
|
|
else:
|
|
_logger.info("KDS Completed: Order %s, Line %s: Prep=%ss, Svc=%ss, Total=%ss",
|
|
order_name, order_line.product_id.name, prep_time, svc_time, comp_time)
|
|
KdsLineReport.create(vals)
|
|
|
|
# Update Order Report
|
|
order_report = KdsOrderReport.search([
|
|
('pos_order_id', '=', order_id),
|
|
('prep_display_id', '=', display_id)
|
|
], limit=1)
|
|
|
|
if order_report:
|
|
# Update state and accumulate/max time
|
|
# We use the max completion time across all lines of this order for this display.
|
|
# If we just updated a line to 219s, and order report was 204s, it becomes 219s.
|
|
if comp_time > order_report.completion_time or order_report.state != 'done':
|
|
order_report.write({
|
|
'completion_time': max(comp_time, order_report.completion_time),
|
|
'state': 'done',
|
|
'completion_datetime': vals['completion_datetime'],
|
|
})
|
|
else:
|
|
KdsOrderReport.create({
|
|
'pos_order_id': order_id,
|
|
'prep_display_id': display_id,
|
|
'preparation_time': prep_time, # Simplified: will be updated by other lines if needed
|
|
'service_time': svc_time,
|
|
'completion_time': comp_time,
|
|
'state': 'done',
|
|
'completion_datetime': vals['completion_datetime'],
|
|
})
|
|
|
|
except Exception as e:
|
|
_logger.error("KDS reporting failed for order %s: %s", order_name, e, exc_info=True)
|
|
|
|
def _record_status_change_prep_time(self, pdis_state):
|
|
super()._record_status_change_prep_time(pdis_state)
|
|
self._update_kds_report(pdis_state)
|
|
|
|
def _record_stage_change_prep_time(self, pdis_state, old_last_stage_change, prep_order_completion_time):
|
|
super()._record_stage_change_prep_time(pdis_state, old_last_stage_change, prep_order_completion_time)
|
|
self._update_kds_report(pdis_state, old_last_stage_change=old_last_stage_change)
|