import uuid import datetime from typing import List, Literal from enum import Enum from pydantic import BaseModel, Field from ..core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry from ..entity.models import Entity class ContractStatus(str, Enum): published = 'published' signed = 'signed' executed = 'executed' class ContractDraftStatus(str, Enum): in_progress = 'in_progress' ready = 'ready' created = 'created' class DraftParty(BaseModel): entity_id: str = Field( foreignKey={ "reference": { "resource": "entity", "schema": "Entity", } } ) part: str representative_id: str = Field( foreignKey={ "reference": { "resource": "entity", "schema": "Entity", } }, default="" ) class Signature(BaseModel): uuid: str affixed: bool class Party(BaseModel): entity: Entity part: str representative: Entity = None signature_uuid: str = str(uuid.uuid4()) signature_affixed: bool = False class ProvisionGenuine(BaseModel): type: Literal['genuine'] = 'genuine' title: str = RichtextSingleline(props={"parametrized": True}) body: str = RichtextMultiline(props={"parametrized": True}) class ContractProvisionTemplateReference(BaseModel): type: Literal['template'] = 'template' provision_template_id: str = Field( foreignKey={ "reference": { "resource": "template/provision", "schema": "ProvisionTemplate", "displayedFields": ['title', 'body'] }, }, props={"parametrized": True} ) class DraftProvision(BaseModel): provision: ContractProvisionTemplateReference | ProvisionGenuine = Field(..., discriminator='type') class Provision(BaseModel): title: str body: str class ContractDraft(CrudDocument): name: str title: str parties: List[DraftParty] provisions: List[DraftProvision] = Field( props={"items-per-row": "1", "numbered": True} ) variables: List[DictionaryEntry] = Field( default=[], format="dictionary", ) status: ContractDraftStatus = ContractDraftStatus.in_progress class Settings(CrudDocument.Settings): bson_encoders = { datetime.date: lambda dt: dt if hasattr(dt, 'hour') else datetime.datetime(year=dt.year, month=dt.month, day=dt.day, hour=0, minute=0, second=0) } class Contract(CrudDocument): name: str title: str parties: List[Party] provisions: List[Provision] = Field( props={"items-per-row": "1", "numbered": True} ) status: ContractStatus = ContractStatus.published location: str date: datetime.date class Settings(CrudDocument.Settings): # fulltext_search = ['label'] bson_encoders = { datetime.date: lambda dt: dt if hasattr(dt, 'hour') else datetime.datetime(year=dt.year, month=dt.month, day=dt.day, hour=0, minute=0, second=0) }