# accounts/signals.py from django.db.models.signals import post_save from django.dispatch import receiver from django.db import transaction from django.utils.text import slugify from hr.models import Employee from .models import User @receiver(post_save, sender=User) def create_employee_for_user(sender, instance: User, created: bool, **kwargs): """ Auto-create an Employee profile when a User is created. Idempotent, tenant-aligned, and makes a unique employee_number per tenant. """ if not created: return def _make_employee(): # Generate a readable employee_number from username/email, unique within tenant base = (instance.username or (instance.email or 'user')).split('@')[0] candidate = slugify(base)[:16] or 'emp' suffix = 1 emp_no = candidate while Employee.objects.filter(tenant=instance.tenant, employee_number=emp_no).exists(): suffix += 1 emp_no = f"{candidate}-{suffix}" # Create with basic info mirrored from User Employee.objects.create( tenant=instance.tenant, user=instance, employee_number=emp_no, first_name=instance.first_name or '', last_name=instance.last_name or '', email=instance.email ) # Defer until after outer transaction commits (avoids race conditions in tests/views) transaction.on_commit(_make_employee)