Compare commits
5 Commits
8f9c1833b0
...
872e27e7e4
| Author | SHA1 | Date | |
|---|---|---|---|
| 872e27e7e4 | |||
| 5bdb754f1c | |||
| 15b77ff09f | |||
| b0c4128e01 | |||
| e5a2539ec6 |
@@ -3,6 +3,7 @@ from typing import List, Literal, Optional
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from beanie import PydanticObjectId
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from firm.core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry
|
from firm.core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry
|
||||||
@@ -24,7 +25,7 @@ class ContractDraftStatus(str, Enum):
|
|||||||
|
|
||||||
|
|
||||||
class DraftParty(BaseModel):
|
class DraftParty(BaseModel):
|
||||||
entity_id: str = Field(
|
entity_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "entity",
|
"resource": "entity",
|
||||||
@@ -35,7 +36,7 @@ class DraftParty(BaseModel):
|
|||||||
title="Partie"
|
title="Partie"
|
||||||
)
|
)
|
||||||
part: str = Field(title="Rôle")
|
part: str = Field(title="Rôle")
|
||||||
representative_id: str = Field(
|
representative_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "entity",
|
"resource": "entity",
|
||||||
@@ -73,7 +74,7 @@ class ProvisionGenuine(BaseModel):
|
|||||||
|
|
||||||
class ContractProvisionTemplateReference(BaseModel):
|
class ContractProvisionTemplateReference(BaseModel):
|
||||||
type: Literal['template'] = ContractProvisionType.template
|
type: Literal['template'] = ContractProvisionType.template
|
||||||
provision_template_id: str = Field(
|
provision_template_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "template/provision",
|
"resource": "template/provision",
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ class Registry:
|
|||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.firm = firm
|
self.firm = firm
|
||||||
|
|
||||||
self.current_firm = CurrentFirmModel.get(self.db)
|
self.current_firm = CurrentFirmModel.get_current(self.db)
|
||||||
|
|
||||||
def set_user(self, user):
|
def set_user(self, user):
|
||||||
for firm in user.firms:
|
for firm in user.firms:
|
||||||
if firm.instance == self.instance and firm.firm == firm:
|
if firm.instance == self.instance and firm.firm == self.firm:
|
||||||
self.user = user
|
self.user = user
|
||||||
self.db.user = user
|
self.db.user = user
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ from pydantic import BaseModel, Field, computed_field
|
|||||||
class CrudDocument(BaseModel):
|
class CrudDocument(BaseModel):
|
||||||
id: Optional[PydanticObjectId] = Field(default=None)
|
id: Optional[PydanticObjectId] = Field(default=None)
|
||||||
created_at: datetime = Field(default=datetime.now(UTC), nullable=False, title="Créé le")
|
created_at: datetime = Field(default=datetime.now(UTC), nullable=False, title="Créé le")
|
||||||
created_by: str = Field(nullable=False, title="Créé par")
|
created_by: Optional[PydanticObjectId] = Field(default=None, title="Créé par")
|
||||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), nullable=False, title="Modifié le")
|
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), nullable=False, title="Modifié le")
|
||||||
updated_by: str = Field(nullable=False, title="Modifié par")
|
updated_by: Optional[PydanticObjectId] = Field(default=None, title="Modifié par")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _id(self):
|
def _id(self):
|
||||||
@@ -37,7 +37,7 @@ class CrudDocument(BaseModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def create(cls, db, create_schema):
|
async def create(cls, db, create_schema):
|
||||||
model_dict = create_schema.model_dump() | {"created_by": db.user, "updated_by":db.user}
|
model_dict = create_schema.model_dump() | {"created_by": db.user.id, "updated_by": db.user.id}
|
||||||
document = cls.model_validate(model_dict).model_dump(mode="json")
|
document = cls.model_validate(model_dict).model_dump(mode="json")
|
||||||
result = await cls._get_collection(db).insert_one(document)
|
result = await cls._get_collection(db).insert_one(document)
|
||||||
|
|
||||||
@@ -66,8 +66,9 @@ class CrudDocument(BaseModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def update(cls, db, model, update_schema):
|
async def update(cls, db, model, update_schema):
|
||||||
|
model_dict = update_schema.model_dump(mode="json") | {"updated_by": db.user.id}
|
||||||
update_query = {
|
update_query = {
|
||||||
"$set": {field: value for field, value in update_schema.model_dump(mode="json").items() if field!= "id" }
|
"$set": {field: value for field, value in model_dict.items() if field!= "id" }
|
||||||
}
|
}
|
||||||
|
|
||||||
await cls._get_collection(db).update_one({"_id": model.id}, update_query)
|
await cls._get_collection(db).update_one({"_id": model.id}, update_query)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from beanie import PydanticObjectId
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
|
|
||||||
from firm.core.models import CrudDocument
|
from firm.core.models import CrudDocument
|
||||||
@@ -8,12 +9,11 @@ from firm.entity.schemas import EntityIndividualCreate, EntityCorporationCreate
|
|||||||
|
|
||||||
|
|
||||||
class CurrentFirmModel(CrudDocument):
|
class CurrentFirmModel(CrudDocument):
|
||||||
instance: str
|
instance: str = Field()
|
||||||
firm: str
|
firm: str = Field()
|
||||||
name: str = Field(nullable=False)
|
entity_id: PydanticObjectId = Field()
|
||||||
|
primary_color: str = Field()
|
||||||
# primary_color: str = Field()
|
secondary_color: str = Field()
|
||||||
# secondary_color: str = Field()
|
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
if isinstance(other, dict):
|
if isinstance(other, dict):
|
||||||
@@ -21,10 +21,10 @@ class CurrentFirmModel(CrudDocument):
|
|||||||
return super().__eq__(other)
|
return super().__eq__(other)
|
||||||
|
|
||||||
def compute_label(self) -> str:
|
def compute_label(self) -> str:
|
||||||
return self.name
|
return f"{self.instance} / {self.firm}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get(cls, db):
|
async def get_current(cls, db):
|
||||||
document = await cls._get_collection(db).find_one({})
|
document = await cls._get_collection(db).find_one({})
|
||||||
if not document:
|
if not document:
|
||||||
return None
|
return None
|
||||||
@@ -39,7 +39,15 @@ class CurrentFirmSchemaRead(Reader):
|
|||||||
class CurrentFirmSchemaCreate(Writer):
|
class CurrentFirmSchemaCreate(Writer):
|
||||||
corporation: EntityCorporationCreate = Field(title="Informations sur la firme")
|
corporation: EntityCorporationCreate = Field(title="Informations sur la firme")
|
||||||
owner: EntityIndividualCreate = Field(title="Informations sur le dirigeant")
|
owner: EntityIndividualCreate = Field(title="Informations sur le dirigeant")
|
||||||
|
position: str = Field(title="Poste")
|
||||||
|
|
||||||
|
primary_color: str = Field()
|
||||||
|
secondary_color: str = Field()
|
||||||
|
|
||||||
|
|
||||||
class CurrentFirmSchemaUpdate(Writer):
|
class CurrentFirmSchemaUpdate(Writer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Partner(CrudDocument):
|
||||||
|
user_id: PydanticObjectId = Field()
|
||||||
|
entity_id: PydanticObjectId = Field()
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from firm.core.depends import get_logged_tenant_db_cursor, get_uninitialized_tenant_db_cursor
|
from firm.core.depends import get_authed_tenant_registry, get_uninitialized_registry
|
||||||
from firm.current_firm import CurrentFirmModel, CurrentFirmSchemaRead, CurrentFirmSchemaCreate, CurrentFirmSchemaUpdate
|
from firm.current_firm import CurrentFirmModel, CurrentFirmSchemaRead, CurrentFirmSchemaCreate, CurrentFirmSchemaUpdate, Partner
|
||||||
|
from firm.entity.models import Entity, Employee
|
||||||
|
|
||||||
current_firm_router = APIRouter()
|
current_firm_router = APIRouter()
|
||||||
|
|
||||||
@current_firm_router.get("/", response_model=CurrentFirmSchemaRead, response_description=f"Current Firm records retrieved")
|
@current_firm_router.get("/", response_model=CurrentFirmSchemaRead, response_description=f"Current Firm records retrieved")
|
||||||
async def read(db=Depends(get_logged_tenant_db_cursor)) -> CurrentFirmSchemaRead:
|
async def read(reg=Depends(get_authed_tenant_registry)) -> CurrentFirmSchemaRead:
|
||||||
return CurrentFirmSchemaRead.from_model(**CurrentFirmModel.get(db))
|
document = await CurrentFirmModel.get_current(reg.db)
|
||||||
|
return CurrentFirmSchemaRead.from_model(document)
|
||||||
|
|
||||||
@current_firm_router.post("/", response_description=f"Current Firm added to the database")
|
@current_firm_router.post("/", response_description=f"Current Firm added to the database")
|
||||||
async def create(schema: CurrentFirmSchemaCreate, db=Depends(get_uninitialized_tenant_db_cursor)) -> CurrentFirmSchemaRead:
|
async def create(schema: CurrentFirmSchemaCreate, reg=Depends(get_uninitialized_registry)) -> CurrentFirmSchemaRead:
|
||||||
await schema.validate_foreign_key(db)
|
owner_entity = await Entity.create(reg.db, schema.owner)
|
||||||
record = await CurrentFirmModel.create(db, schema)
|
Partner.create(reg.db, Partner(user_id=reg.user.id, entity_id=owner_entity.id))
|
||||||
return CurrentFirmSchemaRead.from_model(record)
|
|
||||||
|
corporation_schema = schema.corporation
|
||||||
|
corporation_schema.entity_data.employees.append(Employee(entity_id=owner_entity.id, position=schema.position))
|
||||||
|
corp = await Entity.create(reg.db, corporation_schema)
|
||||||
|
|
||||||
|
document = await CurrentFirmModel.create(reg.db, CurrentFirmModel(
|
||||||
|
instance=reg.instance,
|
||||||
|
firm=reg.firm,
|
||||||
|
entity_id=corp.id,
|
||||||
|
primary_color=schema.primary_color,
|
||||||
|
secondary_color=schema.secondary_color,
|
||||||
|
))
|
||||||
|
return await CurrentFirmSchemaRead.from_model(document)
|
||||||
|
|
||||||
@current_firm_router.put("/", response_description=f"Current Firm record updated")
|
@current_firm_router.put("/", response_description=f"Current Firm record updated")
|
||||||
async def update(schema: CurrentFirmSchemaUpdate, db=Depends(get_logged_tenant_db_cursor)) -> CurrentFirmSchemaRead:
|
async def update(schema: CurrentFirmSchemaUpdate, reg=Depends(get_authed_tenant_registry)) -> CurrentFirmSchemaRead:
|
||||||
record = await CurrentFirmModel.get(db)
|
document = await CurrentFirmModel.get_current(reg.db)
|
||||||
record = await CurrentFirmModel.update(db, record, schema)
|
document = await CurrentFirmModel.update(reg.db, document, schema)
|
||||||
return CurrentFirmSchemaRead.from_model(record)
|
return CurrentFirmSchemaRead.from_model(document)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from datetime import date, datetime
|
|||||||
from typing import List, Literal, Optional
|
from typing import List, Literal, Optional
|
||||||
|
|
||||||
from pydantic import Field, BaseModel
|
from pydantic import Field, BaseModel
|
||||||
from beanie import Indexed
|
from beanie import Indexed, PydanticObjectId
|
||||||
|
|
||||||
from firm.core.models import CrudDocument
|
from firm.core.models import CrudDocument
|
||||||
from firm.core.filter import Filter, FilterSchema
|
from firm.core.filter import Filter, FilterSchema
|
||||||
@@ -38,8 +38,9 @@ class Individual(EntityType):
|
|||||||
|
|
||||||
|
|
||||||
class Employee(BaseModel):
|
class Employee(BaseModel):
|
||||||
role: Indexed(str) = Field(title='Poste')
|
position: Indexed(str) = Field(title='Poste')
|
||||||
entity_id: str = Field(foreignKey={
|
entity_id: PydanticObjectId = Field(
|
||||||
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "entity",
|
"resource": "entity",
|
||||||
"schema": "Entity",
|
"schema": "Entity",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
from html import unescape
|
from html import unescape
|
||||||
|
|
||||||
|
from beanie import PydanticObjectId
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from firm.core.models import CrudDocument, RichtextMultiline, RichtextSingleline, DictionaryEntry
|
from firm.core.models import CrudDocument, RichtextMultiline, RichtextSingleline, DictionaryEntry
|
||||||
@@ -8,7 +9,7 @@ from firm.core.filter import Filter, FilterSchema
|
|||||||
|
|
||||||
|
|
||||||
class PartyTemplate(BaseModel):
|
class PartyTemplate(BaseModel):
|
||||||
entity_id: str = Field(
|
entity_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "entity",
|
"resource": "entity",
|
||||||
@@ -19,7 +20,7 @@ class PartyTemplate(BaseModel):
|
|||||||
title="Partie"
|
title="Partie"
|
||||||
)
|
)
|
||||||
part: str = Field(title="Rôle")
|
part: str = Field(title="Rôle")
|
||||||
representative_id: str = Field(
|
representative_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "entity",
|
"resource": "entity",
|
||||||
@@ -61,7 +62,7 @@ class ProvisionTemplate(CrudDocument):
|
|||||||
|
|
||||||
|
|
||||||
class ProvisionTemplateReference(BaseModel):
|
class ProvisionTemplateReference(BaseModel):
|
||||||
provision_template_id: str = Field(
|
provision_template_id: PydanticObjectId = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"reference": {
|
||||||
"resource": "template/provision",
|
"resource": "template/provision",
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import validator from "@rjsf/validator-ajv8";
|
import validator from "@rjsf/validator-ajv8";
|
||||||
import Form from "@rjsf/mui";
|
import Form from "@rjsf/mui";
|
||||||
import { RegistryFieldsType, RegistryWidgetsType } from "@rjsf/utils";
|
import { RegistryFieldsType, RegistryWidgetsType, UiSchema } from "@rjsf/utils";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
import { jsonschemaProvider } from "../providers/jsonschema-provider";
|
||||||
import { useForm } from "@refinedev/core";
|
import { useForm } from "@refinedev/core";
|
||||||
import CrudTextWidget from "./widgets/crud-text-widget";
|
import CrudTextWidget from "./widgets/crud-text-widget";
|
||||||
import UnionEnumField from "./fields/union-enum";
|
import UnionEnumField from "./fields/union-enum";
|
||||||
|
|
||||||
type Props = {
|
type CrudFormProps = {
|
||||||
schemaName: string,
|
schemaName: string,
|
||||||
|
uiSchema?: UiSchema,
|
||||||
resource: string,
|
resource: string,
|
||||||
id?: string,
|
id?: string,
|
||||||
//onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void
|
//onSubmit: (data: IChangeEvent, event: FormEvent<any>) => void
|
||||||
@@ -23,7 +24,8 @@ const customFields: RegistryFieldsType = {
|
|||||||
AnyOfField: UnionEnumField
|
AnyOfField: UnionEnumField
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CrudForm: React.FC<Props> = ({ schemaName, resource, id, onSuccess }) => {
|
export const CrudForm: React.FC<CrudFormProps> = (props) => {
|
||||||
|
const { schemaName, uiSchema, resource, id, onSuccess } = props;
|
||||||
const { onFinish, query, formLoading } = useForm({
|
const { onFinish, query, formLoading } = useForm({
|
||||||
resource: resource,
|
resource: resource,
|
||||||
action: id === undefined ? "create" : "edit",
|
action: id === undefined ? "create" : "edit",
|
||||||
@@ -55,6 +57,7 @@ export const CrudForm: React.FC<Props> = ({ schemaName, resource, id, onSuccess
|
|||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
schema={schema}
|
schema={schema}
|
||||||
|
uiSchema={uiSchema === undefined ? {} : uiSchema}
|
||||||
formData={record}
|
formData={record}
|
||||||
onChange={(e) => setFormData(e.formData)}
|
onChange={(e) => setFormData(e.formData)}
|
||||||
onSubmit={(e) => onFinish(e.formData)}
|
onSubmit={(e) => onFinish(e.formData)}
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import {FormContextType, getTemplate, RJSFSchema, StrictRJSFSchema, WidgetProps} from "@rjsf/utils";
|
import {FormContextType, getTemplate, RJSFSchema, StrictRJSFSchema, WidgetProps} from "@rjsf/utils";
|
||||||
|
|
||||||
import ForeignKeyWidget from "./foreign-key";
|
import ForeignKeyWidget from "./foreign-key";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
|
||||||
export default function CrudTextWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
export default function CrudTextWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
||||||
props: WidgetProps<T, S, F>
|
props: WidgetProps<T, S, F>
|
||||||
) {
|
) {
|
||||||
if (props.schema.hasOwnProperty("foreign_key")) {
|
const { schema } = props;
|
||||||
|
if (schema.hasOwnProperty("foreign_key")) {
|
||||||
return (<ForeignKeyWidget {...props} />);
|
return (<ForeignKeyWidget {...props} />);
|
||||||
|
} else if (schema.hasOwnProperty("const")) {
|
||||||
|
return <Typography >{schema.const as string}</Typography>;
|
||||||
} else {
|
} else {
|
||||||
const { options, registry } = props;
|
const { options, registry } = props;
|
||||||
const BaseInputTemplate = getTemplate<'BaseInputTemplate', T, S, F>('BaseInputTemplate', registry, options);
|
const BaseInputTemplate = getTemplate<'BaseInputTemplate', T, S, F>('BaseInputTemplate', registry, options);
|
||||||
|
|||||||
@@ -49,7 +49,14 @@ const FirmInitForm = (props: FirmInitFormPros) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Initialization of {`${currentFirm.instance} / ${currentFirm.firm}`}</h1>
|
<h1>Initialization of {`${currentFirm.instance} / ${currentFirm.firm}`}</h1>
|
||||||
<CrudForm schemaName={"CurrentFirmSchemaCreate"} resource={`/firm/${currentFirm.instance}/${currentFirm.firm}`} />
|
|
||||||
|
<CrudForm
|
||||||
|
schemaName={"CurrentFirmSchemaCreate"}
|
||||||
|
resource={`firm/${currentFirm.instance}/${currentFirm.firm}/`}
|
||||||
|
uiSchema={{
|
||||||
|
corporation: {entity_data: {employees: {"ui:style": {"display": "none"}}}},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user