from datetime import date, datetime from typing import List, Literal, Optional from pydantic import Field, BaseModel from beanie import Indexed from firm.core.models import CrudDocument from firm.core.filter import Filter, FilterSchema 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 f"{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(FilterSchema): class Constants(Filter.Constants): model = Entity search_model_fields = ["label"]