Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][FIX] fix rma management using multi step routes #575

Open
wants to merge 1 commit into
base: 17.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 16 additions & 24 deletions rma/models/rma_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ def _get_in_moves(self):
moves |= move
return moves

@api.model
def _get_out_moves(self):
moves = self.env["stock.move"]
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":
moves |= move
elif first_usage == "supplier" and last_usage == "customer":
moves |= moves
return moves

@api.model
def _get_out_pickings(self):
pickings = self.env["stock.picking"]
Expand Down Expand Up @@ -101,30 +113,10 @@ def _get_rma_move_qty(self, states, direction="in"):
product_obj = self.env["uom.uom"]
qty = 0.0
if direction == "in":
moves = rec.move_ids.filtered(
lambda m: m.state in states
and (
m.location_id.usage == "supplier"
or m.location_id.usage == "customer"
)
and (
m.location_dest_id.usage == "internal"
or m.location_dest_id.usage == "supplier"
)
)
elif direction == "out":
moves = rec.move_ids.filtered(
lambda m: m.state in states
and (
m.location_dest_id.usage == "supplier"
or m.location_dest_id.usage == "customer"
)
and (
m.location_id.usage == "internal"
or m.location_id.usage == "supplier"
)
)
for move in moves:
moves = rec._get_in_moves()
else:
moves = rec._get_out_moves()
for move in moves.filtered(lambda m: m.state in states):
# If the move is part of a chain don't count it
if direction == "out" and move.move_orig_ids:
continue
Expand Down
6 changes: 6 additions & 0 deletions rma/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,9 @@ def _update_reserved_quantity(
def _prepare_merge_moves_distinct_fields(self):
res = super()._prepare_merge_moves_distinct_fields()
return res + ["rma_line_id"]

def _prepare_procurement_values(self):
self.ensure_one()
res = super()._prepare_procurement_values()
res["rma_line_id"] = self.rma_line_id.id
return res
5 changes: 5 additions & 0 deletions rma/models/stock_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ def _get_stock_move_values(
company_id,
values,
)
line = self.env["rma.order.line"]
if "rma_line_id" in values:
line = values.get("rma_line_id")
line = self.env["rma.order.line"].browse([line])
elif "group_id" in values:
pg = values["group_id"]
line = pg.rma_line_id
if line:
res["rma_line_id"] = line.id
if line.delivery_address_id:
res["partner_id"] = line.delivery_address_id.id
Expand Down
109 changes: 92 additions & 17 deletions rma/tests/test_rma.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def setUpClass(cls):
cls.rma_cust_replace_op_id = cls.env.ref("rma.rma_operation_customer_replace")
cls.rma_sup_replace_op_id = cls.env.ref("rma.rma_operation_supplier_replace")
cls.rma_ds_replace_op_id = cls.env.ref("rma.rma_operation_ds_replace")
cls.customer_route = cls.env.ref("rma.route_rma_customer")
cls.input_location = cls.env.ref("stock.stock_location_company")
cls.output_location = cls.env.ref("stock.stock_location_output")
cls.category = cls._create_product_category(
"one_step", cls.rma_cust_replace_op_id, cls.rma_sup_replace_op_id
)
Expand Down Expand Up @@ -82,7 +85,7 @@ def setUpClass(cls):
@classmethod
def _create_user(cls, login, groups, company):
group_ids = [group.id for group in groups]
user = cls.res_users_model.create(
user = cls.res_users_model.with_context(no_reset_password=True).create(
{
"name": login,
"login": login,
Expand All @@ -105,14 +108,16 @@ def _receive_rma(cls, rma_line_ids):
}
).create({})
wizard._create_picking()
res = rma_line_ids.action_view_in_shipments()
picking = cls.env["stock.picking"].browse(res["res_id"])
picking.action_assign()
for mv in picking.move_ids:
mv.quantity = mv.product_uom_qty
mv.picked = True
picking._action_done()
return picking
pickings = rma_line_ids._get_in_pickings()
pickings.action_assign()
for picking in pickings:
for mv in picking.move_ids:
mv.quantity = mv.product_uom_qty
mv.picked = True
# In case of two step pickings, ship in two steps:
while pickings.filtered(lambda p: p.state == "assigned"):
pickings._action_done()
return pickings

@classmethod
def _deliver_rma(cls, rma_line_ids):
Expand All @@ -125,14 +130,14 @@ def _deliver_rma(cls, rma_line_ids):
}
).create({})
wizard._create_picking()
res = rma_line_ids.action_view_out_shipments()
picking = cls.env["stock.picking"].browse(res["res_id"])
picking.action_assign()
for mv in picking.move_ids:
mv.quantity = mv.product_uom_qty
mv.picked = True
picking._action_done()
return picking
pickings = rma_line_ids._get_out_pickings()
pickings.action_assign()
for picking in pickings:
for mv in picking.move_ids:
mv.quantity = mv.product_uom_qty
mv.picked = True
pickings._action_done()
return pickings

@classmethod
def _create_product_category(
Expand Down Expand Up @@ -1188,3 +1193,73 @@ def test_10_rma_cancel_line(self):
self.assertEqual(second_rma_out_move_orig.state, "cancel")
# check picking is not canceled because third line has not been yet.
self.assertEqual(second_rma_out_move.picking_id.state, "waiting")

def test_11_customer_rma_multi_step(self):
"""
Receive a product and then return it using a multi-step route.
"""
# Alter the customer RMA route to make it multi-step
# Get rid of the duplicated rule
self.env.ref("rma.rule_rma_customer_out_pull").active = False
self.env.ref("rma.rule_rma_customer_in_pull").active = False
cust_in_pull_rule = self.customer_route.rule_ids.filtered(
lambda r: r.location_dest_id == self.stock_rma_location
)
cust_in_pull_rule.location_dest_id = self.input_location
cust_out_pull_rule = self.customer_route.rule_ids.filtered(
lambda r: r.location_src_id == self.env.ref("rma.location_rma")
)
cust_out_pull_rule.location_src_id = self.output_location
cust_out_pull_rule.procure_method = "make_to_order"
self.env["stock.rule"].create(
{
"name": "RMA->Output",
"action": "pull",
"warehouse_id": self.wh.id,
"location_src_id": self.env.ref("rma.location_rma").id,
"location_dest_id": self.output_location.id,
"procure_method": "make_to_stock",
"route_id": self.customer_route.id,
"picking_type_id": self.env.ref("stock.picking_type_internal").id,
}
)
self.env["stock.rule"].create(
{
"name": "Output->RMA",
"action": "pull",
"warehouse_id": self.wh.id,
"location_src_id": self.input_location.id,
"location_dest_id": self.env.ref("rma.location_rma").id,
"procure_method": "make_to_order",
"route_id": self.customer_route.id,
"picking_type_id": self.env.ref("stock.picking_type_internal").id,
}
)
# Set a standard price on the products
self.product_1.standard_price = 10
self._create_inventory(
self.product_1, 20.0, self.env.ref("stock.stock_location_customers")
)
products2move = [
(self.product_1, 3),
]
self.product_1.categ_id.rma_customer_operation_id = self.rma_cust_replace_op_id
rma_customer_id = self._create_rma_from_move(
products2move,
"customer",
self.env.ref("base.res_partner_2"),
dropship=False,
)
rma = rma_customer_id.rma_line_ids
rma.action_rma_to_approve()
self.assertEqual(rma.qty_to_receive, 3)
self.assertEqual(rma.qty_received, 0)
self._receive_rma(rma)
self.assertEqual(len(rma.move_ids), 2)
self.assertEqual(rma.qty_to_receive, 0)
self.assertEqual(rma.qty_received, 3)
self.assertEqual(rma.qty_to_deliver, 3)
self._deliver_rma(rma)
self.assertEqual(rma.qty_to_deliver, 0)
self.assertEqual(rma.qty_delivered, 3)
self.assertEqual(len(rma.move_ids), 4)
3 changes: 2 additions & 1 deletion rma/wizards/rma_make_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ def _get_procurement_group_data(self, item):
"partner_id": item.line_id.partner_id.id,
"name": item.line_id.rma_id.name or item.line_id.name,
"rma_id": item.line_id.rma_id and item.line_id.rma_id.id or False,
"rma_line_id": item.line_id.id if not item.line_id.rma_id else False,
}
if not item.line_id.rma_id:
group_data["rma_line_id"] = item.line_id and item.line_id.id or False
return group_data

@api.model
Expand Down
Loading