import random import logging from odoo import api, fields, models, _ from odoo.exceptions import UserError _logger = logging.getLogger(__name__) class HrEmployee(models.Model): _inherit = 'hr.employee' employee_pin = fields.Char( string='Employee PIN', size=6, copy=False, help='Unique 6-digit PIN for this employee. ' 'Globally unique across all companies.', ) _sql_constraints = [ ( 'employee_pin_unique', 'UNIQUE(employee_pin)', 'The Employee PIN must be unique across all employees and companies.', ) ] # ------------------------------------------------------------------ # Helpers # ------------------------------------------------------------------ @api.model def _generate_unique_pin(self): """Return a random 6-digit string that is not yet used by any employee.""" existing = set( self.sudo().search([('employee_pin', '!=', False)]).mapped('employee_pin') ) for _attempt in range(1000): pin = '{:06d}'.format(random.randint(0, 999999)) if pin not in existing: return pin raise UserError( _('Could not generate a unique PIN after 1000 attempts. ' 'The PIN pool may be exhausted.') ) # ------------------------------------------------------------------ # ORM overrides # ------------------------------------------------------------------ @api.model_create_multi def create(self, vals_list): for vals in vals_list: if not vals.get('employee_pin'): vals['employee_pin'] = self._generate_unique_pin() return super().create(vals_list) # ------------------------------------------------------------------ # Actions # ------------------------------------------------------------------ def action_regenerate_pin(self): """Regenerate a new unique PIN for this employee (called from button).""" self.ensure_one() new_pin = self._generate_unique_pin() self.employee_pin = new_pin return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': _('PIN Regenerated'), 'message': _('New PIN for %s: %s') % (self.name, new_pin), 'type': 'success', 'sticky': False, }, }