Initial commit: Odoo 18.0-20251222 extra-addons
This commit is contained in:
2
sale_order_line_remove/models/__init__.py
Executable file
2
sale_order_line_remove/models/__init__.py
Executable file
@@ -0,0 +1,2 @@
|
||||
from . import sale_order
|
||||
from . import res_config_settings
|
||||
14
sale_order_line_remove/models/res_config_settings.py
Executable file
14
sale_order_line_remove/models/res_config_settings.py
Executable file
@@ -0,0 +1,14 @@
|
||||
# Copyright 2025 ForgeFlow, S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
restrict_sale_order_line_remove = fields.Boolean(
|
||||
"Allow Sale Order Line Remove",
|
||||
config_parameter="sale.order.line.remove",
|
||||
help="Allow removing confirmed sale order lines only "
|
||||
"if they are not invoiced or delivered.",
|
||||
)
|
||||
60
sale_order_line_remove/models/sale_order.py
Executable file
60
sale_order_line_remove/models/sale_order.py
Executable file
@@ -0,0 +1,60 @@
|
||||
# Copyright 2023 ForgeFlow, S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
def _check_line_unlink(self):
|
||||
non_removable_lines = super()._check_line_unlink()
|
||||
if (
|
||||
not self.env["ir.config_parameter"]
|
||||
.sudo()
|
||||
.get_param("sale.order.line.remove")
|
||||
):
|
||||
return non_removable_lines
|
||||
else:
|
||||
removable_lines = self.filtered(
|
||||
lambda line: line.state in ("sale", "done")
|
||||
and not line.invoice_lines
|
||||
and not line.move_ids.filtered(lambda move: move.state == "done")
|
||||
)
|
||||
invoiced_lines = self.sudo().filtered(
|
||||
lambda line: line.state in ("sale", "done") and line.invoice_lines
|
||||
)
|
||||
if invoiced_lines:
|
||||
raise UserError(
|
||||
_("You can not remove an order line that has been invoiced")
|
||||
)
|
||||
delivered_lines = self.sudo().filtered(
|
||||
lambda line: line.state in ("sale", "done")
|
||||
and line.move_ids.filtered(lambda move: move.state == "done")
|
||||
)
|
||||
if delivered_lines:
|
||||
raise UserError(
|
||||
_("You can not remove an order line that has been delivered")
|
||||
)
|
||||
return non_removable_lines - removable_lines
|
||||
|
||||
def unlink(self):
|
||||
non_removable_lines = self._check_line_unlink()
|
||||
if (
|
||||
not self.env["ir.config_parameter"]
|
||||
.sudo()
|
||||
.get_param("sale.order.line.remove")
|
||||
):
|
||||
return super().unlink()
|
||||
else:
|
||||
for line in self - non_removable_lines:
|
||||
related_pickings = line.move_ids.mapped("picking_id")
|
||||
line.move_ids.filtered(
|
||||
lambda move: move.state not in ("done", "cancel")
|
||||
)._action_cancel()
|
||||
line.move_ids.filtered(lambda move: move.state != "done").unlink()
|
||||
for picking in related_pickings:
|
||||
if not picking.move_ids_without_package:
|
||||
picking.unlink()
|
||||
return super().unlink()
|
||||
Reference in New Issue
Block a user