[fix] rma: improve logic to count in and out pickings

In the scenario where we use a 2 or 3 step receipts or pickings
we want to make sure that we correctly count and classify the pickings.
This commit is contained in:
Jordi Ballester
2022-02-03 16:04:59 +01:00
parent acffe8c5e2
commit f4b8a5060c
3 changed files with 82 additions and 93 deletions

View File

@@ -20,33 +20,17 @@ class RmaOrder(models.Model):
def _compute_in_shipment_count(self): def _compute_in_shipment_count(self):
for rec in self: for rec in self:
picking_ids = [] pickings = self.env["stock.picking"]
if not rec.rma_line_ids:
rec.in_shipment_count = 0
continue
for line in rec.rma_line_ids: for line in rec.rma_line_ids:
for move in line.move_ids: pickings |= line._get_in_pickings()
if move.location_dest_id.usage == "internal": rec.in_shipment_count = len(pickings)
picking_ids.append(move.picking_id.id)
else:
if line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
rec.in_shipment_count = len(shipments)
def _compute_out_shipment_count(self): def _compute_out_shipment_count(self):
picking_ids = []
for rec in self: for rec in self:
if not rec.rma_line_ids: pickings = self.env["stock.picking"]
rec.out_shipment_count = 0
continue
for line in rec.rma_line_ids: for line in rec.rma_line_ids:
for move in line.move_ids: pickings |= line._get_out_pickings()
if move.location_dest_id.usage in ("supplier", "customer"): rec.in_shipment_count = len(pickings)
if not line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
rec.out_shipment_count = len(shipments)
def _compute_supplier_line_count(self): def _compute_supplier_line_count(self):
self.supplier_line_count = len( self.supplier_line_count = len(
@@ -183,47 +167,31 @@ class RmaOrder(models.Model):
vals["name"] = self.env["ir.sequence"].next_by_code("rma.order.customer") vals["name"] = self.env["ir.sequence"].next_by_code("rma.order.customer")
return super(RmaOrder, self).create(vals) return super(RmaOrder, self).create(vals)
def action_view_in_shipments(self): def _view_shipments(self, result, shipments):
action = self.env.ref("stock.action_picking_tree_all")
result = action.read()[0]
picking_ids = []
for line in self.rma_line_ids:
for move in line.move_ids:
if move.location_dest_id.usage == "internal":
picking_ids.append(move.picking_id.id)
else:
if line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
if picking_ids:
shipments = list(set(picking_ids))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) > 1: if len(shipments) > 1:
result["domain"] = [("id", "in", shipments)] result["domain"] = [("id", "in", shipments.ids)]
else: elif len(shipments) == 1:
res = self.env.ref("stock.view_picking_form", False) res = self.env.ref("stock.view_picking_form", False)
result["views"] = [(res and res.id or False, "form")] result["views"] = [(res and res.id or False, "form")]
result["res_id"] = shipments[0] result["res_id"] = shipments.ids[0]
return result return result
def action_view_in_shipments(self):
action = self.env.ref("stock.action_picking_tree_all")
result = action.sudo().read()[0]
shipments = self.env["stock.picking"]
for line in self.rma_line_ids:
shipments |= line._get_in_pickings()
return self._view_shipments(result, shipments)
def action_view_out_shipments(self): def action_view_out_shipments(self):
action = self.env.ref("stock.action_picking_tree_all") action = self.env.ref("stock.action_picking_tree_all")
result = action.read()[0] result = action.sudo().read()[0]
picking_ids = [] shipments = self.env["stock.picking"]
for line in self.rma_line_ids: for line in self.rma_line_ids:
for move in line.move_ids: shipments |= line._get_out_pickings()
if move.location_dest_id.usage in ("supplier", "customer"): return self._view_shipments(result, shipments)
if not line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
if picking_ids:
shipments = list(set(picking_ids))
# choose the view_mode accordingly
if len(shipments) != 1:
result["domain"] = [("id", "in", shipments)]
else:
res = self.env.ref("stock.view_picking_form", False)
result["views"] = [(res and res.id or False, "form")]
result["res_id"] = shipments[0]
return result
def _get_valid_lines(self): def _get_valid_lines(self):
""":return: A recordset of rma lines. """:return: A recordset of rma lines.

View File

@@ -42,27 +42,43 @@ class RmaOrderLine(models.Model):
self.partner_id.address_get(["delivery"])["delivery"] self.partner_id.address_get(["delivery"])["delivery"]
) )
@api.model
def _get_in_pickings(self):
# We consider an in move one where the first origin is outside
# of the company and the final destination is outside. In case
# of 2 or 3 step pickings, we should categorize as in shipments
# even when they are technically internal transfers.
pickings = self.env["stock.picking"]
for move in self.move_ids:
first_usage = move._get_first_usage()
last_usage = move._get_last_usage()
if last_usage == "internal" and first_usage != "internal":
pickings |= move.picking_id
elif last_usage == "supplier" and first_usage == "customer":
pickings |= move.picking_id
return pickings
@api.model
def _get_out_pickings(self):
pickings = self.env["stock.picking"]
for move in self.move_ids:
first_usage = move._get_first_usage()
last_usage = move._get_last_usage()
if first_usage == "internal" and last_usage != "internal":
pickings |= move.picking_id
elif last_usage == "customer" and first_usage == "supplier":
pickings |= move.picking_id
return pickings
def _compute_in_shipment_count(self): def _compute_in_shipment_count(self):
for line in self: for line in self:
picking_ids = [] pickings = line._get_in_pickings()
for move in line.move_ids: line.in_shipment_count = len(pickings)
if move.location_dest_id.usage == "internal":
picking_ids.append(move.picking_id.id)
else:
if line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
line.in_shipment_count = len(shipments)
def _compute_out_shipment_count(self): def _compute_out_shipment_count(self):
picking_ids = []
for line in self: for line in self:
for move in line.move_ids: pickings = line._get_out_pickings()
if move.location_dest_id.usage in ("supplier", "customer"): line.out_shipment_count = len(pickings)
if not line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
line.out_shipment_count = len(shipments)
def _get_rma_move_qty(self, states, direction="in"): def _get_rma_move_qty(self, states, direction="in"):
for rec in self: for rec in self:
@@ -662,43 +678,32 @@ class RmaOrderLine(models.Model):
def action_view_in_shipments(self): def action_view_in_shipments(self):
action = self.env.ref("stock.action_picking_tree_all") action = self.env.ref("stock.action_picking_tree_all")
result = action.read()[0] result = action.sudo().read()[0]
picking_ids = [] shipments = self.env["stock.picking"]
for line in self: for line in self:
for move in line.move_ids: shipments |= line._get_in_pickings()
if move.location_dest_id.usage == "internal":
picking_ids.append(move.picking_id.id)
else:
if line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if len(shipments) != 1:
result["domain"] = "[('id', 'in', " + str(shipments) + ")]" result["domain"] = "[('id', 'in', " + str(shipments.ids) + ")]"
elif len(shipments) == 1: elif len(shipments) == 1:
res = self.env.ref("stock.view_picking_form", False) res = self.env.ref("stock.view_picking_form", False)
result["views"] = [(res and res.id or False, "form")] result["views"] = [(res and res.id or False, "form")]
result["res_id"] = shipments[0] result["res_id"] = shipments.ids[0]
return result return result
def action_view_out_shipments(self): def action_view_out_shipments(self):
action = self.env.ref("stock.action_picking_tree_all") action = self.env.ref("stock.action_picking_tree_all")
result = action.read()[0] result = action.sudo().read()[0]
picking_ids = [] shipments = self.env["stock.picking"]
for line in self: for line in self:
for move in line.move_ids: shipments |= line._get_out_pickings()
if move.location_dest_id.usage in ("supplier", "customer"):
if not line.customer_to_supplier:
picking_ids.append(move.picking_id.id)
shipments = list(set(picking_ids))
# choose the view_mode accordingly # choose the view_mode accordingly
if len(shipments) != 1: if len(shipments) != 1:
result["domain"] = "[('id', 'in', " + str(shipments) + ")]" result["domain"] = "[('id', 'in', " + str(shipments.ids) + ")]"
elif len(shipments) == 1: elif len(shipments) == 1:
res = self.env.ref("stock.view_picking_form", False) res = self.env.ref("stock.view_picking_form", False)
result["views"] = [(res and res.id or False, "form")] result["views"] = [(res and res.id or False, "form")]
result["res_id"] = shipments[0] result["res_id"] = shipments.ids[0]
return result return result
def action_view_rma_lines(self): def action_view_rma_lines(self):

View File

@@ -44,3 +44,19 @@ class StockMove(models.Model):
if move.rma_line_id: if move.rma_line_id:
move.partner_id = move.rma_line_id.partner_id.id or False move.partner_id = move.rma_line_id.partner_id.id or False
return res return res
@api.model
def _get_first_usage(self):
if self.move_orig_ids:
# We assume here that all origin moves come from the same place
return self.move_orig_ids[0]._get_first_usage()
else:
return self.location_id.usage
@api.model
def _get_last_usage(self):
if self.move_dest_ids:
# We assume here that all origin moves come from the same place
return self.move_dest_ids[0]._get_last_usage()
else:
return self.location_dest_id.usage