diff --git a/stock_ux/__manifest__.py b/stock_ux/__manifest__.py index c3135e833..a204042d0 100644 --- a/stock_ux/__manifest__.py +++ b/stock_ux/__manifest__.py @@ -19,7 +19,7 @@ ############################################################################## { "name": "Stock UX", - "version": "18.0.1.7.0", + "version": "18.0.1.8.0", "category": "Warehouse Management", "sequence": 14, "summary": "", diff --git a/stock_ux/models/__init__.py b/stock_ux/models/__init__.py index d58254965..285095479 100644 --- a/stock_ux/models/__init__.py +++ b/stock_ux/models/__init__.py @@ -11,6 +11,7 @@ from . import stock_move_line from . import stock_picking_type from . import res_config_settings +from . import res_company from . import stock_rule from . import stock_scrap from . import stock_location diff --git a/stock_ux/models/res_company.py b/stock_ux/models/res_company.py new file mode 100644 index 000000000..934a2b5f7 --- /dev/null +++ b/stock_ux/models/res_company.py @@ -0,0 +1,16 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + stock_ux_protect_moves = fields.Boolean( + string="Protect Stock Moves", + help="Prevent deletion of stock moves that originate from sales or purchase orders. " + "Users must make changes from the corresponding order instead.", + default=True, + ) diff --git a/stock_ux/models/stock_move.py b/stock_ux/models/stock_move.py index 09a3b9687..57015b831 100644 --- a/stock_ux/models/stock_move.py +++ b/stock_ux/models/stock_move.py @@ -125,7 +125,10 @@ def check_cancel(self): def _merge_moves(self, merge_into=False): # 22/04/2024: Agregamos esto porque sino al intentar confirmar compras con usuarios sin permisos, podia pasar que salga la constrain de arriba (check_cancel) - return super(StockMove, self.with_context(cancel_from_order=True))._merge_moves(merge_into=merge_into) + # Agregamos bypass_stock_ux_protect_moves para permitir el unlink de moves duplicados durante el merge + return super( + StockMove, self.with_context(cancel_from_order=True, bypass_stock_ux_protect_moves=True) + )._merge_moves(merge_into=merge_into) @api.model_create_multi def create(self, vals_list): @@ -147,6 +150,47 @@ def create(self, vals_list): return super(StockMove, self).create(vals_list) + def unlink(self): + """ + Prevenir eliminación de moves que provienen de ventas o compras. + Los usuarios deben hacer modificaciones desde la orden correspondiente. + """ + # Verificar si la protección está habilitada en la compañía + # Permitir unlink cuando viene de procesos internos de Odoo (merge, backorder, etc) + if not self.company_id.stock_ux_protect_moves or self._context.get("bypass_stock_ux_protect_moves"): + return super().unlink() + + # Verificar si hay moves que provienen de órdenes de venta o compra + # Verificamos primero si los campos existen para soportar instalación parcial de módulos + protected_moves = self.env["stock.move"] + origins = [] + + # Verificar moves de ventas (si sale_stock está instalado) + if "sale_line_id" in self._fields: + sale_moves = self.filtered(lambda m: m.sale_line_id) + if sale_moves: + protected_moves |= sale_moves + origins.append("sales orders") + + # Verificar moves de compras (si purchase_stock está instalado) + if "purchase_line_id" in self._fields: + purchase_moves = self.filtered(lambda m: m.purchase_line_id) + if purchase_moves: + protected_moves |= purchase_moves + origins.append("purchase orders") + + if protected_moves: + raise UserError( + _( + "Cannot delete stock moves that originate from %s.\n" + "Please make changes from the corresponding order instead.\n\n" + "Affected moves: %s" + ) + % (" or ".join(origins), ", ".join(protected_moves.mapped("reference"))) + ) + + return super().unlink() + @api.depends("state", "picking_id") def _compute_is_initial_demand_editable(self): super(StockMove, self)._compute_is_initial_demand_editable() diff --git a/stock_ux/views/res_company_views.xml b/stock_ux/views/res_company_views.xml index d42205c7b..890e45238 100644 --- a/stock_ux/views/res_company_views.xml +++ b/stock_ux/views/res_company_views.xml @@ -7,6 +7,10 @@ + +