diff --git a/care/emr/resources/facility/spec.py b/care/emr/resources/facility/spec.py index 5cb0db567c..0e620d797c 100644 --- a/care/emr/resources/facility/spec.py +++ b/care/emr/resources/facility/spec.py @@ -1,6 +1,8 @@ +from typing import Literal + from django.conf import settings from django.db.models.functions import Lower, Trim -from pydantic import UUID4, BaseModel, field_validator, model_validator +from pydantic import UUID4, BaseModel, Field, field_validator, model_validator from pydantic_core.core_schema import ValidationInfo from pydantic_extra_types.coordinate import Latitude, Longitude @@ -29,6 +31,61 @@ class FacilityBareMinimumSpec(EMRResource): name: str +class PageMargin(BaseModel): + top: float = Field(ge=0) + bottom: float = Field(ge=0) + left: float = Field(ge=0) + right: float = Field(ge=0) + + +class PageConfig(BaseModel): + size: Literal["A4", "A5", "Letter", "Legal"] | None = None + orientation: Literal["portrait", "landscape"] | None = None + margin: PageMargin | None = None + + +class PrintSetupConfig(BaseModel): + auto_print: bool | None = None + + +class LogoConfig(BaseModel): + url: str + width: float | None = None + height: float | None = None + alignment: Literal["left", "center", "right"] + + +class HeaderImageConfig(BaseModel): + url: str + height: float | None = None + + +class FooterImageConfig(BaseModel): + url: str | None = None + height: float | None = None + + +class BrandingConfig(BaseModel): + logo: LogoConfig | None = None + header_image: HeaderImageConfig | None = None + footer_image: FooterImageConfig | None = None + + +class WatermarkConfig(BaseModel): + enabled: bool | None = None + text: str | None = None + opacity: float | None = Field(None, ge=0, le=1) + rotation: float | None = None + + +class PrintTemplate(BaseModel): + slug: str + page: PageConfig | None = None + print_setup: PrintSetupConfig | None = None + branding: BrandingConfig | None = None + watermark: WatermarkConfig | None = None + + class FacilityBaseSpec(FacilityBareMinimumSpec): description: str longitude: Longitude | None = None @@ -63,6 +120,7 @@ def validate_invoice_number_expression(cls, v): class FacilityCreateSpec(FacilityBaseSpec): geo_organization: UUID4 features: list[int] + print_templates: list[PrintTemplate] = [] @field_validator("name") @classmethod @@ -137,6 +195,8 @@ class FacilityRetrieveSpec(FacilityReadSpec, FacilityPermissionsMixin): extensions_schema_supply_delivery_order: dict = {} extensions_schema_account: dict = {} + print_templates: list[dict] = [] + @classmethod def perform_extra_serialization(cls, mapping, obj): super().perform_extra_serialization(mapping, obj) diff --git a/care/facility/migrations/0482_facility_print_templates.py b/care/facility/migrations/0482_facility_print_templates.py new file mode 100644 index 0000000000..ca06873ef4 --- /dev/null +++ b/care/facility/migrations/0482_facility_print_templates.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0 on 2026-02-26 07:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('facility', '0481_delete_asset_delete_assetbed_delete_bed_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='facility', + name='print_templates', + field=models.JSONField(default=dict), + ), + ] diff --git a/care/facility/models/facility.py b/care/facility/models/facility.py index 38ae713cc3..94955e4ac1 100644 --- a/care/facility/models/facility.py +++ b/care/facility/models/facility.py @@ -216,6 +216,8 @@ class Facility(BaseModel): max_length=1000, blank=True, null=True, default=None ) + print_templates = models.JSONField(default=dict) + class Meta: verbose_name_plural = "Facilities"