from __future__ import annotations from dataclasses import dataclass from typing import Iterable, List, Optional from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.utils import timezone from orgs.models import Organization from recycle_core.models import Document @dataclass class PickupRequestData: organization: Organization name: str email: str = "" phone: str = "" address: str = "" materials: str = "" preferred_at: Optional[timezone.datetime] = None files: Optional[Iterable] = None # iterable of UploadedFile created_by: Optional[object] = None # User, but avoid circular import typing @dataclass class PickupRequestResult: ok: bool lead_id: Optional[int] = None error: Optional[str] = None document_ids: List[int] = None class PickupRequestController: """Application layer controller for the fast-path pickup request. - Creates a Lead scoped to an Organization - Stores any uploaded photos/documents as Document records attached to the Lead """ def submit(self, data: PickupRequestData) -> PickupRequestResult: from public_frontend.models import Lead # import locally to avoid circular imports try: # Prepare message body for staff message = ( f"Pickup Request\n" f"Address: {data.address}\n" f"Preferred: {data.preferred_at or ''}\n" f"Materials: {data.materials or ''}" ) lead = Lead.objects.create( organization=data.organization, name=data.name, email=data.email or "", phone=data.phone or "", subject="Pickup Request", message=message, source="pickup_request", created_by=data.created_by if getattr(data, "created_by", None) else None, ) # Attach uploaded files as Documents linked to the Lead doc_ids: List[int] = [] if data.files: ct = ContentType.objects.get_for_model(Lead) for idx, f in enumerate(data.files): doc = Document.objects.create( organization=data.organization, file=f, kind="pickup_request", content_type=ct, object_id=lead.id, uploaded_by=None, ) doc_ids.append(doc.id) return PickupRequestResult(ok=True, lead_id=lead.id, document_ids=doc_ids) except Exception as e: return PickupRequestResult(ok=False, error=str(e), document_ids=[])