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'