diff --git a/purchase_sale_inter_company/models/res_company.py b/purchase_sale_inter_company/models/res_company.py
index cab6b7e9f49..93cb474e9f5 100644
--- a/purchase_sale_inter_company/models/res_company.py
+++ b/purchase_sale_inter_company/models/res_company.py
@@ -51,3 +51,8 @@ class ResCompany(models.Model):
string="Block manual validation of picking in the destination company",
)
notify_user_id = fields.Many2one("res.users", "User to Notify")
+ notification_side = fields.Selection(
+ [("so", "Sale Order Source Company"), ("po", "Purchase Destination Company")],
+ default="so",
+ help="Select which Company side to notify",
+ )
diff --git a/purchase_sale_inter_company/models/res_config.py b/purchase_sale_inter_company/models/res_config.py
index 3116b653a12..538b8b5316e 100644
--- a/purchase_sale_inter_company/models/res_config.py
+++ b/purchase_sale_inter_company/models/res_config.py
@@ -61,3 +61,6 @@ class InterCompanyRulesConfig(models.TransientModel):
help="User to notify incase of sync picking failure.",
readonly=False,
)
+ notification_side = fields.Selection(
+ related="company_id.notification_side", string="Notify", readonly=False
+ )
diff --git a/purchase_sale_inter_company/models/stock_picking.py b/purchase_sale_inter_company/models/stock_picking.py
index 1df7f835fb9..6e803330a3b 100644
--- a/purchase_sale_inter_company/models/stock_picking.py
+++ b/purchase_sale_inter_company/models/stock_picking.py
@@ -58,21 +58,14 @@ def _action_done_intercompany_actions(self, purchase):
).mapped("move_line_ids")
)
if len(move_lines) != len(po_move_lines):
- note = _(
- "Mismatch between move lines with the "
- "corresponding PO %s for assigning "
- "quantities and lots from %s for product %s"
- ) % (purchase.name, pick.name, move.product_id.name)
- self.activity_schedule(
- "mail.mail_activity_data_warning",
- fields.Date.today(),
- note=note,
- # Try to notify someone relevant
- user_id=(
- pick.sale_id.user_id.id
- or pick.sale_id.team_id.user_id.id
- or SUPERUSER_ID,
- ),
+ self._notify_picking_problem(
+ purchase,
+ additional_note=_(
+ "Mismatch between move lines with the "
+ "corresponding PO %s for assigning "
+ "quantities and lots from %s for product %s"
+ )
+ % (purchase.name, pick.name, move.product_id.name),
)
# check and assign lots here
for ml, po_ml in zip(move_lines, po_move_lines):
@@ -97,31 +90,38 @@ def _action_done_intercompany_actions(self, purchase):
dest_lot_id = lot_id.copy({"company_id": po_ml.company_id.id})
po_ml.lot_id = dest_lot_id
- except Exception:
+ except Exception as e:
if self.env.company_id.sync_picking_failure_action == "raise":
raise
else:
- self._notify_picking_problem(purchase)
+ self._notify_picking_problem(purchase, additional_note=str(e))
- def _notify_picking_problem(self, purchase):
+ def _notify_picking_problem(self, purchase, additional_note=False):
self.ensure_one()
note = _(
"Failure to confirm picking for PO %s. "
"Original picking %s still confirmed, please check "
"the other side manually."
) % (purchase.name, self.name)
- self.activity_schedule(
+ if additional_note:
+ note += _(" Additional info: ") + additional_note
+ user_id = self.sudo()._get_user_to_notify(purchase)
+ self.sudo().activity_schedule(
"mail.mail_activity_data_warning",
fields.Date.today(),
note=note,
- # Try to notify someone relevant
- user_id=(
+ user_id=user_id or SUPERUSER_ID,
+ )
+
+ def _get_user_to_notify(self, purchase):
+ """Notify user based on res.config.settings"""
+ if purchase.company_id.notification_side == "so":
+ return (
self.company_id.notify_user_id.id
or self.sale_id.user_id.id
or self.sale_id.team_id.user_id.id
- or SUPERUSER_ID,
- ),
- )
+ )
+ return purchase.company_id.notify_user_id.id or purchase.user_id.id
def button_validate(self):
res = super().button_validate()
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..a098538731d 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
@@ -723,6 +723,43 @@ def test_notify_picking_problem(self):
warning_activity.user_id, so_picking_id.company_id.notify_user_id
)
+ def test_notify_picking_problem_dest_company(self):
+ self.company_a.sync_picking = True
+ self.company_b.sync_picking = True
+ self.company_a.sync_picking_failure_action = "notify"
+ self.company_b.sync_picking_failure_action = "notify"
+ self.company_a.notification_side = "po"
+ self.company_b.notification_side = "po"
+ purchase = self._create_purchase_order(
+ self.partner_company_b, self.consumable_product
+ )
+ purchase_2 = self._create_purchase_order(
+ self.partner_company_b, self.consumable_product
+ )
+ purchase.order_line += purchase.order_line.copy({"product_qty": 2})
+ sale = self._approve_po(purchase)
+ sale.action_confirm()
+
+ # validate the SO picking
+ so_picking_id = sale.picking_ids
+ # Set as purchase_2 user user_company_a
+ purchase_2.user_id = self.user_company_a
+ # Link to a new purchase order so it can trigger
+ # `PO does not exist or has no receipts` in _sync_receipt_with_delivery
+ sale.auto_purchase_order_id = purchase_2
+
+ # Set quantities done on the picking and validate
+ for move in so_picking_id.move_lines:
+ move.quantity_done = move.product_uom_qty
+ so_picking_id.button_validate()
+
+ activity_warning = self.env.ref("mail.mail_activity_data_warning")
+ warning_activity = so_picking_id.activity_ids.filtered(
+ lambda a: a.activity_type_id == activity_warning
+ )
+ # Test the user assigned to the activity
+ self.assertEqual(warning_activity.user_id, self.user_company_a)
+
def test_raise_picking_problem(self):
self.company_a.sync_picking = True
self.company_b.sync_picking = True
diff --git a/purchase_sale_inter_company/views/res_config_view.xml b/purchase_sale_inter_company/views/res_config_view.xml
index 46f1f59ef0f..74c8d6558c0 100644
--- a/purchase_sale_inter_company/views/res_config_view.xml
+++ b/purchase_sale_inter_company/views/res_config_view.xml
@@ -52,6 +52,18 @@
for="sync_picking_failure_action"
/>
+
+
+