from typing import Dict, Any, List from django.db import transaction from core.models.project_scope_template import ProjectScopeTemplate, ProjectAreaTemplate, ProjectTaskTemplate from core.models.scope_template import ScopeTemplate, AreaTemplate, TaskTemplate from core.models.enums import TaskFrequencyChoices as Freq TemplatePayload = Dict[str, Any] @transaction.atomic def build_scope_template(payload: TemplatePayload) -> ScopeTemplate: tpl = ScopeTemplate.objects.create( name=payload["name"], description=payload.get("description") or "", is_active=payload.get("is_active") or payload.get("isActive", True), ) # Support both camelCase (areaTemplates) and snake_case (areas) for flexibility areas = payload.get("areaTemplates") or payload.get("areas", []) for area_data in areas: area = AreaTemplate.objects.create( scope_template=tpl, name=area_data["name"], order=area_data.get("order", 0), ) # Support both camelCase (taskTemplates) and snake_case (tasks) for flexibility tasks_data = area_data.get("taskTemplates") or area_data.get("tasks", []) tasks: List[TaskTemplate] = [] for t in tasks_data: # Normalize frequency to lowercase to match enum values frequency = t.get("frequency", Freq.AS_NEEDED) if isinstance(frequency, str): frequency = frequency.lower() tasks.append(TaskTemplate( area_template=area, description=t["description"], checklist_description=t.get("checklist_description") or t.get("checklistDescription") or "", frequency=frequency, order=t.get("order", 0), is_conditional=t.get("is_conditional") or t.get("isConditional", False), estimated_minutes=t.get("estimated_minutes") or t.get("estimatedMinutes"), )) if tasks: TaskTemplate.objects.bulk_create(tasks) return tpl @transaction.atomic def build_project_scope_template(payload: Dict[str, Any]) -> ProjectScopeTemplate: tpl = ProjectScopeTemplate.objects.create( name=payload["name"], description=payload.get("description") or "", is_active=payload.get("is_active", True), ) for cat_data in payload.get("categories", []): category = ProjectAreaTemplate.objects.create( scope_template=tpl, name=cat_data["name"], order=cat_data.get("order", 0), ) tasks: List[ProjectTaskTemplate] = [] for t in cat_data.get("tasks", []): tasks.append(ProjectTaskTemplate( area_template=category, description=t["description"], checklist_description=t.get("checklist_description") or "", order=t.get("order", 0), estimated_minutes=t.get("estimated_minutes"), )) if tasks: ProjectTaskTemplate.objects.bulk_create(tasks) return tpl