Adding contract creation
This commit is contained in:
@@ -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 .routes_draft import draft_router
|
||||||
from .print import print_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(draft_router, prefix="/draft", tags=["draft"], )
|
||||||
contract_router.include_router(print_router, prefix="/print", tags=["print"], )
|
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
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from typing import List, Literal
|
from typing import List, Literal
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@@ -5,21 +7,22 @@ from enum import Enum
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from ..core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry
|
from ..core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry
|
||||||
|
from ..entity.models import Entity
|
||||||
|
|
||||||
|
|
||||||
class ContractStatus(str, Enum):
|
class ContractStatus(str, Enum):
|
||||||
new = 'new'
|
published = 'published'
|
||||||
signed = 'signed'
|
signed = 'signed'
|
||||||
in_effect = 'in_effect'
|
|
||||||
executed = 'executed'
|
executed = 'executed'
|
||||||
|
|
||||||
|
|
||||||
class ContractDraftStatus(str, Enum):
|
class ContractDraftStatus(str, Enum):
|
||||||
draft = 'draft'
|
in_progress = 'in_progress'
|
||||||
|
ready = 'ready'
|
||||||
created = 'created'
|
created = 'created'
|
||||||
|
|
||||||
|
|
||||||
class Party(BaseModel):
|
class DraftParty(BaseModel):
|
||||||
entity_id: str = Field(
|
entity_id: str = Field(
|
||||||
foreignKey={
|
foreignKey={
|
||||||
"reference": {
|
"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):
|
class ProvisionGenuine(BaseModel):
|
||||||
type: Literal['genuine'] = 'genuine'
|
type: Literal['genuine'] = 'genuine'
|
||||||
title: str = RichtextSingleline(props={"parametrized": True})
|
title: str = RichtextSingleline(props={"parametrized": True})
|
||||||
@@ -64,10 +80,15 @@ class DraftProvision(BaseModel):
|
|||||||
provision: ContractProvisionTemplateReference | ProvisionGenuine = Field(..., discriminator='type')
|
provision: ContractProvisionTemplateReference | ProvisionGenuine = Field(..., discriminator='type')
|
||||||
|
|
||||||
|
|
||||||
|
class Provision(BaseModel):
|
||||||
|
title: str
|
||||||
|
body: str
|
||||||
|
|
||||||
|
|
||||||
class ContractDraft(CrudDocument):
|
class ContractDraft(CrudDocument):
|
||||||
name: str
|
name: str
|
||||||
title: str
|
title: str
|
||||||
parties: List[Party]
|
parties: List[DraftParty]
|
||||||
provisions: List[DraftProvision] = Field(
|
provisions: List[DraftProvision] = Field(
|
||||||
props={"items-per-row": "1", "numbered": True}
|
props={"items-per-row": "1", "numbered": True}
|
||||||
)
|
)
|
||||||
@@ -75,6 +96,32 @@ class ContractDraft(CrudDocument):
|
|||||||
default=[],
|
default=[],
|
||||||
format="dictionary",
|
format="dictionary",
|
||||||
)
|
)
|
||||||
status: ContractDraftStatus = Field(default=ContractDraftStatus.draft)
|
status: ContractDraftStatus = ContractDraftStatus.in_progress
|
||||||
location: str = ""
|
|
||||||
date: datetime.date = datetime.date(1970, 1, 1)
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from typing import List
|
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 ..entity.models import Entity
|
||||||
from ..core.schemas import Writer
|
from ..core.schemas import Writer
|
||||||
@@ -36,3 +36,17 @@ class ContractDraftCreate(Writer):
|
|||||||
|
|
||||||
class ContractDraftUpdate(ContractDraftCreate):
|
class ContractDraftUpdate(ContractDraftCreate):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ContractRead(Contract):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ContractCreate(Writer):
|
||||||
|
date: datetime.date
|
||||||
|
location: str
|
||||||
|
draft_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class ContractUpdate(BaseModel):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from .user import User, AccessToken
|
|||||||
from .entity.models import Entity
|
from .entity.models import Entity
|
||||||
from .template.models import ContractTemplate, ProvisionTemplate
|
from .template.models import ContractTemplate, ProvisionTemplate
|
||||||
from .order.models import Order
|
from .order.models import Order
|
||||||
from .contract.models import ContractDraft
|
from .contract.models import ContractDraft, Contract
|
||||||
|
|
||||||
DATABASE_URL = "mongodb://root:example@mongo:27017/"
|
DATABASE_URL = "mongodb://root:example@mongo:27017/"
|
||||||
|
|
||||||
@@ -17,5 +17,6 @@ async def init_db():
|
|||||||
)
|
)
|
||||||
|
|
||||||
await init_beanie(database=client.db_name,
|
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)
|
allow_index_dropping=True)
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { FormlyFieldConfig } from "@ngx-formly/core";
|
|||||||
import { FormGroup} from "@angular/forms";
|
import { FormGroup} from "@angular/forms";
|
||||||
import { CrudFormlyJsonschemaService } from "@common/crud/crud-formly-jsonschema.service";
|
import { CrudFormlyJsonschemaService } from "@common/crud/crud-formly-jsonschema.service";
|
||||||
import { CrudService } from "@common/crud/crud.service";
|
import { CrudService } from "@common/crud/crud.service";
|
||||||
|
import {ActivatedRoute, ParamMap} from "@angular/router";
|
||||||
|
|
||||||
|
import { formatDate } from "@angular/common";
|
||||||
|
|
||||||
|
|
||||||
export class BaseDraftsComponent {
|
export class BaseDraftsComponent {
|
||||||
@@ -86,7 +89,69 @@ export class DraftsNewComponent extends BaseDraftsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@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)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user