Odoo18-Base/addons/point_of_sale/tests/test_pos_capture.py
2025-03-10 10:52:11 +07:00

172 lines
7.7 KiB
Python

import contextlib
import logging
from unittest.mock import patch
import odoo
from odoo.addons.point_of_sale.models.pos_order import PosOrder
from odoo.addons.point_of_sale.models.pos_session import PosSession
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
class IntendedException(Exception):
pass
def mocked_process_order(*args):
# We just want the order process to crash (to see if it is captured)
raise IntendedException()
def mocked_handle_order_process_fail(self, order: dict, exception: Exception, draft: bool):
# We DO NOT want to create a new env in the test as the current pos_session does not exist (as it was not committed)
self._process_order_process_fail(order, exception)
@odoo.tests.tagged('post_install', '-at_install')
class TestPosCapture(TestPoSCommon):
"""
Test the capture system of failed to process orders
"""
def setUp(self):
super().setUp()
self.config = self.basic_config
self.product1 = self.create_product('Product 1', self.categ_basic, 10, 5)
def assert_activity_and_attachment(self, pos_session, number):
pos_attachments_domain = [
['res_model', '=', pos_session._name],
['res_id', '=', pos_session.id]
]
self.assertEqual(len(pos_session.activity_ids), number)
self.assertEqual(len(self.env['ir.attachment'].search(pos_attachments_domain)), number)
def test_capture_one_order(self):
# open a session
session = self.open_new_session()
orders = [self.create_ui_order_data([(self.product1, 1)])]
self.assert_activity_and_attachment(session, 0)
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR) as logger_error_output:
try:
self.env['pos.order'].create_from_ui(orders)
except IntendedException:
self.assertIn("An error occurred when processing the PoS order", logger_error_output.output[0])
self.assert_activity_and_attachment(session, 1)
self.assertEqual(session.activity_ids[0].user_id.id, self.env.user.id)
def test_capture_two_orders(self):
"""Two order even with same content should have distinct captured file"""
# open a session
session = self.open_new_session()
order1 = [self.create_ui_order_data([(self.product1, 1)], uid='12345-678-1996')]
order2 = [self.create_ui_order_data([(self.product1, 1)], uid='12345-678-1999')] # Different order with same content but different uuid
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR):
try:
self.env['pos.order'].create_from_ui(order1)
except IntendedException:
self.assert_activity_and_attachment(session, 1)
try:
self.env['pos.order'].create_from_ui(order2)
except IntendedException:
self.assert_activity_and_attachment(session, 2)
def test_capture_one_order_twice(self):
"""Should have only one attachment as we sync the same order twice"""
# open a session
session = self.open_new_session()
orders = [self.create_ui_order_data([(self.product1, 1)])]
self.assert_activity_and_attachment(session, 0)
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR):
for _ in range(2):
try:
self.env['pos.order'].create_from_ui(orders)
except IntendedException:
self.assert_activity_and_attachment(session, 1)
def test_capture_order_same_uuid(self):
"""Should have 2 attachments as the content is different"""
# open a session
session = self.open_new_session()
order1 = [self.create_ui_order_data([(self.product1, 1)], uid='12345-678-1996')]
order2 = [self.create_ui_order_data([(self.product1, 2)], uid='12345-678-1996')]
self.assert_activity_and_attachment(session, 0)
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR):
try:
self.env['pos.order'].create_from_ui(order1)
except IntendedException:
self.assert_activity_and_attachment(session, 1)
try:
self.env['pos.order'].create_from_ui(order2)
except IntendedException:
self.assert_activity_and_attachment(session, 2)
def test_capture_one_order_and_removed(self):
"""Check if the attachment and activity is automatically remove after the order sync"""
# open a session
session = self.open_new_session()
orders = [self.create_ui_order_data([(self.product1, 1)])]
self.assert_activity_and_attachment(session, 0)
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR),\
contextlib.suppress(IntendedException):
self.env['pos.order'].create_from_ui(orders)
self.assert_activity_and_attachment(session, 1)
# Resync the order, this time it should go through!
self.env['pos.order'].create_from_ui(orders)
# Should automatically remove the attachment for this order after sync
self.assert_activity_and_attachment(session, 0)
def test_capture_two_orders_and_removed(self):
"""Check if the attachment and activity is automatically remove after the order sync (with 2 orders)"""
# open a session
session = self.open_new_session()
order1 = [self.create_ui_order_data([(self.product1, 1)], uid='12345-678-1996')]
order2 = [self.create_ui_order_data([(self.product1, 1)], uid='12345-678-1999')] # Different order with same content but different uuid
with patch.object(PosOrder, '_process_order', mocked_process_order),\
patch.object(PosSession, '_handle_order_process_fail', mocked_handle_order_process_fail),\
self.assertLogs('odoo.addons.point_of_sale.models.pos_order', level=logging.ERROR):
try:
self.env['pos.order'].create_from_ui(order1)
except IntendedException:
self.assert_activity_and_attachment(session, 1)
try:
self.env['pos.order'].create_from_ui(order2)
except IntendedException:
self.assert_activity_and_attachment(session, 2)
self.assert_activity_and_attachment(session, 2)
# Resync the order, this time it should go through!
self.env['pos.order'].create_from_ui(order2)
# Should automatically remove the attachment for this order after sync
self.assert_activity_and_attachment(session, 1)
self.env['pos.order'].create_from_ui(order1)
# Should automatically remove the attachment for this order after sync
self.assert_activity_and_attachment(session, 0)