from __future__ import annotations from dataclasses import dataclass from pathlib import Path from fastapi import HTTPException, status from sqlalchemy import select from sqlalchemy.orm import Session from app.models.contact import Contact from app.models.customer import Customer from app.models.device import Device from app.models.equipment import Equipment from app.models.report_template import ( ChecklistTemplate, MeasurementImport, MeasurementImportValue, ReportSection, TextBlock, ) from app.models.location import Location from app.models.validation import Validation from app.modules.orion.template_service import ReportTemplateService @dataclass(frozen=True) class ReportContext: validation: Validation customer: Customer location: Location | None contact: Contact | None device: Device | None equipment: list[Equipment] generated_dir: Path report_sections: list[ReportSection] text_blocks: dict[str, TextBlock] checklist_templates: list[ChecklistTemplate] confirmed_measurements: list[MeasurementImportValue] class OrionContextBuilder: def __init__(self, session: Session, generated_dir: Path) -> None: self.session = session self.generated_dir = generated_dir def build(self, validation_id: str) -> ReportContext: validation = self.session.get(Validation, validation_id) if validation is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Validation not found") customer = self.session.get(Customer, validation.customer_id) if customer is None: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Validation has no customer") location = self.session.get(Location, validation.location_id) if validation.location_id else None contact = self.session.get(Contact, validation.contact_id) if validation.contact_id else None device = self.session.get(Device, validation.device_id) if validation.device_id else None equipment = [] if validation.equipment_ids: equipment = list( self.session.scalars( select(Equipment).where(Equipment.id.in_(validation.equipment_ids)) ) ) template_bundle = ReportTemplateService(self.session).ensure_default_template() confirmed_measurements = list( self.session.scalars( select(MeasurementImportValue) .join_from(MeasurementImportValue, MeasurementImport) .where( MeasurementImport.validation_id == validation.id, MeasurementImportValue.confirmed.is_(True), ) ) ) self.generated_dir.mkdir(parents=True, exist_ok=True) return ReportContext( validation=validation, customer=customer, location=location, contact=contact, device=device, equipment=equipment, generated_dir=self.generated_dir, report_sections=template_bundle.sections, text_blocks=template_bundle.text_blocks, checklist_templates=template_bundle.checklists, confirmed_measurements=confirmed_measurements, )