snapshot: preserve reliability hardening and Workdock identity pass

This commit is contained in:
Md Bayazid Bostame
2026-03-27 00:28:34 +01:00
parent 811bcd8745
commit 8553482ddd
39 changed files with 1393 additions and 320 deletions

View File

@@ -4,7 +4,7 @@ import base64
import mimetypes
import re
from celery import shared_task
from celery import current_task, shared_task
from django.contrib.auth import get_user_model
from django.conf import settings
from django.utils import timezone
@@ -13,8 +13,8 @@ from jinja2 import Template
from pypdf import PageObject, PdfReader, PdfWriter
from xhtml2pdf import pisa
from .branding import get_company_contact_copy, get_default_notification_templates, get_portal_letterhead_path
from .models import EmployeeProfile, IntroChecklistItem, NotificationRule, NotificationTemplate, OffboardingRequest, OnboardingIntroductionSession, OnboardingRequest, ScheduledWelcomeEmail, WorkflowConfig
from .branding import get_branding_email_copy, get_company_contact_copy, get_default_notification_templates, get_portal_letterhead_path
from .models import AsyncTaskLog, EmployeeProfile, IntroChecklistItem, NotificationRule, NotificationTemplate, OffboardingRequest, OnboardingIntroductionSession, OnboardingRequest, ScheduledWelcomeEmail, WorkflowConfig
from .emailing import send_system_email
from .services import upload_to_nextcloud
from .services import get_email_test_redirect, is_email_test_mode
@@ -247,6 +247,27 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
},
}
def _start_task_log(task_name: str, *, target_type: str = '', target_id: int | None = None, target_label: str = '') -> AsyncTaskLog:
task_request = getattr(current_task, 'request', None)
return AsyncTaskLog.objects.create(
task_name=task_name,
task_id=getattr(task_request, 'id', '') or '',
target_type=target_type,
target_id=target_id,
target_label=target_label,
status='started',
)
def _finish_task_log(task_log: AsyncTaskLog | None, *, status: str, error_message: str = '') -> None:
if not task_log:
return
task_log.status = status
task_log.error_message = error_message
task_log.finished_at = timezone.now()
task_log.save(update_fields=['status', 'error_message', 'finished_at'])
def _split_name(full_name: str) -> tuple[str, str]:
parts = full_name.split()
if not parts:
@@ -1196,6 +1217,12 @@ def _generate_offboarding_pdf(request_obj: OffboardingRequest) -> Path:
@shared_task
def process_onboarding_request(onboarding_request_id: int) -> None:
request_obj = OnboardingRequest.objects.get(id=onboarding_request_id)
task_log = _start_task_log(
'process_onboarding_request',
target_type='onboarding_request',
target_id=request_obj.id,
target_label=request_obj.full_name,
)
request_obj.processing_status = 'processing'
request_obj.last_error = ''
request_obj.save(update_fields=['processing_status', 'last_error'])
@@ -1301,16 +1328,24 @@ def process_onboarding_request(onboarding_request_id: int) -> None:
request_obj.processing_status = 'completed'
request_obj.last_error = ''
request_obj.save(update_fields=['processing_status', 'last_error'])
_finish_task_log(task_log, status='succeeded')
except Exception as exc:
request_obj.processing_status = 'failed'
request_obj.last_error = str(exc)
request_obj.save(update_fields=['processing_status', 'last_error'])
_finish_task_log(task_log, status='failed', error_message=str(exc))
raise
@shared_task
def process_offboarding_request(offboarding_request_id: int) -> None:
request_obj = OffboardingRequest.objects.get(id=offboarding_request_id)
task_log = _start_task_log(
'process_offboarding_request',
target_type='offboarding_request',
target_id=request_obj.id,
target_label=request_obj.full_name,
)
request_obj.processing_status = 'processing'
request_obj.last_error = ''
request_obj.save(update_fields=['processing_status', 'last_error'])
@@ -1380,10 +1415,12 @@ def process_offboarding_request(offboarding_request_id: int) -> None:
request_obj.processing_status = 'completed'
request_obj.last_error = ''
request_obj.save(update_fields=['processing_status', 'last_error'])
_finish_task_log(task_log, status='succeeded')
except Exception as exc:
request_obj.processing_status = 'failed'
request_obj.last_error = str(exc)
request_obj.save(update_fields=['processing_status', 'last_error'])
_finish_task_log(task_log, status='failed', error_message=str(exc))
raise
@@ -1392,15 +1429,24 @@ def send_scheduled_welcome_email(scheduled_email_id: int, force_now: bool = Fals
scheduled = ScheduledWelcomeEmail.objects.select_related('onboarding_request').filter(id=scheduled_email_id).first()
if not scheduled:
return
task_log = _start_task_log(
'send_scheduled_welcome_email',
target_type='scheduled_welcome_email',
target_id=scheduled.id,
target_label=scheduled.recipient_email,
)
if scheduled.status in {'sent', 'cancelled'} and not force_now:
_finish_task_log(task_log, status='succeeded')
return
if scheduled.status == 'paused' and not force_now:
_finish_task_log(task_log, status='succeeded')
return
if not force_now and timezone.now() < scheduled.send_at:
async_result = send_scheduled_welcome_email.apply_async(args=[scheduled.id], eta=scheduled.send_at)
scheduled.celery_task_id = async_result.id or scheduled.celery_task_id
scheduled.save(update_fields=['celery_task_id', 'updated_at'])
_finish_task_log(task_log, status='succeeded')
return
request_obj = scheduled.onboarding_request
@@ -1441,9 +1487,11 @@ def send_scheduled_welcome_email(scheduled_email_id: int, force_now: bool = Fals
scheduled.status = 'sent'
scheduled.sent_at = timezone.now()
scheduled.last_error = ''
_finish_task_log(task_log, status='succeeded')
except Exception as exc:
scheduled.status = 'failed'
scheduled.last_error = str(exc)
_finish_task_log(task_log, status='failed', error_message=str(exc))
raise
finally:
scheduled.save(update_fields=['status', 'sent_at', 'last_error', 'updated_at'])