Files
enterprise-addons/pos_enterprise/tests/test_pos_preparation_display.py
T

154 lines
6.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
from odoo.tests import tagged
from odoo import Command, fields
@tagged('post_install', '-at_install')
class TestPosPreparationDisplay(TestPoSCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.config = cls.basic_config
def test_load_preparation_display_model(self):
config1 = self.env['pos.config'].create({
'name': 'rest1',
'active': False
})
config2 = self.env['pos.config'].create({
'name': 'rest2'
})
config3 = self.env['pos.config'].create({
'name': 'rest3'
})
config4 = self.env['pos.config'].create({
'name': 'rest4'
})
# pos preperation display linked to specific configs
display1 = self.env['pos.prep.display'].create({
'name': 'Preparation Display 1',
'pos_config_ids': [Command.link(config1.id)]
})
display2 = self.env['pos.prep.display'].create({
'name': 'Preparation Display 2',
'pos_config_ids': [Command.link(config2.id)]
})
display3 = self.env['pos.prep.display'].create({
'name': 'Preparation Display 3',
'pos_config_ids': []
})
display4 = self.env['pos.prep.display'].create({
'name': 'Preparation Display 4',
'pos_config_ids': [Command.link(config3.id)]
})
config2.open_ui()
config3.open_ui()
config4.open_ui()
self.assertEqual({d['id'] for d in config2.current_session_id.load_data([])['pos.prep.display']},
{display1.id, display2.id, display3.id})
self.assertEqual({d['id'] for d in config3.current_session_id.load_data([])['pos.prep.display']},
{display1.id, display3.id, display4.id})
self.assertEqual({d['id'] for d in config4.current_session_id.load_data([])['pos.prep.display']},
{display1.id, display3.id})
def test_preparation_updated_on_stage_change(self):
prep_display = self.env['pos.prep.display'].create({
'name': 'Preparation Display 1',
'pos_config_ids': [Command.link(self.config.id)],
})
first_stage, second_stage, final_stage = prep_display.stage_ids
self.open_new_session()
order = next(iter(self._create_orders([{'pos_order_lines_ui_args': [(self.product, 1)]}]).values()))
order_line = order.lines[0]
# Simulate sending the order to preparation
self.env['pos.prep.order'].process_order(order.id)
prep_line = self.env['pos.prep.line'].search([('pos_order_line_id', '=', order_line.id)])
prep_state = self.env['pos.prep.state'].search([('prep_line_id', '=', prep_line.id)])
self.assertEqual(prep_state.stage_id, first_stage)
self.assertEqual(order_line.preparation_time, -1)
self.assertEqual(order_line.service_time, -1)
# Move order from first -> second stage
prep_state.change_state_stage(
{str(prep_state.id): second_stage.id},
prep_display.id,
)
self.assertEqual(prep_state.stage_id, second_stage)
self.assertNotEqual(order_line.preparation_time, -1)
self.assertEqual(order_line.service_time, -1)
# Move order from second -> final stage
prep_state.change_state_stage(
{str(prep_state.id): final_stage.id},
prep_display.id,
)
self.assertEqual(prep_state.stage_id, final_stage)
self.assertNotEqual(order_line.service_time, -1)
def _send_order_to_display(self, prep_display):
"""Open a session, sync one order routed to prep_display, return its pos.prep.order."""
self.open_new_session()
order = next(iter(self._create_orders([{'pos_order_lines_ui_args': [(self.product, 1)]}]).values()))
self.env['pos.prep.order'].process_order(order.id)
prep_line = self.env['pos.prep.line'].search([('pos_order_line_id', '=', order.lines[0].id)])
return prep_line.prep_order_id
def _screen_order_count(self, prep_display):
return len(prep_display.get_preparation_display_order(False)['pos.prep.order'])
def _badge_order_count(self, prep_display):
# order_count does not depend on the order records, invalidate manually
prep_display.invalidate_recordset(['order_count'])
return prep_display.order_count
def test_order_count_includes_orders_older_than_today(self):
"""An order that crossed midnight while still open must stay counted in
the kanban badge for as long as the preparation screen shows it."""
prep_display = self.env['pos.prep.display'].create({
'name': 'Kitchen Display',
'pos_config_ids': [Command.link(self.config.id)],
})
prep_order = self._send_order_to_display(prep_display)
self.assertEqual(self._screen_order_count(prep_display), 1)
self.assertEqual(self._badge_order_count(prep_display), 1)
# the session stays open past midnight
self.env.cr.execute(
"UPDATE pos_prep_order SET create_date = %s WHERE id = %s",
(fields.Datetime.now() - timedelta(days=1), prep_order.id),
)
prep_order.invalidate_recordset(['create_date'])
self.assertEqual(self._screen_order_count(prep_display), 1,
"the order is still displayed on the preparation screen")
self.assertEqual(self._badge_order_count(prep_display), 1,
"an order still shown on the screen must still be counted in the badge")
def test_order_count_cleared_by_reset(self):
"""Resetting the display clears the screen, so it must clear the badge too."""
prep_display = self.env['pos.prep.display'].create({
'name': 'Kitchen Display',
'pos_config_ids': [Command.link(self.config.id)],
})
self._send_order_to_display(prep_display)
self.assertEqual(self._screen_order_count(prep_display), 1)
self.assertEqual(self._badge_order_count(prep_display), 1)
prep_display.reset()
self.assertEqual(self._screen_order_count(prep_display), 0,
"reset removes the order from the preparation screen")
self.assertEqual(self._badge_order_count(prep_display), 0,
"reset must leave no outstanding work in the badge either")