From de4f502d0177ff2eedf64653ef6c37910e716354 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Wed, 28 Jan 2026 13:45:34 +0700 Subject: [PATCH] feat: Add subcontract lot generation wizard and UI buttons to stock pickings and moves, including validation for cancelled manufacturing orders. --- README.md | 1 + models/stock_move.py | 17 ++++++ security/ir.model.access.csv | 2 + views/stock_move_views.xml | 20 +++++++ views/stock_picking_views.xml | 69 ++++++++++++++++++++++ wizard/subcontract_lot_generator_views.xml | 40 +++++++++++++ 6 files changed, 149 insertions(+) create mode 100644 security/ir.model.access.csv create mode 100644 views/stock_move_views.xml create mode 100644 views/stock_picking_views.xml create mode 100644 wizard/subcontract_lot_generator_views.xml diff --git a/README.md b/README.md index dc43187..dcae39c 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This Odoo 19 module provides automated lot/serial number generation specifically ## Features - **Auto-Generate Lots**: Automatically generates lot/serial numbers for subcontract receipt moves based on the product's configured sequence. +- **Validation Check**: Prevents lot generation if the linked Subcontract Manufacturing Order is cancelled, alerting the user to potential data inconsistency. - **Wizard Support**: Includes a "Generate Subcontract Lots" wizard for manual control and batch generation. - **Validation Hook**: Automatically triggers lot generation when validating a subcontracting receipt (Stock Picking). - **Native Compatibility**: Uses Odoo 19's standard `lot_sequence_id` on the product template, ensuring no conflict with standard features. diff --git a/models/stock_move.py b/models/stock_move.py index cec1df0..a16abdc 100644 --- a/models/stock_move.py +++ b/models/stock_move.py @@ -1,4 +1,6 @@ + from odoo import api, models, _ +from odoo.exceptions import UserError import logging _logger = logging.getLogger(__name__) @@ -11,8 +13,23 @@ class StockMove(models.Model): """ Auto-generate lot numbers for subcontracting moves. This method handles the automatic lot generation for subcontracted products. + It also validates that the linked Manufacturing Order is not cancelled. """ self.ensure_one() + + if getattr(self, 'is_subcontract', False): + # Check for cancelled subcontract MOs + # We use getattr/safe access or rely on the fact that this module depends on mrp_subcontracting + productions = self._get_subcontract_production() + cancelled_productions = productions.filtered(lambda p: p.state == 'cancel') + if cancelled_productions: + raise UserError(_( + "Cannot generate lots for product %s.\n" + "The linked Subcontracting Manufacturing Order (e.g., %s) is cancelled.\n" + "Lots generated would not be correctly linked to the receipt quantity.\n" + "Please check the Manufacturing Order status." + ) % (self.product_id.display_name, cancelled_productions[0].name)) + if not self.product_id.tracking in ['lot', 'serial']: return [] diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv new file mode 100644 index 0000000..234ef90 --- /dev/null +++ b/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_subcontract_lot_generator,subcontract.lot.generator,model_subcontract_lot_generator,base.group_user,1,1,1,1 diff --git a/views/stock_move_views.xml b/views/stock_move_views.xml new file mode 100644 index 0000000..fceadbe --- /dev/null +++ b/views/stock_move_views.xml @@ -0,0 +1,20 @@ + + + + + stock.move.form.inherit.lot.generation + stock.move + + + + + + + + diff --git a/wizard/subcontract_lot_generator_views.xml b/wizard/subcontract_lot_generator_views.xml new file mode 100644 index 0000000..9f1059f --- /dev/null +++ b/wizard/subcontract_lot_generator_views.xml @@ -0,0 +1,40 @@ + + + + + subcontract.lot.generator.form + subcontract.lot.generator + +
+ + + + + + + + + + + + + +
+
+
+
+
+ + + + Generate Subcontract Lots + subcontract.lot.generator + form + new + { + 'default_picking_id': active_id, + } + +