diff --git a/purchase_sale_inter_company/models/res_company.py b/purchase_sale_inter_company/models/res_company.py
index cab6b7e9f49..26e5d2da575 100644
--- a/purchase_sale_inter_company/models/res_company.py
+++ b/purchase_sale_inter_company/models/res_company.py
@@ -47,6 +47,13 @@ class ResCompany(models.Model):
default="raise",
help="Pick action to perform on sync picking failure",
)
+ sync_picking_state = fields.Boolean(
+ string="Sync the receipt state with the delivery state",
+ default=lambda p: p.sync_picking,
+ help="State of receipt picking syncs with state of the delivery "
+ "from the source company. Note this disallows user to manually "
+ "correct or change a picking that did not sync properly.",
+ )
block_po_manual_picking_validation = fields.Boolean(
string="Block manual validation of picking in the destination company",
)
diff --git a/purchase_sale_inter_company/models/res_config.py b/purchase_sale_inter_company/models/res_config.py
index 3116b653a12..cb717b11c89 100644
--- a/purchase_sale_inter_company/models/res_config.py
+++ b/purchase_sale_inter_company/models/res_config.py
@@ -49,6 +49,9 @@ class InterCompanyRulesConfig(models.TransientModel):
)
sync_picking_failure_action = fields.Selection(
related="company_id.sync_picking_failure_action",
+ )
+ sync_picking_state = fields.Boolean(
+ related="company_id.sync_picking_state",
readonly=False,
)
block_po_manual_picking_validation = fields.Boolean(
diff --git a/purchase_sale_inter_company/models/stock_picking.py b/purchase_sale_inter_company/models/stock_picking.py
index 1df7f835fb9..409bd4f6f0c 100644
--- a/purchase_sale_inter_company/models/stock_picking.py
+++ b/purchase_sale_inter_company/models/stock_picking.py
@@ -21,7 +21,8 @@ def _compute_state(self):
res = super()._compute_state()
for picking in self:
if (
- picking.intercompany_picking_id
+ picking.company_id.sync_picking_state
+ and picking.intercompany_picking_id
and picking.picking_type_code == "incoming"
and picking.state not in ["done", "cancel"]
):
diff --git a/purchase_sale_inter_company/tests/test_inter_company_purchase_sale.py b/purchase_sale_inter_company/tests/test_inter_company_purchase_sale.py
index cd183b3a956..55017d9e83b 100644
--- a/purchase_sale_inter_company/tests/test_inter_company_purchase_sale.py
+++ b/purchase_sale_inter_company/tests/test_inter_company_purchase_sale.py
@@ -326,6 +326,8 @@ def test_confirm_several_picking(self):
def test_sync_picking(self):
self.company_a.sync_picking = True
self.company_b.sync_picking = True
+ self.company_a.sync_picking_state = True
+ self.company_b.sync_picking_state = True
purchase = self._create_purchase_order(
self.partner_company_b, self.consumable_product
@@ -354,14 +356,16 @@ def test_sync_picking(self):
so_picking_id.move_lines.product_qty,
)
- so_picking_id.state = "done"
+ # Validate sale order, create backorder
wizard_data = so_picking_id.with_user(self.user_company_b).button_validate()
wizard = (
self.env["stock.backorder.confirmation"]
.with_context(**wizard_data.get("context"))
.create({})
)
- wizard.process()
+ wizard.with_user(self.user_company_b).process()
+ self.assertEqual(so_picking_id.state, "done")
+ self.assertNotEqual((sale.picking_ids - so_picking_id).state, "done")
# Quantities should have been synced
self.assertNotEqual(po_picking_id, so_picking_id)
@@ -376,10 +380,15 @@ def test_sync_picking(self):
# A backorder should have been made for both
self.assertTrue(len(sale.picking_ids) > 1)
self.assertEqual(len(purchase.picking_ids), len(sale.picking_ids))
+ # The original orders should now be done.
+ self.assertEqual(so_picking_id.state, "done")
+ self.assertEqual(po_picking_id.state, "done")
def test_sync_picking_no_backorder(self):
self.company_a.sync_picking = True
self.company_b.sync_picking = True
+ self.company_a.sync_picking_state = True
+ self.company_b.sync_picking_state = True
purchase = self._create_purchase_order(
self.partner_company_b, self.consumable_product
@@ -453,9 +462,12 @@ def test_sync_picking_lot(self):
)
self.company_a.sync_picking = True
self.company_b.sync_picking = True
+ self.company_a.sync_picking_state = True
+ self.company_b.sync_picking_state = True
purchase = self._create_purchase_order(
- self.partner_company_b, self.stockable_product_serial
+ self.partner_company_b,
+ self.stockable_product_serial + self.consumable_product,
)
sale = self._approve_po(purchase)
@@ -463,14 +475,15 @@ def test_sync_picking_lot(self):
po_picking_id = purchase.picking_ids
so_picking_id = sale.picking_ids
- so_move = so_picking_id.move_lines
- so_move.move_line_ids = [
+ so_moves = so_picking_id.move_lines
+ so_moves[1].quantity_done = 2
+ so_moves[0].move_line_ids = [
(
0,
0,
{
- "location_id": so_move.location_id.id,
- "location_dest_id": so_move.location_dest_id.id,
+ "location_id": so_moves[0].location_id.id,
+ "location_dest_id": so_moves[0].location_dest_id.id,
"product_id": self.stockable_product_serial.id,
"product_uom_id": self.stockable_product_serial.uom_id.id,
"qty_done": 1,
@@ -482,21 +495,8 @@ def test_sync_picking_lot(self):
0,
0,
{
- "location_id": so_move.location_id.id,
- "location_dest_id": so_move.location_dest_id.id,
- "product_id": self.stockable_product_serial.id,
- "product_uom_id": self.stockable_product_serial.uom_id.id,
- "qty_done": 1,
- "lot_id": self.serial_2.id,
- "picking_id": so_picking_id.id,
- },
- ),
- (
- 0,
- 0,
- {
- "location_id": so_move.location_id.id,
- "location_dest_id": so_move.location_dest_id.id,
+ "location_id": so_moves[0].location_id.id,
+ "location_dest_id": so_moves[0].location_dest_id.id,
"product_id": self.stockable_product_serial.id,
"product_uom_id": self.stockable_product_serial.uom_id.id,
"qty_done": 1,
@@ -505,9 +505,17 @@ def test_sync_picking_lot(self):
},
),
]
- so_picking_id.button_validate()
+ wizard_data = so_picking_id.with_user(self.user_company_b).button_validate()
+ wizard = (
+ self.env["stock.backorder.confirmation"]
+ .with_context(**wizard_data.get("context"))
+ .create({})
+ )
+ wizard.with_user(self.user_company_b).process()
+ self.assertEqual(so_picking_id.state, "done")
+ self.assertNotEqual((sale.picking_ids - so_picking_id).state, "done")
- so_lots = so_move.mapped("move_line_ids.lot_id")
+ so_lots = so_moves.mapped("move_line_ids.lot_id")
po_lots = po_picking_id.mapped("move_lines.move_line_ids.lot_id")
self.assertEqual(
len(so_lots),
@@ -518,8 +526,8 @@ def test_sync_picking_lot(self):
so_lots, po_lots, msg="The lots of the moves should be different objects"
)
self.assertEqual(
- so_lots.mapped("name"),
- po_lots.mapped("name"),
+ so_lots.sudo().mapped("name"),
+ po_lots.sudo().mapped("name"),
msg="The lots should have the same name in both moves",
)
self.assertIn(
@@ -527,6 +535,12 @@ def test_sync_picking_lot(self):
po_lots,
msg="Serial 333 already existed, a new one shouldn't have been created",
)
+ # A backorder should have been made for both
+ self.assertTrue(len(sale.picking_ids) > 1)
+ self.assertEqual(len(purchase.picking_ids), len(sale.picking_ids))
+ # The original orders should now be done.
+ self.assertEqual(so_picking_id.state, "done")
+ self.assertEqual(po_picking_id.state, "done")
def test_sync_picking_same_product_multiple_lines(self):
"""
@@ -659,6 +673,10 @@ def test_update_open_sale_order(self):
"3.0 Units of Consumable Product 2.+instead of 8.0 Units", re.DOTALL
),
)
+ print(so_picking_id.state)
+ po_picking_id = purchase.picking_ids
+ print(po_picking_id.state)
+ # Upon confirm, I expect here an issue
def test_block_manual_validation(self):
"""
@@ -667,6 +685,8 @@ def test_block_manual_validation(self):
"""
self.company_a.sync_picking = True
self.company_b.sync_picking = True
+ self.company_a.sync_picking_state = True
+ self.company_b.sync_picking_state = True
self.company_a.block_po_manual_picking_validation = True
self.company_b.block_po_manual_picking_validation = True
purchase = self._create_purchase_order(
diff --git a/purchase_sale_inter_company/views/res_config_view.xml b/purchase_sale_inter_company/views/res_config_view.xml
index 46f1f59ef0f..e8601893730 100644
--- a/purchase_sale_inter_company/views/res_config_view.xml
+++ b/purchase_sale_inter_company/views/res_config_view.xml
@@ -62,6 +62,12 @@
attrs="{'invisible': [('sync_picking_failure_action', '!=', 'notify')], 'required': [('sync_picking_failure_action', '=', 'notify')]}"
class="oe_inline"
/>
+
+