product_lot_sequence_per_pr.../models/product_template.py
2025-09-29 11:47:29 +07:00

63 lines
2.9 KiB
Python

from odoo import api, fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
lot_sequence_id = fields.Many2one(
'ir.sequence',
string='Serial/Lot Numbers Sequence',
domain=[('code', '=', 'stock.lot.serial')],
help='Technical Field: The Ir.Sequence record that is used to generate serial/lot numbers for this product'
)
serial_prefix_format = fields.Char(
'Custom Lot/Serial',
compute='_compute_serial_prefix_format',
inverse='_inverse_serial_prefix_format',
help='Set a prefix to generate serial/lot numbers automatically when receiving or producing this product. '
'Use % codes like %(y)s for year, %(month)s for month, etc.'
)
next_serial = fields.Char(
'Next Number',
compute='_compute_next_serial',
help='The next serial/lot number to be generated for this product'
)
@api.depends('lot_sequence_id', 'lot_sequence_id.prefix')
def _compute_serial_prefix_format(self):
for template in self:
template.serial_prefix_format = template.lot_sequence_id.prefix or ""
def _inverse_serial_prefix_format(self):
valid_sequences = self.env['ir.sequence'].search([('prefix', 'in', self.mapped('serial_prefix_format'))])
sequences_by_prefix = {seq.prefix: seq for seq in valid_sequences}
for template in self:
if template.serial_prefix_format:
if template.serial_prefix_format in sequences_by_prefix:
template.lot_sequence_id = sequences_by_prefix[template.serial_prefix_format]
else:
# Create a new sequence with the given prefix
new_sequence = self.env['ir.sequence'].create({
'name': f'{template.name} Serial Sequence',
'code': 'stock.lot.serial',
'prefix': template.serial_prefix_format,
'padding': 7,
'company_id': False, # Global sequence to avoid cross-company conflicts
})
template.lot_sequence_id = new_sequence
sequences_by_prefix[template.serial_prefix_format] = new_sequence
else:
# Reset to default if no prefix
template.lot_sequence_id = self.env.ref('stock.sequence_production_lots', raise_if_not_found=False)
@api.depends('serial_prefix_format', 'lot_sequence_id')
def _compute_next_serial(self):
for template in self:
if template.lot_sequence_id:
template.next_serial = '{:0{}d}{}'.format(
template.lot_sequence_id.number_next_actual,
template.lot_sequence_id.padding,
template.lot_sequence_id.suffix or ""
)
else:
template.next_serial = '00001'