164 lines
5.7 KiB
Python
164 lines
5.7 KiB
Python
"""
|
|
Accounts signals - Handle onboarding events
|
|
"""
|
|
from django.db.models.signals import post_save, post_delete, pre_save
|
|
from django.dispatch import receiver
|
|
|
|
from .models import User, UserAcknowledgement, UserProvisionalLog, AcknowledgementContent, AcknowledgementChecklistItem
|
|
from .services import EmailService
|
|
|
|
|
|
# ==================== Version Control Signals ====================
|
|
|
|
@receiver(post_save, sender=AcknowledgementContent)
|
|
def create_content_version(sender, instance, created, **kwargs):
|
|
"""
|
|
Automatically create a version record when content is saved.
|
|
"""
|
|
from .version_models import ContentVersion
|
|
|
|
# Get the next version number
|
|
last_version = ContentVersion.objects.filter(
|
|
content=instance
|
|
).order_by('-version_number').first()
|
|
|
|
version_number = 1 if not last_version else last_version.version_number + 1
|
|
|
|
# Create version
|
|
ContentVersion.objects.create(
|
|
content=instance,
|
|
version_number=version_number,
|
|
title_en=instance.title_en,
|
|
title_ar=instance.title_ar,
|
|
description_en=instance.description_en,
|
|
description_ar=instance.description_ar,
|
|
content_en=instance.content_en,
|
|
content_ar=instance.content_ar,
|
|
role=instance.role,
|
|
order=instance.order,
|
|
is_active=instance.is_active,
|
|
# changed_by will be set via view
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=AcknowledgementChecklistItem)
|
|
def create_checklist_version(sender, instance, created, **kwargs):
|
|
"""
|
|
Automatically create a version record when checklist item is saved.
|
|
"""
|
|
from .version_models import ChecklistItemVersion
|
|
|
|
# Get the next version number
|
|
last_version = ChecklistItemVersion.objects.filter(
|
|
checklist_item=instance
|
|
).order_by('-version_number').first()
|
|
|
|
version_number = 1 if not last_version else last_version.version_number + 1
|
|
|
|
# Create version
|
|
ChecklistItemVersion.objects.create(
|
|
checklist_item=instance,
|
|
version_number=version_number,
|
|
text_en=instance.text_en,
|
|
text_ar=instance.text_ar,
|
|
description_en=instance.description_en,
|
|
description_ar=instance.description_ar,
|
|
is_required=instance.is_required,
|
|
is_active=instance.is_active,
|
|
order=instance.order,
|
|
content=instance.content,
|
|
role=instance.role,
|
|
# changed_by will be set via view
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def log_provisional_user_creation(sender, instance, created, **kwargs):
|
|
"""
|
|
Log when a provisional user is created
|
|
"""
|
|
if created and instance.is_provisional:
|
|
UserProvisionalLog.objects.create(
|
|
user=instance,
|
|
event_type='created',
|
|
description=f"Provisional user {instance.email} created",
|
|
metadata={
|
|
'email': instance.email,
|
|
'first_name': instance.first_name,
|
|
'last_name': instance.last_name
|
|
}
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=UserAcknowledgement)
|
|
def log_acknowledgement(sender, instance, created, **kwargs):
|
|
"""
|
|
Log when a user acknowledges an item
|
|
"""
|
|
if created and instance.is_acknowledged:
|
|
UserProvisionalLog.objects.create(
|
|
user=instance.user,
|
|
event_type='step_completed',
|
|
description=f"Acknowledged: {instance.checklist_item.text_en}",
|
|
metadata={
|
|
'checklist_item_id': str(instance.checklist_item.id),
|
|
'checklist_item_code': instance.checklist_item.code
|
|
}
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def check_onboarding_completion(sender, instance, **kwargs):
|
|
"""
|
|
Check if all required acknowledgements are completed
|
|
"""
|
|
if instance.is_provisional and not instance.acknowledgement_completed:
|
|
from .services import OnboardingService
|
|
|
|
required_items = OnboardingService.get_checklist_items(instance).filter(is_required=True)
|
|
acknowledged_items = UserAcknowledgement.objects.filter(
|
|
user=instance,
|
|
checklist_item__in=required_items,
|
|
is_acknowledged=True
|
|
)
|
|
|
|
# All required items acknowledged
|
|
if required_items.count() > 0 and acknowledged_items.count() == required_items.count():
|
|
UserProvisionalLog.objects.create(
|
|
user=instance,
|
|
event_type='wizard_completed',
|
|
description="All required acknowledgements completed",
|
|
metadata={
|
|
'total_items': required_items.count(),
|
|
'acknowledged_items': acknowledged_items.count()
|
|
}
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=User)
|
|
def log_account_activation(sender, instance, **kwargs):
|
|
"""
|
|
Log when a user account is activated
|
|
"""
|
|
if not instance.is_provisional and instance.acknowledgement_completed:
|
|
# Check if this is a recent activation (within last minute)
|
|
from django.utils import timezone
|
|
if instance.acknowledgement_completed_at and \
|
|
(timezone.now() - instance.acknowledgement_completed_at).total_seconds() < 60:
|
|
|
|
UserProvisionalLog.objects.create(
|
|
user=instance,
|
|
event_type='user_activated',
|
|
description=f"User {instance.email} account activated",
|
|
metadata={
|
|
'username': instance.username,
|
|
'email': instance.email
|
|
}
|
|
)
|
|
|
|
# Send notification to PX Admins
|
|
from django.contrib.auth import get_user_model
|
|
User = get_user_model()
|
|
admin_users = User.objects.filter(groups__name='PX Admin')
|
|
EmailService.send_completion_notification(instance, admin_users)
|