mirror of
https://github.com/bringout/oca-purchase.git
synced 2026-04-20 07:42:02 +02:00
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
163 lines
6.4 KiB
Python
163 lines
6.4 KiB
Python
# Copyright 2017 Akretion (http://www.akretion.com)
|
|
# Copyright 2020 Camptocamp SA
|
|
# Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com>
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
|
from datetime import datetime
|
|
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
|
|
|
|
|
class TestPurchaseException(TransactionCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
# Useful models
|
|
cls.PurchaseOrder = cls.env["purchase.order"]
|
|
cls.PurchaseOrderLine = cls.env["purchase.order.line"]
|
|
cls.partner_id = cls.env.ref("base.res_partner_1")
|
|
cls.product_id_1 = cls.env.ref("product.product_product_6")
|
|
cls.product_id_2 = cls.env.ref("product.product_product_7")
|
|
cls.product_id_3 = cls.env.ref("product.product_product_7")
|
|
cls.date_planned = datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
cls.purchase_exception_confirm = cls.env["purchase.exception.confirm"]
|
|
cls.exception_noemail = cls.env.ref("purchase_exception.po_excep_no_email")
|
|
cls.exception_qtycheck = cls.env.ref("purchase_exception.pol_excep_qty_check")
|
|
cls.po_vals = {
|
|
"partner_id": cls.partner_id.id,
|
|
"order_line": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"name": cls.product_id_1.name,
|
|
"product_id": cls.product_id_1.id,
|
|
"product_qty": 5.0,
|
|
"product_uom": cls.product_id_1.uom_po_id.id,
|
|
"price_unit": 500.0,
|
|
"date_planned": cls.date_planned,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"name": cls.product_id_2.name,
|
|
"product_id": cls.product_id_2.id,
|
|
"product_qty": 5.0,
|
|
"product_uom": cls.product_id_2.uom_po_id.id,
|
|
"price_unit": 250.0,
|
|
"date_planned": cls.date_planned,
|
|
},
|
|
),
|
|
],
|
|
}
|
|
cls.po_vals2 = {
|
|
"partner_id": cls.partner_id.id,
|
|
"order_line": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"name": cls.product_id_3.name,
|
|
"product_id": cls.product_id_3.id,
|
|
"product_qty": -1.0,
|
|
"product_uom": cls.product_id_3.uom_po_id.id,
|
|
"price_unit": 20.0,
|
|
"date_planned": cls.date_planned,
|
|
},
|
|
),
|
|
],
|
|
}
|
|
|
|
def test_purchase_order_exception(self):
|
|
self.exception_noemail.active = True
|
|
self.exception_qtycheck.active = True
|
|
self.partner_id.email = False
|
|
self.po = self.PurchaseOrder.create(self.po_vals.copy())
|
|
|
|
# confirm quotation
|
|
self.po.button_confirm()
|
|
self.assertEqual(self.po.state, "draft")
|
|
# test all draft po
|
|
self.po2 = self.PurchaseOrder.create(self.po_vals.copy())
|
|
|
|
self.PurchaseOrder.test_all_draft_orders()
|
|
self.assertEqual(self.po2.state, "draft")
|
|
# Set ignore_exception flag (Done after ignore is selected at wizard)
|
|
self.po.ignore_exception = True
|
|
self.po.button_confirm()
|
|
self.assertEqual(self.po.state, "purchase")
|
|
|
|
# Add a order line to test after PO is confirmed
|
|
field_onchange = self.PurchaseOrder._onchange_spec()
|
|
self.assertEqual(field_onchange.get("order_line"), "1")
|
|
self.po3New = self.PurchaseOrder.new(self.po_vals.copy())
|
|
self.po3New.ignore_exception = True
|
|
self.po3New.state = "purchase"
|
|
self.po.write(
|
|
{
|
|
"order_line": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"name": self.product_id_3.name,
|
|
"product_id": self.product_id_3.id,
|
|
"product_qty": 2,
|
|
"product_uom": self.product_id_3.uom_id.id,
|
|
"price_unit": 30,
|
|
"date_planned": self.date_planned,
|
|
},
|
|
)
|
|
]
|
|
}
|
|
)
|
|
|
|
# Set ignore exception True (Done manually by user)
|
|
self.po.ignore_exception = True
|
|
self.po.button_cancel()
|
|
self.po.button_draft()
|
|
self.assertEqual(self.po.state, "draft")
|
|
self.assertTrue(not self.po.ignore_exception)
|
|
self.po.button_confirm()
|
|
self.assertTrue(self.po.state, "to approve")
|
|
|
|
# Simulation the opening of the wizard purchase_exception_confirm and
|
|
# set ignore_exception to True
|
|
po_except_confirm = self.purchase_exception_confirm.with_context(
|
|
active_id=self.po.id,
|
|
active_ids=[self.po.id],
|
|
active_model=self.po._name,
|
|
).create({"ignore": True})
|
|
po_except_confirm.action_confirm()
|
|
|
|
def test_exception_qtycheck(self):
|
|
# No allow ignoring exceptions if the "is_blocking" field is checked
|
|
self.exception_qtycheck.active = True
|
|
self.exception_qtycheck.is_blocking = True
|
|
self.po = self.PurchaseOrder.create(self.po_vals2.copy())
|
|
po_except_confirm = self.purchase_exception_confirm.with_context(
|
|
**{
|
|
"active_id": self.po.id,
|
|
"active_ids": [self.po.id],
|
|
"active_model": self.po._name,
|
|
}
|
|
).create({"ignore": True})
|
|
po_except_confirm.exception_ids = self.exception_qtycheck
|
|
po_except_confirm.action_confirm()
|
|
|
|
def test_exception_no_validation_for_unlock(self):
|
|
self.partner_id.email = False
|
|
po = self.PurchaseOrder.create(self.po_vals.copy())
|
|
po.button_confirm()
|
|
self.assertEqual(po.state, "purchase")
|
|
po.button_done()
|
|
self.assertEqual(po.state, "done")
|
|
exception = self.env.ref("purchase_exception.po_excep_no_email")
|
|
exception.active = True
|
|
with self.assertRaises(ValidationError):
|
|
po.write({"state": "purchase"})
|
|
po.button_unlock()
|
|
self.assertEqual(po.state, "purchase")
|