Skip to content

Commit

Permalink
[IMP] rma : propagate cancelation
Browse files Browse the repository at this point in the history
When canceling a rma order line, it will also cancel the previous (orig) steps.
Following steps (dest) can be managed with the propagate cancel option of the stock rules.
This commit also avoid canceling a whole picking which is problematic in case of the use of RMA groups
  • Loading branch information
florian-dacosta committed Sep 26, 2024
1 parent 44a3669 commit 6ae7556
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
15 changes: 11 additions & 4 deletions rma/models/rma_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,19 @@ def check_cancel(self):
def action_rma_cancel(self):
for order in self:
order.check_cancel()
# cancel ongoing orig moves
# dest move cancelation can be managed with propagate_cancel option
# on stock rules.
moves = order.move_ids
to_cancel_orig_moves = self.env["stock.move"]
while moves:
moves = moves.move_orig_ids.filtered(
lambda m: m.state not in ("done", "cancel") and m.picking_id
)
to_cancel_orig_moves |= moves
to_cancel_orig_moves._action_cancel()
order.write({"state": "canceled"})
order.move_ids._action_cancel()
shipments = order._get_in_pickings()
shipments |= order._get_out_pickings()
for ship in shipments:
ship.action_cancel()
return True

def _get_price_unit(self):
Expand Down
90 changes: 90 additions & 0 deletions rma/tests/test_rma.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,3 +1093,93 @@ def test_09_rma_state(self):
self.assertEqual(
rma.rma_line_ids.mapped("state"), ["approved", "approved", "approved"]
)

def test_10_rma_cancel_line(self):
# configure a new rule to make reception and expedition in 2 steps
rma_route = self.env.ref("rma.route_rma_customer")
rma_loc = self.env.ref("rma.location_rma")
rma_customer_rule = self.env.ref("rma.rule_rma_customer_out_pull")
rma_customer_rule.write({"procure_method": "make_to_order"})
self.env["stock.rule"].create(
{
"name": "reception => rma",
"action": "pull",
"picking_type_id": self.wh.int_type_id.id,
"location_src_id": self.wh.wh_input_stock_loc_id.id,
"location_dest_id": rma_loc.id,
"procure_method": "make_to_stock",
"route_id": rma_route.id,
"warehouse_id": self.wh.id,
"company_id": self.wh.company_id.id,
}
)
self.env["stock.rule"].create(
{
"name": "rma => reception",
"action": "push",
"picking_type_id": self.wh.int_type_id.id,
"location_src_id": rma_loc.id,
"location_dest_id": self.wh.wh_input_stock_loc_id.id,
"procure_method": "make_to_stock",
"route_id": rma_route.id,
"warehouse_id": self.wh.id,
"company_id": self.wh.company_id.id,
}
)
# Generate expedition for the rma group
self.rma_customer_id.rma_line_ids.action_rma_to_approve()
wizard = self.rma_make_picking.with_context(
**{
"active_ids": self.rma_customer_id.rma_line_ids.ids,
"active_model": "rma.order.line",
"picking_type": "incoming",
"active_id": 1,
}
).create({})
wizard._create_picking()
self.rma_customer_id.rma_line_ids.action_view_in_shipments()
# cancel first line and check it cancel the dest moves, but leave the picking
# ongoing for the 2 other lines
first_rma_line = self.rma_customer_id.rma_line_ids[0]
second_rma_line = self.rma_customer_id.rma_line_ids[1]
first_line_in_move = first_rma_line.move_ids.filtered(
lambda m: m.location_dest_id == rma_loc
)
first_line_in_dest_move = first_line_in_move.move_dest_ids
reception_picking = first_line_in_move.picking_id
self.assertEqual(first_line_in_dest_move.state, "waiting")
first_rma_line.action_rma_cancel()
self.assertEqual(first_line_in_dest_move.state, "cancel")
self.assertEqual(first_line_in_move.state, "cancel")
self.assertEqual(reception_picking.state, "assigned")
second_line_in_move = second_rma_line.move_ids.filtered(
lambda m: m.location_dest_id == rma_loc
)
self.assertEqual(second_line_in_move.state, "assigned")

# generate 2 step expedition for the 2 remaining lines
wizard = self.rma_make_picking.with_context(
**{
"active_ids": self.rma_customer_id.rma_line_ids.filtered(
lambda rol: rol.state != "canceled"
).ids,
"active_model": "rma.order.line",
"picking_type": "outgoing",
"active_id": 1,
}
).create({})
for line in wizard.item_ids:
line.qty_to_deliver = line.product_qty
wizard._create_picking()
# cancel first line, check both chained move are canceled
second_rma_out_move = second_rma_line.move_ids.filtered(
lambda m: m.picking_id.picking_type_code == "outgoing"
)
second_rma_out_move_orig = second_rma_out_move.move_orig_ids
self.assertTrue(second_rma_out_move_orig)
self.assertEqual(second_rma_out_move.state, "waiting")
second_rma_line.action_rma_cancel()
self.assertEqual(second_rma_out_move.state, "cancel")
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")

0 comments on commit 6ae7556

Please sign in to comment.