import uuid from datetime import date, datetime from decimal import Decimal from typing import Optional from brewman.schemas import to_camel from pydantic import BaseModel, Field, validator class AccountLink(BaseModel): id_: uuid.UUID = Field(...) name: Optional[str] class Config: fields = {"id_": "id"} class CostCentreLink(BaseModel): id_: uuid.UUID = Field(...) name: Optional[str] class Config: fields = {"id_": "id"} class EmployeeLink(BaseModel): id_: uuid.UUID = Field(...) name: Optional[str] designation: Optional[str] cost_centre: CostCentreLink class Config: alias_generator = to_camel class ProductGroupIn(BaseModel): name: str = Field(..., min_length=1) class ProductGroup(ProductGroupIn): id_: uuid.UUID is_fixture: bool class Config: fields = {"id_": "id"} anystr_strip_whitespace = True alias_generator = to_camel class ProductGroupLink(BaseModel): id_: uuid.UUID = Field(...) class Config: fields = {"id_": "id"} class ProductLink(BaseModel): id_: uuid.UUID = Field(...) name: Optional[str] class Config: fields = {"id_": "id"} class ProductIn(BaseModel): name: str = Field(..., min_length=1) units: str fraction: Decimal = Field(ge=1, default=1) fraction_units: str product_yield: Decimal = Field(gt=0, le=1, default=1) product_group: ProductGroupLink = Field(...) price: Decimal = Field(ge=0, multiple_of=0.01, default=0) sale_price: Decimal = Field(ge=0, multiple_of=0.01, default=0) is_active: bool is_purchased: bool is_sold: bool class Config: fields = {"id_": "id"} anystr_strip_whitespace = True alias_generator = to_camel class Product(ProductIn): id_: uuid.UUID code: int account: AccountLink = Field(...) is_fixture: bool class Recipe(BaseModel): id_: uuid.UUID product_id: uuid.UUID quantity: Decimal cost_price: Decimal sale_price: Decimal notes: str valid_from: date valid_to: date effective_from: date effective_to: date class RecipeItem(BaseModel): id_: uuid.UUID recipe_id: uuid.UUID product_id: uuid.UUID quantity: int price: int class CostCentreIn(BaseModel): name: str = Field(..., min_length=1) class CostCentre(CostCentreIn): id_: uuid.UUID is_fixture: bool class Config: fields = {"id_": "id"} anystr_strip_whitespace = True alias_generator = to_camel class AccountBase(BaseModel): name: str = Field(..., min_length=1) is_starred: bool is_active: bool cost_centre: CostCentreLink class Config: fields = {"id_": "id"} anystr_strip_whitespace = True alias_generator = to_camel class AccountIn(AccountBase): type: int is_reconcilable: bool class Account(AccountIn): id_: uuid.UUID code: int is_fixture: bool class EmployeeIn(AccountBase): designation: str salary: int = Field(ge=0) points: Decimal = Field(ge=0, lt=1000, multiple_of=0.01) joining_date: date leaving_date: Optional[date] @validator("joining_date", pre=True) def parse_joining_date(cls, value): return datetime.strptime(value, "%d-%b-%Y").date() @validator("leaving_date", pre=True) def parse_leaving_date(cls, value): if value is None or value == "": return None else: return datetime.strptime(value, "%d-%b-%Y").date() @validator("leaving_date") def leaving_date_more_than_joining_date(cls, v, values, **kwargs): if values["is_active"]: return None if v < values["joining_date"]: raise ValueError("Leaving Date cannot be less than Joining Date") return v class Employee(EmployeeIn): id_: uuid.UUID code: int is_fixture: bool class DbSetting(BaseModel): id_: uuid.UUID name: str data: bytes class AccountType(BaseModel): id_: int name: str class Config: fields = {"id_": "id"}