41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
# 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) |