|
| 1 | +# Copyright 2024 Open Source Integrators |
| 2 | +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) |
| 3 | +from odoo.tests import Form |
| 4 | +from odoo.tests.common import TransactionCase |
| 5 | + |
| 6 | + |
| 7 | +class TestStockPicking(TransactionCase): |
| 8 | + def setUp(self): |
| 9 | + super().setUp() |
| 10 | + stock_location = self.env.ref("stock.stock_location_stock") |
| 11 | + customer_location = self.env.ref("stock.stock_location_customers") |
| 12 | + product = self.env.ref("product.product_product_4") |
| 13 | + picking_type = self.env.ref("stock.picking_type_out") |
| 14 | + # Create a picking in 'assigned' state with exceptions |
| 15 | + self.picking_with_exceptions = self.env["stock.picking"].create( |
| 16 | + { |
| 17 | + "name": "Test Picking With Exceptions 2", |
| 18 | + "state": "assigned", |
| 19 | + "location_id": stock_location.id, |
| 20 | + "location_dest_id": customer_location.id, |
| 21 | + "picking_type_id": picking_type.id, |
| 22 | + "move_ids": [ |
| 23 | + ( |
| 24 | + 0, |
| 25 | + 0, |
| 26 | + { |
| 27 | + "name": "Test Move With Exceptions", |
| 28 | + "product_id": product.id, |
| 29 | + "product_uom_qty": 1, |
| 30 | + "quantity": 1, |
| 31 | + "product_uom": self.env.ref("uom.product_uom_unit").id, |
| 32 | + "location_id": stock_location.id, |
| 33 | + "location_dest_id": customer_location.id, |
| 34 | + }, |
| 35 | + ) |
| 36 | + ], |
| 37 | + "ignore_exception": False, |
| 38 | + } |
| 39 | + ) |
| 40 | + |
| 41 | + self.exception = self.env["exception.rule"].create( |
| 42 | + { |
| 43 | + "name": "Demand Quantity not positive", |
| 44 | + "description": "Demand Quantity not positive", |
| 45 | + "sequence": 50, |
| 46 | + "model": "stock.move", |
| 47 | + "code": "if self.product_uom_qty == 0: failed=True", |
| 48 | + "active": True, |
| 49 | + } |
| 50 | + ) |
| 51 | + |
| 52 | + def test_detect_exceptions(self): |
| 53 | + # Test that exceptions are detected for the picking with exceptions |
| 54 | + exceptions = self.picking_with_exceptions.detect_exceptions() |
| 55 | + self.assertFalse(exceptions, "Exceptions shouldn't be detected") |
| 56 | + move = self.picking_with_exceptions.move_ids[0] |
| 57 | + move._reverse_field() |
| 58 | + move.write({"product_uom_qty": 0}) |
| 59 | + exceptions = self.picking_with_exceptions.detect_exceptions() |
| 60 | + self.assertTrue(exceptions, "Exceptions should be detected") |
| 61 | + |
| 62 | + def test_button_validate_with_exceptions(self): |
| 63 | + move = self.picking_with_exceptions.move_ids[0] |
| 64 | + move.write({"product_uom_qty": 0}) |
| 65 | + move.write({"quantity": 1}) |
| 66 | + # Result returns a dict in case it detects an exception, |
| 67 | + # otherwise it returns 'True' |
| 68 | + result = self.picking_with_exceptions.button_validate() |
| 69 | + |
| 70 | + # Verify the result of the button_validate action |
| 71 | + # If exceptions detected, the result should be different from 'True' |
| 72 | + self.assertNotEqual( |
| 73 | + result, True, f"Expected result not to be True, but got {type(result)}" |
| 74 | + ) |
| 75 | + |
| 76 | + def test_onchange_ignore_exception(self): |
| 77 | + # Change state and verify onchange behavior for picking |
| 78 | + self.picking_with_exceptions.onchange_ignore_exception() |
| 79 | + self.picking_with_exceptions._reverse_field() |
| 80 | + self.picking_with_exceptions.write( |
| 81 | + {"state": "waiting", "ignore_exception": True} |
| 82 | + ) |
| 83 | + self.assertTrue(self.picking_with_exceptions.ignore_exception) |
| 84 | + |
| 85 | + def test_confirm_picking(self): |
| 86 | + self.stock_exception = self.env["exception.rule"].create( |
| 87 | + { |
| 88 | + "name": "No Partner", |
| 89 | + "description": "No Partner", |
| 90 | + "sequence": 10, |
| 91 | + "model": "stock.picking", |
| 92 | + "exception_type": "by_py_code", |
| 93 | + "code": "if not self.partner_id: failed=True", |
| 94 | + } |
| 95 | + ) |
| 96 | + exception_action = self.picking_with_exceptions.action_confirm() |
| 97 | + self.assertEqual(exception_action.get("res_model"), "stock.exception.confirm") |
| 98 | + exception_form = Form( |
| 99 | + self.env["stock.exception.confirm"].with_context( |
| 100 | + **exception_action.get("context") |
| 101 | + ), |
| 102 | + ) |
| 103 | + stock_exception = exception_form.save() |
| 104 | + stock_exception.ignore = True |
| 105 | + self.picking_with_exceptions.test_all_draft_pickings() |
| 106 | + stock_exception.action_confirm() |
0 commit comments