63 lines
2.6 KiB
Python
Executable File
63 lines
2.6 KiB
Python
Executable File
# Copyright 2022 Camptocamp SA
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class StockMove(models.Model):
|
|
_inherit = "stock.move"
|
|
|
|
customer_ref_sale_line_id = fields.Many2one(
|
|
comodel_name="sale.order.line",
|
|
compute="_compute_customer_ref_sale_line_id",
|
|
string="Sale Line With Customer Ref.",
|
|
store=True,
|
|
index=True,
|
|
)
|
|
customer_ref = fields.Char(compute="_compute_customer_ref", store=True)
|
|
|
|
@api.depends("sale_line_id.customer_ref", "move_dest_ids.sale_line_id")
|
|
def _compute_customer_ref_sale_line_id(self):
|
|
for move in self:
|
|
sale_line = move._get_customer_ref_sale_line()
|
|
move.customer_ref_sale_line_id = sale_line
|
|
|
|
@api.depends("customer_ref_sale_line_id.customer_ref")
|
|
def _compute_customer_ref(self):
|
|
for move in self:
|
|
move.customer_ref = move.customer_ref_sale_line_id.customer_ref
|
|
|
|
def _get_customer_ref_sale_line(self):
|
|
"""Return the SO line with a customer ref. from the ship move."""
|
|
self.ensure_one()
|
|
if self.sale_line_id.customer_ref:
|
|
return self.sale_line_id
|
|
if not self.move_dest_ids:
|
|
return self.sale_line_id.browse()
|
|
# Search in the destination moves recursively until we find a SO line
|
|
moves_dest = self.move_dest_ids
|
|
move_seen_ids = set(moves_dest.ids)
|
|
while moves_dest:
|
|
for move_dest in moves_dest:
|
|
# As soon as the SO line has a customer reference, we break.
|
|
# That means for pick+pack moves we return the first SO line found.
|
|
if move_dest.sale_line_id.customer_ref:
|
|
return move_dest.sale_line_id
|
|
# Guard to avoid infinite loop. This should not happen.
|
|
recursion_move_ids = move_seen_ids & set(moves_dest.move_dest_ids.ids)
|
|
if recursion_move_ids:
|
|
break
|
|
moves_dest = moves_dest.move_dest_ids
|
|
move_seen_ids |= set(moves_dest.ids)
|
|
return self.sale_line_id.browse()
|
|
|
|
@api.model
|
|
def _prepare_merge_moves_distinct_fields(self):
|
|
distinct_fields = super()._prepare_merge_moves_distinct_fields()
|
|
# While ship moves can't be merged together as they are coming from
|
|
# different SO lines ('sale_line_id' is part of the merge-key in
|
|
# 'sale_stock'), we allow only the merge of chained moves like
|
|
# pick+pack based on the customer reference.
|
|
distinct_fields.append("customer_ref")
|
|
return distinct_fields
|