86 lines
3.8 KiB
Python
86 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Fix for KDS (Kitchen Display System) / Preparation Display bug:
|
|
|
|
Problem:
|
|
When Table X has N items that are already in the "Completed" stage on the KDS,
|
|
and the customer adds a new item, Odoo creates a new pos.prep.order for the
|
|
same pos.order. The KDS frontend receives a LOAD_ORDERS notification and reloads
|
|
all open prep states for that pos.order via get_preparation_display_order().
|
|
|
|
The _get_open_orderlines_in_display() filter excludes ONLY states where:
|
|
todo=False AND stage=last_stage
|
|
|
|
Items that were advanced to the last stage via the stage-advance button have:
|
|
todo=True, stage=last_stage <-- these ARE returned and shown as "To Prepare"
|
|
|
|
So the previously completed items (stage-advanced to last stage, todo=True) reappear
|
|
on the KDS card alongside the new item, effectively resetting their visual status.
|
|
|
|
Fix:
|
|
When a new pos.prep.order is created for an existing pos.order (meaning new items
|
|
are being added to a table that already sent items to the kitchen), we find all
|
|
existing prep states for all PREVIOUS prep orders of the same pos.order that are
|
|
currently at the LAST stage (regardless of todo status). These represent items
|
|
the kitchen staff already processed. We set their todo=False to ensure the filter
|
|
in _get_open_orderlines_in_display() correctly excludes them from future reloads.
|
|
"""
|
|
from odoo import models
|
|
|
|
|
|
class PosOrder(models.Model):
|
|
_inherit = 'pos.order'
|
|
|
|
def _process_preparation_changes(self, options):
|
|
"""
|
|
Override to fix KDS stage reset bug.
|
|
|
|
Before calling super(), we record existing prep orders for this pos.order.
|
|
After super() runs (which may create a new prep order for new items),
|
|
we mark all states in the OLD prep orders that are at the last stage
|
|
as todo=False so they won't reappear on the KDS display.
|
|
"""
|
|
self.ensure_one()
|
|
|
|
# Capture existing prep orders BEFORE super() creates a new one
|
|
existing_prep_orders = self.env['pos.prep.order'].search([
|
|
('pos_order_id', '=', self.id)
|
|
])
|
|
|
|
# Run the original logic (may create new pos.prep.order + lines + states)
|
|
result = super()._process_preparation_changes(options)
|
|
|
|
# If new items were added (flag_order_added), super() created a new prep order
|
|
if result.get('order_added') and existing_prep_orders:
|
|
# Fetch all prep displays relevant to this order
|
|
prep_displays = self.env['pos.prep.display'].search([
|
|
'|',
|
|
('pos_config_ids', '=', False),
|
|
('pos_config_ids', 'in', self.config_id.id),
|
|
])
|
|
|
|
for prep_display in prep_displays:
|
|
last_stage_id = (
|
|
prep_display.stage_ids.ids[-1]
|
|
if prep_display.stage_ids.ids else False
|
|
)
|
|
if not last_stage_id:
|
|
continue
|
|
|
|
# Find all states from the OLD prep orders that are at the last stage
|
|
# with todo=True — these are items the kitchen advanced to "Completed"
|
|
# stage but which would still be returned by _get_open_orderlines_in_display
|
|
# because the filter only excludes (todo=False AND stage=last).
|
|
old_prep_lines = existing_prep_orders.mapped('prep_line_ids')
|
|
states_at_last_stage = self.env['pos.prep.state'].search([
|
|
('prep_line_id', 'in', old_prep_lines.ids),
|
|
('stage_id', '=', last_stage_id),
|
|
('todo', '=', True),
|
|
])
|
|
|
|
if states_at_last_stage:
|
|
# Mark them as done so the KDS filter hides them
|
|
states_at_last_stage.write({'todo': False})
|
|
|
|
return result
|