Handling mongo indexes in firm

This commit is contained in:
2025-05-04 02:26:06 +02:00
parent b542fd40a6
commit ea5093f2c2
9 changed files with 67 additions and 56 deletions

View File

@@ -7,7 +7,8 @@ from beanie import PydanticObjectId
from pydantic import BaseModel, Field, ConfigDict
from pydantic.json_schema import SkipJsonSchema
from firm.core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry, ForeignKey
from firm.core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry, ForeignKey, \
CrudDocumentConfig
from firm.core.filter import Filter, FilterSchema
from firm.entity.models import Entity
@@ -98,15 +99,6 @@ class ContractDraft(CrudDocument):
status: ContractDraftStatus = Field(default=ContractDraftStatus.in_progress, title="Statut")
todo: List[str] = Field(default=[], title="Reste à faire")
class Settings(CrudDocument.Settings):
fulltext_search = ['name', 'title']
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)
}
async def check_is_ready(self, db):
if self.status == ContractDraftStatus.published:
return
@@ -150,6 +142,11 @@ class Contract(CrudDocument):
Contrat publié. Les contrats ne peuvent pas être modifiés.
Ils peuvent seulement être signés par les parties et imprimés par l'avocat
"""
model_config = ConfigDict(title='Contrat')
document_config = CrudDocumentConfig(
indexes=["parties.signature_uuid"],
)
name: str = Field(title="Nom")
title: str = Field(title="Titre")
parties: List[Party] = Field(title="Parties")
@@ -170,15 +167,6 @@ class Contract(CrudDocument):
contract_label = f"{contract_label} - {self.date.strftime('%m/%d/%Y')}"
return contract_label
class Settings(CrudDocument.Settings):
fulltext_search = ['name', 'title']
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)
}
@classmethod
async def find_by_signature_id(cls, db, signature_id: UUID):
request = {'parties': {"$elemMatch": {"signature_uuid": str(signature_id) }}}

View File

@@ -1,12 +1,18 @@
from datetime import datetime, UTC
from typing import Optional
from typing import Optional, TypedDict, ClassVar
from beanie import PydanticObjectId
from motor.motor_asyncio import AsyncIOMotorCollection
from pydantic import BaseModel, Field, computed_field
class CrudDocumentConfig(TypedDict, total=False):
fulltext_search: list[str]
indexes: list[str]
class CrudDocument(BaseModel):
document_config: ClassVar[CrudDocumentConfig] = CrudDocumentConfig()
id: Optional[PydanticObjectId] = Field(default=None)
created_at: datetime = Field(default=datetime.now(UTC), nullable=False, title="Créé le")
created_by: Optional[PydanticObjectId] = Field(default=None, title="Créé par")
@@ -17,16 +23,13 @@ class CrudDocument(BaseModel):
def _id(self):
return self.id
@computed_field
@computed_field(title="Label")
def label(self) -> str:
return self.compute_label()
def compute_label(self) -> str:
return ""
class Settings:
fulltext_search = []
@classmethod
def _collection_name(cls):
return cls.__name__
@@ -35,6 +38,10 @@ class CrudDocument(BaseModel):
def _get_collection(cls, db) -> AsyncIOMotorCollection:
return db.get_collection(cls._collection_name())
@classmethod
def create_index(cls, db, index):
cls._get_collection(db).create_index(index)
@classmethod
async def create(cls, db, create_schema):
model_dict = create_schema.model_dump() | {"created_by": db.partner.id, "updated_by": db.partner.id}
@@ -84,7 +91,6 @@ class CrudDocument(BaseModel):
await cls._get_collection(db).delete_one({"_id": model.id})
def text_area(*args, **kwargs):
kwargs['widget'] = {
"formlyConfig": {

View File

@@ -3,7 +3,7 @@ from typing import Any
from beanie import PydanticObjectId
from pydantic import Field
from firm.core.models import CrudDocument
from firm.core.models import CrudDocument, CrudDocumentConfig
from firm.core.schemas import Writer, Reader
from firm.entity.schemas import EntityIndividualCreate, EntityCorporationCreate, EntityRead
@@ -59,6 +59,10 @@ class CurrentFirmSchemaUpdate(Writer):
pass
class Partner(CrudDocument):
document_config = CrudDocumentConfig(
indexes=["user_id", "entity_id"],
)
user_id: PydanticObjectId = Field()
entity_id: PydanticObjectId = Field()

View File

@@ -11,9 +11,6 @@ client = motor.motor_asyncio.AsyncIOMotorClient(
DATABASE_URL, uuidRepresentation="standard"
)
async def init_db():
pass
async def stop_db():
client.close()

View File

@@ -1,8 +1,8 @@
from datetime import date, datetime
from datetime import date
from typing import List, Literal, Optional
from pydantic import Field, BaseModel, ConfigDict
from beanie import Indexed, PydanticObjectId
from beanie import PydanticObjectId
from firm.core.models import CrudDocument, ForeignKey
from firm.core.filter import Filter, FilterSchema
@@ -18,10 +18,10 @@ class Individual(EntityType):
model_config = ConfigDict(title='Particulier')
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(
firstname: str = Field(title='Prénom')
middlename: str = Field(default="", title='Autres prénoms')
lastname: str = Field(title='Nom de famille')
surnames: List[str] = Field(
default=[],
props={"items_per_row": "4", "numbered": True},
title="Surnoms"
@@ -32,14 +32,14 @@ class Individual(EntityType):
@property
def label(self) -> str:
# if len(self.surnames) > 0:
# return '{} "{}" {}'.format(self.firstname, self.surnames[0], self.lastname)
# return f"{self.firstname} \"{self.surnames[0]}\" {self.lastname}"
return f"{self.firstname} {self.lastname}"
class Employee(BaseModel):
model_config = ConfigDict(title='Fiche Employé')
position: Indexed(str) = Field(title='Poste')
position: str = Field(title='Poste')
entity_id: PydanticObjectId = ForeignKey("entities", "Entity", title='Employé')
@@ -47,8 +47,8 @@ class Corporation(EntityType):
model_config = ConfigDict(title='Entreprise')
type: Literal['corporation'] = 'corporation'
title: Indexed(str) = Field(title='Dénomination sociale')
activity: Indexed(str) = Field(title='Activité')
title: str = Field(title='Dénomination sociale')
activity: str = Field(title='Activité')
employees: List[Employee] = Field(default=[], title='Employés')
@@ -72,15 +72,6 @@ class Entity(CrudDocument):
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 EntityFilters(FilterSchema):
class Constants(Filter.Constants):

View File

@@ -0,0 +1,31 @@
import logging
from firm.contract.models import Contract, ContractDraft
from firm.core.depends import Registry
from firm.current_firm import CurrentFirm, Partner
from firm.db import client
from firm.entity.models import Entity
from firm.template.models import ContractTemplate, ProvisionTemplate
from hub.firm import Firm
collections = [CurrentFirm, Entity, Partner, Contract, ContractDraft, ContractTemplate, ProvisionTemplate]
logger = logging.getLogger('uvicorn.error')
async def create_documents_indexes(db):
for collection in collections:
if "indexes" in collection.document_config:
for field in collection.document_config["indexes"]:
collection.create_index(db, field)
async def init_all_db():
logger.info("[FRM] Creating index for firms")
for firm in await Firm.find({}).to_list():
reg = Registry(client, firm.instance, firm.firm)
await reg.current_firm
await create_documents_indexes(reg.db)
async def init_db():
await init_all_db()

View File

@@ -36,9 +36,6 @@ class ProvisionTemplate(CrudDocument):
def compute_label(self) -> str:
return f"{self.name} - \"{unescape(remove_html_tags(self.title))}\""
class Settings(CrudDocument.Settings):
fulltext_search = ['name', 'title', 'body']
class ProvisionTemplateReference(BaseModel):
model_config = ConfigDict(title="Clause")
@@ -67,9 +64,6 @@ class ContractTemplate(CrudDocument):
def compute_label(self) -> str:
return f"{self.name} - \"{unescape(remove_html_tags(self.title))}\""
class Settings(CrudDocument.Settings):
fulltext_search = ['name', 'title']
class ContractTemplateFilters(FilterSchema):
class Constants(Filter.Constants):

View File

@@ -5,7 +5,7 @@ from hub import hub_router
from hub.db import init_db as hub_init_db
from firm import firm_router
from firm.db import init_db as firm_init_db
from firm.init_db import init_db as firm_init_db
if __name__ == '__main__':