Adding contract creation

This commit is contained in:
2023-03-06 17:05:49 +01:00
parent d8c8ebdc48
commit 576b5970a5
5 changed files with 210 additions and 16 deletions

View File

@@ -1,9 +1,76 @@
from fastapi import APIRouter
from fastapi import Depends, HTTPException
from ..core.routes import get_crud_router
from .routes_draft import draft_router
from .print import print_router
contract_router = APIRouter()
from .models import Contract, ContractDraft
from .schemas import ContractCreate, ContractRead, ContractUpdate
from ..entity.models import Entity
from ..template.models import ProvisionTemplate
contract_router = get_crud_router(Contract, ContractCreate, ContractRead, ContractUpdate)
del(contract_router.routes[0])
del(contract_router.routes[2])
del(contract_router.routes[2])
contract_router.include_router(draft_router, prefix="/draft", tags=["draft"], )
contract_router.include_router(print_router, prefix="/print", tags=["print"], )
def can_create_contract():
class User:
entity_id = '63d127bcf355de8e65a193e1'
return User()
@contract_router.post("/", response_description="Contract Successfully created")
async def create(item: ContractCreate, user=Depends(can_create_contract)) -> dict:
await item.validate_foreign_key()
draft = await ContractDraft.get(item.draft_id)
for v in draft.variables:
if not v.key or not v.value:
raise HTTPException(status_code=400, detail="Variable {} is invalid".format(v))
contract_dict = item.dict()
del(contract_dict['draft_id'])
contract_dict['lawyer'] = await Entity.get(user.entity_id)
contract_dict['name'] = draft.name
contract_dict['title'] = draft.title
parties = []
for p in draft.parties:
parties.append({
'entity': await Entity.get(p.entity_id),
'part': p.part,
'representative': await Entity.get(p.representative_id) if p.representative_id else None
})
contract_dict['parties'] = parties
provisions = []
for p in draft.provisions:
p = p.provision
provision = await ProvisionTemplate.get(p.provision_template_id) if p.type == 'template' \
else p
provisions.append({
'title': replace_variables_in_value(draft.variables, provision.title),
'body': replace_variables_in_value(draft.variables, provision.body)
})
contract_dict['provisions'] = provisions
o = await Contract(**contract_dict).create()
return {"message": "Contract Successfully created", "id": o.id}
def replace_variables_in_value(variables, value: str):
for v in variables:
value = value.replace('%{}%'.format(v.key), v.value)
return value

View File

@@ -1,3 +1,5 @@
import uuid
import datetime
from typing import List, Literal
from enum import Enum
@@ -5,21 +7,22 @@ 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):
new = 'new'
published = 'published'
signed = 'signed'
in_effect = 'in_effect'
executed = 'executed'
class ContractDraftStatus(str, Enum):
draft = 'draft'
in_progress = 'in_progress'
ready = 'ready'
created = 'created'
class Party(BaseModel):
class DraftParty(BaseModel):
entity_id: str = Field(
foreignKey={
"reference": {
@@ -40,6 +43,19 @@ class Party(BaseModel):
)
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})
@@ -64,10 +80,15 @@ 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[Party]
parties: List[DraftParty]
provisions: List[DraftProvision] = Field(
props={"items-per-row": "1", "numbered": True}
)
@@ -75,6 +96,32 @@ class ContractDraft(CrudDocument):
default=[],
format="dictionary",
)
status: ContractDraftStatus = Field(default=ContractDraftStatus.draft)
location: str = ""
date: datetime.date = datetime.date(1970, 1, 1)
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)
}

View File

@@ -1,9 +1,9 @@
import datetime
from typing import List
from pydantic import Field
from pydantic import BaseModel, Field
from .models import ContractDraft, DraftProvision, Party
from .models import ContractDraft, DraftProvision, Party, Contract
from ..entity.models import Entity
from ..core.schemas import Writer
@@ -36,3 +36,17 @@ class ContractDraftCreate(Writer):
class ContractDraftUpdate(ContractDraftCreate):
pass
class ContractRead(Contract):
pass
class ContractCreate(Writer):
date: datetime.date
location: str
draft_id: str
class ContractUpdate(BaseModel):
pass

View File

@@ -6,7 +6,7 @@ from .user import User, AccessToken
from .entity.models import Entity
from .template.models import ContractTemplate, ProvisionTemplate
from .order.models import Order
from .contract.models import ContractDraft
from .contract.models import ContractDraft, Contract
DATABASE_URL = "mongodb://root:example@mongo:27017/"
@@ -17,5 +17,6 @@ async def init_db():
)
await init_beanie(database=client.db_name,
document_models=[User, AccessToken, Entity, ContractTemplate, ProvisionTemplate, ContractDraft, ],
document_models=[User, AccessToken, Entity, ContractTemplate, ProvisionTemplate, ContractDraft,
Contract, ],
allow_index_dropping=True)

View File

@@ -3,6 +3,9 @@ import { FormlyFieldConfig } from "@ngx-formly/core";
import { FormGroup} from "@angular/forms";
import { CrudFormlyJsonschemaService } from "@common/crud/crud-formly-jsonschema.service";
import { CrudService } from "@common/crud/crud.service";
import {ActivatedRoute, ParamMap} from "@angular/router";
import { formatDate } from "@angular/common";
export class BaseDraftsComponent {
@@ -86,7 +89,69 @@ export class DraftsNewComponent extends BaseDraftsComponent implements OnInit {
}
@Component({
templateUrl: '../base-view/templates/card.template.html'
template: `
<base-card
[resource]="this.resource"
[schema]="this.schema">
</base-card>
<a class="btn btn-link" href="http://localhost/api/v1/contract/print/preview/{{this.resource_id}}">Preview</a>
<formly-form [fields]="newContractFormfields" [form]="newContractForm" [model]="newContractModel"></formly-form>
<button class="btn btn-success" (click)="publish()">Publish</button>
`
})
export class DraftsCardComponent extends BaseDraftsComponent {
export class DraftsCardComponent extends BaseDraftsComponent implements OnInit {
resource_id: string | null = null;templateModel: {} = {};
newContractFormfields: FormlyFieldConfig[] = [];
newContractForm: FormGroup = new FormGroup({});
newContractModel: any = {
date: formatDate(new Date(),'YYYY-MM-dd', 'EN_US', 'CET'),
location: "Los Santos, SA",
draft_id: null
}
fieldJson = {
type: "object",
properties: {
date: {
type: "string",
format: "date",
title: "Date"
},
location: {
type: "string",
title: "Location"
},
draft_id: {
type: "string",
title: "Contract Draft",
hidden: true
},
},
}
constructor(
private route: ActivatedRoute,
private formlyJsonschema: CrudFormlyJsonschemaService,
private crudService: CrudService
) {
super();
}
ngOnInit(): void {
if (this.resource_id === null) {
this.route.paramMap.subscribe((params: ParamMap) => {
this.resource_id = params.get('id')
})
}
this.newContractModel.draft_id = this.resource_id;
// @ts-ignore
this.newContractFormfields = [this.formlyJsonschema.toFieldConfig(this.fieldJson)];
}
publish() {
this.crudService.create('contract', this.newContractModel).subscribe((templateModel) => {
console.log(templateModel)
});
}
}