import uuid from decimal import Decimal from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from . import to_camel from .customer import CustomerLink from .modifier import ModifierLink from .product_link import ProductLink from .table import TableLink from .tax import TaxLink class Inventory(BaseModel): id_: uuid.UUID | None = None product: ProductLink quantity: Decimal price: Decimal | None = None tax: TaxLink | None = None tax_rate: Decimal | None = None discount: Decimal = Field(ge=0, le=1) is_happy_hour: bool modifiers: list[ModifierLink] amount: Decimal | None = None model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) @field_validator("quantity") @classmethod def _quantity(cls, value: Decimal | None) -> Decimal: if value is None: return Decimal(0) return round(value, 2) @field_validator("price") @classmethod def _price(cls, value: Decimal | None) -> Decimal: if value is None: return Decimal(0) return round(value, 2) @field_validator("tax_rate") @classmethod def _tax_rate(cls, value: Decimal | None) -> Decimal: if value is None: return Decimal(0) return round(value, 5) @field_validator("discount") @classmethod def _discount(cls, value: Decimal | None) -> Decimal: if value is None: return Decimal(0) return round(value, 5) @model_validator(mode="after") def calculate_amount(self) -> "Inventory": self.amount = round( Decimal( (self.price or Decimal(0)) * self.quantity * (1 - self.discount) * (1 + (self.tax_rate or Decimal(0))) ), 2, ) return self class Kot(BaseModel): id_: uuid.UUID | None = None inventories: list[Inventory] model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class VoucherIn(BaseModel): pax: int table: TableLink customer: CustomerLink | None = None kots: list[Kot] model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class Voucher(VoucherIn): id_: uuid.UUID model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)