from datetime import date, datetime from typing import List, Literal, Optional from pydantic import Field, BaseModel from beanie import Indexed from ..core.models import CrudDocument from ..core.filter import Filter class EntityType(BaseModel): @property def label(self) -> str: return self.title class Individual(EntityType): type: Literal['individual'] = 'individual' firstname: Indexed(str) = Field(title='Prénom') middlename: Indexed(str) = Field(default="", title='Autres prénoms') lastname: Indexed(str) = Field(title='Nom de famille') surnames: List[Indexed(str)] = Field( default=[], props={"items-per-row": "4", "numbered": True}, title="Surnoms" ) day_of_birth: Optional[date] = Field(default=None, title='Date de naissance') place_of_birth: Optional[str] = Field(default="", title='Lieu de naissance') @property def label(self) -> str: # if len(self.surnames) > 0: # return '{} "{}" {}'.format(self.firstname, self.surnames[0], self.lastname) return '{} {}'.format(self.firstname, self.lastname) class Config: title = 'Particulier' class Employee(BaseModel): role: Indexed(str) = Field(title='Poste') entity_id: str = Field(foreignKey={ "reference": { "resource": "entity", "schema": "Entity", "condition": "entity_data.type=individual" } }, title='Employé' ) class Config: title = 'Fiche Employé' class Corporation(EntityType): type: Literal['corporation'] = 'corporation' title: Indexed(str) = Field(title='Dénomination sociale') activity: Indexed(str) = Field(title='Activité') employees: List[Employee] = Field(default=[], title='Employés') class Config: title = 'Entreprise' class Institution(Corporation): type: Literal['institution'] = 'institution' class Config: title = 'Institution' class Entity(CrudDocument): """ Fiche d'un client """ entity_data: Individual | Corporation | Institution = Field(..., discriminator='type') address: str = Field(default="", title='Adresse') def compute_label(self) -> str: if not self.entity_data: return "" return self.entity_data.label class Settings(CrudDocument.Settings): fulltext_search = ['label'] bson_encoders = { date: lambda dt: dt if hasattr(dt, 'hour') else datetime(year=dt.year, month=dt.month, day=dt.day, hour=0, minute=0, second=0) } class Config: title = 'Client' class EntityFilters(Filter): name__like: Optional[str] = None order_by: Optional[list[str]] = None class Constants(Filter.Constants): model = Entity search_model_fields = ["name"]