Skip to content

Commit 80aaf60

Browse files
[IMP] sale_order_line_cancel: Allow to decrease product_uom_qty on line cancel
1 parent e963926 commit 80aaf60

File tree

7 files changed

+90
-2
lines changed

7 files changed

+90
-2
lines changed

sale_order_line_cancel/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"wizards/sale_order_line_cancel.xml",
1818
"views/sale_order.xml",
1919
"views/sale_order_line.xml",
20+
"views/res_config_settings_views.xml",
2021
],
2122
"website": "https://github.com/OCA/sale-workflow",
2223
"pre_init_hook": "pre_init_hook",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
from . import sale_order_line
22
from . import stock_move
33
from . import sale_order
4+
from . import res_company
5+
from . import res_config_settings
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2025 Michael Tietz (MT Software) <mtietz@mt-software.de>
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from odoo import fields, models
4+
5+
6+
class ResCompany(models.Model):
7+
_inherit = "res.company"
8+
9+
on_sale_line_cancel_decrease_line_qty = fields.Boolean(
10+
"On sale order line cancel decrease line quantity",
11+
help="On canceling the remaining qty to deliver of an order line "
12+
"it decreases the initial quantity",
13+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright 2025 Michael Tietz (MT Software) <mtietz@mt-software.de>
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from odoo import fields, models
4+
5+
6+
class ResConfigSettings(models.TransientModel):
7+
_inherit = "res.config.settings"
8+
9+
on_sale_line_cancel_decrease_line_qty = fields.Boolean(
10+
related="company_id.on_sale_line_cancel_decrease_line_qty", readonly=False
11+
)

sale_order_line_cancel/models/sale_order_line.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright 2018 Okia SPRL
22
# Copyright 2018 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
33
# Copyright 2020 ACSONE SA/NV
4+
# Copyright 2025 Michael Tietz (MT Software) <mtietz@mt-software.de>
45
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
56

67
from odoo import _, api, fields, models
@@ -41,7 +42,7 @@ def _compute_can_cancel_remaining_qty(self):
4142
@api.depends("qty_to_deliver", "product_qty_canceled")
4243
def _compute_product_qty_remains_to_deliver(self):
4344
for line in self:
44-
qty_remaining = line.qty_to_deliver - line.product_qty_canceled
45+
qty_remaining = max(0, line.qty_to_deliver - line.product_qty_canceled)
4546
line.product_qty_remains_to_deliver = qty_remaining
4647

4748
def _get_moves_to_cancel(self):
@@ -57,7 +58,18 @@ def _update_qty_canceled(self):
5758
for line in self:
5859
if line._get_moves_to_cancel():
5960
continue
60-
line.product_qty_canceled = line.qty_to_deliver
61+
qty_to_deliver = line.qty_to_deliver
62+
vals = {
63+
"product_qty_canceled": qty_to_deliver
64+
}
65+
if (
66+
line.state == "sale"
67+
and line.company_id.on_sale_line_cancel_decrease_line_qty
68+
):
69+
vals["product_uom_qty"] = max(
70+
line.qty_delivered, line.product_uom_qty - qty_to_deliver
71+
)
72+
line.write(vals)
6173

6274
def cancel_remaining_qty(self):
6375
lines = self.filtered(lambda l: l.can_cancel_remaining_qty)

sale_order_line_cancel/tests/test_sale_order_line_cancel.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright 2023 ACSONE SA/NV
2+
# Copyright 2025 Michael Tietz (MT Software) <mtietz@mt-software.de>
23
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
34

45

@@ -125,3 +126,25 @@ def test_draft_sale_order_with_picking_cancel(self):
125126
self.assertEqual(sale.order_line.product_qty_canceled, 0)
126127
self.assertEqual(sale.order_line.qty_to_deliver, 10)
127128
self.assertEqual(sale.order_line.product_qty_remains_to_deliver, 10)
129+
130+
def test_cancel_decrease_product_uom_qty(self):
131+
sale = self.sale
132+
sale.company_id.on_sale_line_cancel_decrease_line_qty = True
133+
sale.with_context(disable_cancel_warning=True).action_cancel()
134+
sale.picking_ids.unlink()
135+
sale.action_draft()
136+
sale.action_confirm()
137+
line = self.sale.order_line
138+
self.assertEqual(line.product_uom_qty, 10)
139+
ship = self.sale.picking_ids
140+
ship.action_assign()
141+
ship.move_ids.move_line_ids.qty_done = 4
142+
ship.with_context(cancel_backorder=False)._action_done()
143+
self.wiz.with_context(
144+
active_id=line.id, active_model="sale.order.line"
145+
).cancel_remaining_qty()
146+
self.assertEqual(line.product_qty_canceled, 6)
147+
self.assertEqual(line.product_qty_remains_to_deliver, 0)
148+
self.assertEqual(line.qty_to_deliver, 0)
149+
self.assertEqual(line.qty_delivered, 4)
150+
self.assertEqual(line.product_uom_qty, 4)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version='1.0' encoding='utf-8' ?>
2+
<odoo>
3+
<record id="res_config_settings_form_view" model="ir.ui.view">
4+
<field name="name">res.config.settings.form.view</field>
5+
<field name="model">res.config.settings</field>
6+
<field name="inherit_id" ref="sale.res_config_settings_view_form" />
7+
<field name="arch" type="xml">
8+
<xpath expr="//div[@id='proforma_configuration']" position="after">
9+
<div
10+
class="col-12 col-lg-6 o_setting_box"
11+
id="line_cancel_decrease_qty_configuration"
12+
>
13+
<div class="o_setting_left_pane">
14+
<field name="on_sale_line_cancel_decrease_line_qty" />
15+
</div>
16+
<div class="o_setting_right_pane">
17+
<label for="on_sale_line_cancel_decrease_line_qty" />
18+
<div class="text-muted">
19+
On canceling the remaining qty to deliver of an order line it decreases the initial quantity
20+
</div>
21+
</div>
22+
</div>
23+
</xpath>
24+
</field>
25+
</record>
26+
</odoo>

0 commit comments

Comments
 (0)