"""Pydantic schemas for the Report Generator plugin.""" from __future__ import annotations from datetime import datetime from pydantic import BaseModel, Field class TemplateCreate(BaseModel): name: str = Field(..., min_length=1, max_length=255) description: str = Field("", max_length=2000) template_type: str = Field("jinja2", pattern="^(jinja2|sql)$") content: str = Field(..., min_length=1) output_format: str = Field("csv", pattern="^(csv|excel|json|pdf|print)$") class TemplateUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=255) description: str | None = Field(None, max_length=2000) template_type: str | None = Field(None, pattern="^(jinja2|sql)$") content: str | None = None output_format: str | None = Field(None, pattern="^(csv|excel|json|pdf|print)$") class TemplateResponse(BaseModel): id: str name: str description: str template_type: str content: str output_format: str created_by: str deleted_at: datetime | None = None created_at: datetime | None = None updated_at: datetime | None = None class ReportGenerateRequest(BaseModel): template_id: str = Field(..., min_length=1) data: dict = Field(default_factory=dict) output_format: str | None = Field(None, pattern="^(csv|excel|json|pdf|print)$") class PresetReportRequest(BaseModel): """Request to generate a preset report by name.""" preset: str = Field( ..., pattern="^(contact_list|calendar_week|calendar_month|company_list|audit_log)$", ) output_format: str = Field("pdf", pattern="^(csv|excel|json|pdf|print)$") parameters: dict = Field(default_factory=dict) class PresetReportInfo(BaseModel): """Metadata for a preset report template.""" key: str name: str description: str icon: str output_formats: list[str] class ReportResponse(BaseModel): id: str template_id: str status: str output_path: str | None = None error_message: str | None = None created_by: str created_at: datetime | None = None updated_at: datetime | None = None # ─── Documents Generator (Phase L1-L3) ────────────────────────────────────── class LetterheadCreate(BaseModel): name: str = Field(..., min_length=1, max_length=255) description: str = Field("", max_length=2000) config: dict = Field(default_factory=dict) is_default: bool = False class LetterheadUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=255) description: str | None = Field(None, max_length=2000) config: dict | None = None is_default: bool | None = None class LetterheadResponse(BaseModel): id: str name: str description: str config: dict is_default: bool created_by: str created_at: datetime | None = None updated_at: datetime | None = None class PrintTemplateCreate(BaseModel): name: str = Field(..., min_length=1, max_length=255) description: str = Field("", max_length=2000) letterhead_id: str | None = None entity_type: str = Field("contact", max_length=100) blocks: list[dict] = Field(default_factory=list) output_format: str = Field("pdf", pattern="^(pdf|print)$") class PrintTemplateUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=255) description: str | None = Field(None, max_length=2000) letterhead_id: str | None = None entity_type: str | None = Field(None, max_length=100) blocks: list[dict] | None = None output_format: str | None = Field(None, pattern="^(pdf|print)$") class PrintTemplateResponse(BaseModel): id: str name: str description: str letterhead_id: str | None = None entity_type: str blocks: list[dict] output_format: str created_by: str created_at: datetime | None = None updated_at: datetime | None = None class DocumentPreviewRequest(BaseModel): """Preview: render blocks to HTML (live preview in the editor).""" blocks: list[dict] letterhead_config: dict | None = None entity_type: str | None = None data: dict | None = None class DocumentPreviewResponse(BaseModel): html: str class DocumentRenderRequest(BaseModel): """Render a stored print template with entity data to PDF.""" entity_type: str entity_id: str output_format: str = Field("pdf", pattern="^(pdf|print)$") class DocumentAssetResponse(BaseModel): id: str letterhead_id: str | None = None filename: str mime_type: str size_bytes: int data_url: str | None = None created_at: datetime | None = None # ─── E-Invoice (EN16931/XRechnung, Phase L5) ──────────────────────────────── class EInvoiceAddress(BaseModel): """Postal address (BT-50..53 seller, BT-65..68 buyer).""" street: str | None = None postal_code: str | None = None city: str | None = None country: str | None = None class EInvoiceLineItem(BaseModel): """Invoice line (BG-25). ``line_net_amount`` wins over qty*price.""" name: str = "" quantity: float = 1.0 unit: str = "HUR" unit_net_price: float = 0.0 vat_rate: float = 0.0 line_net_amount: float | None = None class EInvoiceRenderRequest(BaseModel): """Inline invoice data — field-level semantics validated by ``einvoice.validate_einvoice_data`` (BT/BG business terms, 422).""" invoice_number: str = "" issue_date: str = "" type_code: str = "380" currency: str = "EUR" due_date: str | None = None delivery_date: str | None = None buyer_name: str = "" buyer_reference: str | None = None buyer_address: EInvoiceAddress | None = None seller_name: str = "" seller_vat_id: str | None = None seller_tax_id: str | None = None seller_address: EInvoiceAddress | None = None payment_means_code: str | None = None payment_terms_text: str | None = None note: str | None = None line_items: list[EInvoiceLineItem] = Field(default_factory=list) profile: str = Field("en16931", pattern="^(en16931|xrechnung)$") class EInvoiceRenderForRequest(BaseModel): """Render an e-invoice for an entity via the ``einvoice_data()`` contract hook (future sales module docking point).""" entity_type: str = Field(..., min_length=1, max_length=100) entity_id: str = Field(..., min_length=1) class EInvoiceValidationResponse(BaseModel): valid: bool missing: list[str] = Field(default_factory=list) # ─── AI block suggestion (Phase L4) ────────────────────────────────────────── class DocumentSuggestRequest(BaseModel): """Natural-language block composition request for the template editor.""" prompt: str = Field(..., min_length=1, max_length=2000) entity_type: str | None = Field(None, max_length=100) class DocumentSuggestResponse(BaseModel): blocks: list[dict] notes: str = ""