# Copyright 2011 Akretion, Sodexis # Copyright 2018 Akretion # Copyright 2019 Camptocamp SA # Copyright 2021 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from odoo import Command from odoo.exceptions import UserError, ValidationError from odoo.tests import Form, TransactionCase class TestSaleException(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) cls.default_pl = cls.env["product.pricelist"].create( { "name": "Public Pricelist", } ) def test_sale_order_exception(self): self.sale_exception_confirm = self.env["sale.exception.confirm"] exception = self.env.ref("sale_exception.excep_no_zip").sudo() exception.active = True partner = self.env.ref("base.res_partner_1") partner.zip = False p = self.env.ref("product.product_product_6") so1 = self.env["sale.order"].create( { "partner_id": partner.id, "partner_invoice_id": partner.id, "partner_shipping_id": partner.id, "order_line": [ Command.create( { "name": p.name, "product_id": p.id, "product_uom_qty": 2, "product_uom": p.uom_id.id, "price_unit": p.list_price, }, ) ], "pricelist_id": self.default_pl.id, } ) # confirm quotation exception = self.env.ref("sale_exception.excep_no_zip") exception.active = True so1.action_confirm() self.assertTrue(so1.state == "draft") so1.detect_exceptions() self.assertTrue(so1.exception_ids.filtered(lambda x: x == exception)) # test all draft so so2 = self.env["sale.order"].create( { "partner_id": partner.id, "partner_invoice_id": partner.id, "partner_shipping_id": partner.id, "order_line": [ Command.create( { "name": p.name, "product_id": p.id, "product_uom_qty": 3, "product_uom": p.uom_id.id, "price_unit": p.list_price, }, ) ], "pricelist_id": self.default_pl.id, } ) self.env["sale.order"].test_all_draft_orders() self.assertTrue(so2.state == "draft") # Set ignore_exception flag (Done after ignore is selected at wizard) so1.ignore_exception = True so1.action_confirm() self.assertTrue(so1.state == "sale") # Add a order line to test after SO is confirmed p = self.env.ref("product.product_product_7") # set ignore_exception = False (Done by onchange of order_line) self.assertRaises( ValidationError, so1.write, { "ignore_exception": False, "order_line": [ Command.create( { "name": p.name, "product_id": p.id, "product_uom_qty": 2, "product_uom": p.uom_id.id, "price_unit": p.list_price, }, ) ], }, ) p = self.env.ref("product.product_product_7") # Set ignore exception True (Done manually by user) so1.write( { "ignore_exception": True, "order_line": [ Command.create( { "name": p.name, "product_id": p.id, "product_uom_qty": 2, "product_uom": p.uom_id.id, "price_unit": p.list_price, }, ) ], } ) exception.active = False so1.with_context(disable_cancel_warning=True).action_cancel() so1.action_draft() self.assertTrue(not so1.ignore_exception) # Simulation the opening of the wizard sale_exception_confirm and # set ignore_exception to True so_except_confirm = self.sale_exception_confirm.with_context( active_id=so1.id, active_ids=so1.ids, active_model=so1._name ).create({"ignore": True}) so_except_confirm.action_confirm() self.assertTrue(so1.ignore_exception) self.assertEqual(so1.state, "sale") def _create_sale_order(self, partner, product): order_form = Form(self.env["sale.order"]) order_form.partner_id = partner with order_form.order_line.new() as line_form: line_form.product_id = product return order_form.save() def test_exception_partner_sale_warning(self): exception = self.env.ref("sale_exception.exception_partner_sale_warning") exception.active = True partner = self.env.ref("base.res_partner_1") sale_order = self._create_sale_order( partner=partner, product=self.env.ref("product.product_product_6") ) sale_order.action_confirm() partner.sale_warn = "warning" sale_order2 = sale_order.copy() self.env.company.sale_exception_show_popup = True result = sale_order2.action_confirm() self.assertEqual( result.get("xml_id"), "sale_exception.action_sale_exception_confirm" ) self.assertEqual(sale_order2.state, "draft") self.assertTrue(sale_order2.exception_ids.filtered(lambda x: x == exception)) def test_exception_partner_sale_warning_no_popup(self): exception = self.env.ref("sale_exception.exception_partner_sale_warning") exception.active = True partner = self.env.ref("base.res_partner_1") sale_order = self._create_sale_order( partner=partner, product=self.env.ref("product.product_product_6") ) sale_order.action_confirm() partner.sale_warn = "warning" sale_order2 = sale_order.copy() self.env.company.sale_exception_show_popup = False result = sale_order2.action_confirm() self.assertIsNone(result) self.assertEqual(sale_order2.state, "draft") self.assertTrue(sale_order2.exception_ids.filtered(lambda x: x == exception)) def test_exception_product_sale_warning(self): exception = self.env.ref("sale_exception.exception_product_sale_warning") exception.active = True product = self.env.ref("product.product_product_6") sale_order = self._create_sale_order( partner=self.env.ref("base.res_partner_1"), product=product ) sale_order.action_confirm() product.sale_line_warn = "warning" sale_order2 = sale_order.copy() sale_order2.detect_exceptions() self.assertTrue(sale_order2.exception_ids.filtered(lambda x: x == exception)) def test_exception_no_free(self): # No allow ignoring exceptions if the "is_blocking" field is checked self.sale_exception_confirm = self.env["sale.exception.confirm"] exception = self.env.ref("sale_exception.excep_no_free") exception.active = True exception.is_blocking = True partner = self.env.ref("base.res_partner_1") p = self.env.ref("product.product_product_6") sale_order = self.env["sale.order"].create( { "partner_id": partner.id, "partner_invoice_id": partner.id, "partner_shipping_id": partner.id, "order_line": [ Command.create( { "name": p.name, "product_id": p.id, "product_uom_qty": 2, "product_uom": p.uom_id.id, "price_unit": 0, }, ) ], } ) sale_order.action_confirm() so_except_confirm = self.sale_exception_confirm.with_context( **{ "active_id": sale_order.id, "active_ids": [sale_order.id], "exception_ids": [exception.id], "active_model": sale_order._name, } ).create({"ignore": True}) with self.assertRaisesRegex( UserError, "The exceptions can not be ignored, because some of them are blocking.", ): so_except_confirm.action_confirm() self.assertFalse(sale_order.ignore_exception) self.assertTrue(sale_order.state == "draft")