143 lines
5.4 KiB
Python
Executable File
143 lines
5.4 KiB
Python
Executable File
# Copyright 2020 Akretion Renato Lima <renato.lima@akretion.com.br>
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tests.common import TransactionCase
|
|
|
|
|
|
class TestSaleMrpLink(TransactionCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.partner = cls.env.ref("base.res_partner_2")
|
|
cls.warehouse = cls.env.ref("stock.warehouse0")
|
|
route_manufacture = cls.warehouse.manufacture_pull_id.route_id.id
|
|
route_mto = cls.warehouse.mto_pull_id.route_id.id
|
|
cls.product_a = cls._create_product(
|
|
"Product A", route_ids=[(6, 0, [route_manufacture, route_mto])]
|
|
)
|
|
cls.product_b = cls._create_product(
|
|
"Product B", route_ids=[(6, 0, [route_manufacture, route_mto])]
|
|
)
|
|
cls.component_a = cls._create_product("Component A", route_ids=[])
|
|
cls.component_b = cls._create_product("Component B", route_ids=[])
|
|
|
|
@classmethod
|
|
def _create_product(cls, name, route_ids):
|
|
return cls.env["product.product"].create(
|
|
{"name": name, "type": "consu", "route_ids": route_ids}
|
|
)
|
|
|
|
def _prepare_bom_lines(self):
|
|
# Create BOMs
|
|
bom_a_v1 = self._create_bom(self.product_a.product_tmpl_id)
|
|
self._create_bom_line(bom_a_v1, self.component_a, 1)
|
|
bom_a_v2 = self._create_bom(self.product_a.product_tmpl_id)
|
|
self._create_bom_line(bom_a_v2, self.component_a, 2)
|
|
|
|
bom_b_v1 = self._create_bom(self.product_b.product_tmpl_id)
|
|
self._create_bom_line(bom_b_v1, self.component_b, 1)
|
|
bom_b_v2 = self._create_bom(self.product_b.product_tmpl_id)
|
|
self._create_bom_line(bom_b_v2, self.component_b, 2)
|
|
|
|
bom_a, bom_b = bom_a_v2, bom_b_v2
|
|
self.boms = {
|
|
self.product_a.id: bom_a,
|
|
self.product_b.id: bom_b,
|
|
}
|
|
return bom_a, bom_b
|
|
|
|
def _prepare_so(self):
|
|
bom_a_v2, bom_b_v2 = self._prepare_bom_lines()
|
|
|
|
# Create Sale Order
|
|
so = self._create_sale_order(self.partner, "SO1")
|
|
self._create_sale_order_line(so, self.product_a, 1, 10.0, bom_a_v2)
|
|
self._create_sale_order_line(so, self.product_b, 1, 10.0, bom_b_v2)
|
|
so.action_confirm()
|
|
return so, bom_a_v2, bom_b_v2
|
|
|
|
def _create_bom(self, template):
|
|
return self.env["mrp.bom"].create(
|
|
[{"product_tmpl_id": template.id, "type": "normal"}]
|
|
)
|
|
|
|
def _create_bom_line(self, bom, product, qty):
|
|
self.env["mrp.bom.line"].create(
|
|
[{"bom_id": bom.id, "product_id": product.id, "product_qty": qty}]
|
|
)
|
|
|
|
def _create_sale_order(self, partner, client_ref):
|
|
return self.env["sale.order"].create(
|
|
[{"partner_id": partner.id, "client_order_ref": client_ref}]
|
|
)
|
|
|
|
def _create_sale_order_line(self, sale_order, product, qty, price, bom):
|
|
self.env["sale.order.line"].create(
|
|
[
|
|
{
|
|
"order_id": sale_order.id,
|
|
"product_id": product.id,
|
|
"price_unit": price,
|
|
"product_uom_qty": qty,
|
|
"bom_id": bom.id,
|
|
}
|
|
]
|
|
)
|
|
|
|
def test_define_bom_in_sale_line(self):
|
|
"""Check manufactured order is created with BOM defined in Sale."""
|
|
previous_mos = self.env["mrp.production"].search([])
|
|
_so, _bom_a, _bom_b = self._prepare_so()
|
|
|
|
# Check manufacture order
|
|
mos = self.env["mrp.production"].search([]) - previous_mos
|
|
for mo in mos:
|
|
self.assertEqual(mo.bom_id, self.boms.get(mo.product_id.id))
|
|
|
|
def test_pick_a_pack_confirm(self):
|
|
so, bom_a, bom_b = self._prepare_so()
|
|
picking, boms = so.picking_ids[0], (bom_a, bom_b)
|
|
|
|
for i, line in enumerate(picking.move_ids):
|
|
values = line._prepare_procurement_values()
|
|
self.assertEqual(values["bom_id"], boms[i])
|
|
|
|
def test_mismatch_product_variant_ids(self):
|
|
so, bom_a, bom_b = self._prepare_so()
|
|
line_a = so.order_line[0]
|
|
self.assertEqual(line_a.bom_id, bom_a)
|
|
with self.assertRaises(ValidationError):
|
|
line_a.write({"bom_id": bom_b})
|
|
|
|
def test_accept_bom_with_no_variant(self):
|
|
# make variants for template of product A
|
|
product_tmpl_a = self.product_a.product_tmpl_id
|
|
prod_att_color = self.env["product.attribute"].create({"name": "Color"})
|
|
product_attr_val_red, product_attr_val_green = self.env[
|
|
"product.attribute.value"
|
|
].create(
|
|
[
|
|
{"name": "red", "attribute_id": prod_att_color.id, "sequence": 1},
|
|
{"name": "blue", "attribute_id": prod_att_color.id, "sequence": 2},
|
|
]
|
|
)
|
|
product_tmpl_a.attribute_line_ids = [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"attribute_id": prod_att_color.id,
|
|
"value_ids": [
|
|
(6, 0, [product_attr_val_red.id, product_attr_val_green.id])
|
|
],
|
|
},
|
|
)
|
|
]
|
|
product_a = product_tmpl_a.product_variant_ids[0]
|
|
bom_no_variant = self._create_bom(product_tmpl_a)
|
|
so = self._create_sale_order(self.partner, "SO2")
|
|
self._create_sale_order_line(so, product_a, 2, 25, bom_no_variant)
|
|
line_a = so.order_line[0]
|
|
line_a.bom_id = bom_no_variant
|