diff --git a/sale_order_line_cancel/__manifest__.py b/sale_order_line_cancel/__manifest__.py index 91002adc450..c86db022eb6 100644 --- a/sale_order_line_cancel/__manifest__.py +++ b/sale_order_line_cancel/__manifest__.py @@ -1,4 +1,5 @@ -# © 2016 Sylvain Van Hoof +# Copyright 2018 Sylvain Van Hoof (Okia SPRL) +# Copyright 2018 Jacques-Etienne Baudoux (BCIM) # Copyright 2023 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/sale_order_line_cancel/models/sale_order.py b/sale_order_line_cancel/models/sale_order.py index b5d7a36922d..cb9ec0a3de7 100644 --- a/sale_order_line_cancel/models/sale_order.py +++ b/sale_order_line_cancel/models/sale_order.py @@ -1,11 +1,11 @@ # Copyright 2023 ACSONE SA/NV +# Copyright 2024 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import models class SaleOrder(models.Model): - _inherit = "sale.order" def action_draft(self): @@ -16,14 +16,18 @@ def action_draft(self): def _action_cancel(self): orders = self.filtered(lambda s: s.state != "cancel") - orders_with_picking = orders.filtered("picking_ids") + orders_with_stock_move = orders.filtered( + lambda o: any( + line.qty_delivered_method == "stock_move" for line in o.order_line + ) + ) res = None - if orders_with_picking: - orders_with_picking = orders_with_picking.with_context( - orders_cancel_by_running_procurements=orders_with_picking.ids + if orders_with_stock_move: + orders_with_stock_move = orders_with_stock_move.with_context( + orders_cancel_by_running_procurements=orders_with_stock_move.ids ) - res = super(SaleOrder, orders_with_picking)._action_cancel() - remaining_orders = orders - orders_with_picking + res = super(SaleOrder, orders_with_stock_move)._action_cancel() + remaining_orders = orders - orders_with_stock_move if remaining_orders: res = super(SaleOrder, remaining_orders)._action_cancel() diff --git a/sale_order_line_cancel/models/sale_order_line.py b/sale_order_line_cancel/models/sale_order_line.py index 575b4266c3d..e9dc71d5e33 100644 --- a/sale_order_line_cancel/models/sale_order_line.py +++ b/sale_order_line_cancel/models/sale_order_line.py @@ -1,4 +1,5 @@ # Copyright 2018 Okia SPRL +# Copyright 2018 Jacques-Etienne Baudoux (BCIM) # Copyright 2020 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -34,7 +35,7 @@ def _compute_can_cancel_remaining_qty(self): ) == 1 and rec.state in ("sale", "done") - and rec.move_ids + and rec.qty_delivered_method == "stock_move" ) @api.depends( @@ -44,10 +45,8 @@ def _compute_can_cancel_remaining_qty(self): ) def _compute_product_qty_remains_to_deliver(self): for line in self: - remaining_to_deliver = ( - line.product_uom_qty - line.qty_delivered - line.product_qty_canceled - ) - line.product_qty_remains_to_deliver = remaining_to_deliver + qty_remaining = line.qty_to_deliver - line.product_qty_canceled + line.product_qty_remains_to_deliver = qty_remaining def _get_moves_to_cancel(self): return self.move_ids.filtered(lambda m: m.state not in ("done", "cancel")) @@ -101,11 +100,11 @@ def _cancel_by_running_procurement(self): simulate_procured_qty = self.product_uom_qty + qty_to_cancel self.ensure_one() line = self.with_context(simulate_procured_qty=simulate_procured_qty) - previous_sate = line.state + previous_state = line.state line.state = "sale" line._action_launch_stock_rule(simulate_procured_qty) - line.state = previous_sate - line.product_qty_canceled += qty_to_cancel + line.state = previous_state + line.product_qty_canceled = line.qty_to_deliver def _get_qty_procurement(self, previous_product_uom_qty=False): return self.env.context.get( diff --git a/sale_order_line_cancel/models/stock_move.py b/sale_order_line_cancel/models/stock_move.py index 80167aa9cc1..088149baf3f 100644 --- a/sale_order_line_cancel/models/stock_move.py +++ b/sale_order_line_cancel/models/stock_move.py @@ -1,11 +1,11 @@ # Copyright 2023 ACSONE SA/NV +# Copyright 2024 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import models class StockMove(models.Model): - _inherit = "stock.move" def _action_cancel(self): @@ -13,8 +13,10 @@ def _action_cancel(self): lambda m: m.sale_line_id and m.state not in ("done", "cancel") ) res = super()._action_cancel() - for rec in sale_moves: - if rec.state != "cancel": + sale_lines = sale_moves.filtered(lambda m: m.state == "cancel").sale_line_id + for line in sale_lines: + # Update SO line qty canceled only when all remaining moves are canceled + if line._get_moves_to_cancel(): continue - rec.sale_line_id.product_qty_canceled = rec.product_uom_qty + line.product_qty_canceled = line.qty_to_deliver return res diff --git a/sale_order_line_cancel/models/stock_picking.py b/sale_order_line_cancel/models/stock_picking.py index 9342699c590..c4e7bf3858e 100644 --- a/sale_order_line_cancel/models/stock_picking.py +++ b/sale_order_line_cancel/models/stock_picking.py @@ -5,7 +5,6 @@ class StockPicking(models.Model): - _inherit = "stock.picking" def action_cancel(self):