Contract Drafts modules

This commit is contained in:
2023-02-11 18:07:50 +01:00
parent cb3af5bcf2
commit a288d32ec9
10 changed files with 187 additions and 44 deletions

View File

@@ -1,16 +1,9 @@
from datetime import datetime
from typing import List
from typing import List, Literal
from enum import Enum
from pydantic import BaseModel, Field
from beanie import Document
from ..entity.models import Entity
class ContractType(str, Enum):
employment = 'employment'
location = 'location'
from ..core.models import CrudDocument, RichtextSingleline, RichtextMultiline, DictionaryEntry
class ContractStatus(str, Enum):
@@ -20,21 +13,54 @@ class ContractStatus(str, Enum):
executed = 'executed'
class ContractDraftStatus(str, Enum):
draft = 'draft'
created = 'created'
class Party(BaseModel):
entity: Entity
entity_id: str = Field(
foreignKey={
"reference": {
"resource": "entity",
"schema": "Entity",
}
}
)
part: str
class Clause(BaseModel):
class ProvisionGenuine(BaseModel):
type: Literal['genuine'] = 'genuine'
title: str = RichtextSingleline(props={"parametrized": True})
body: str = RichtextMultiline(props={"parametrized": True})
class ContractProvisionTemplateReference(BaseModel):
type: Literal['template'] = 'template'
provision_template_id: str = Field(
foreignKey={
"reference": {
"resource": "template/provision",
"schema": "ProvisionTemplate",
"displayedFields": ['title', 'body']
},
},
props={"parametrized": True}
)
class DraftProvision(BaseModel):
provision: ContractProvisionTemplateReference | ProvisionGenuine = Field(..., discriminator='type')
class ContractDraft(CrudDocument):
name: str
body: str
class Contract(Document):
_id: str
type: ContractType
title: str
parties: List[Party]
clauses: List[Clause]
status: ContractStatus = Field(default=ContractStatus.new)
created_at: datetime = Field(default=datetime.utcnow(), nullable=False)
updated_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
provisions: List[DraftProvision]
variables: List[DictionaryEntry] = Field(
default=[],
format="dictionary",
)
status: ContractDraftStatus = Field(default=ContractDraftStatus.draft)

View File

@@ -1,5 +1,5 @@
from ..core.routes import get_crud_router
from .models import Contract
from .schemas import ContractCreate, ContractRead, ContractUpdate
from .models import ContractDraft
from .schemas import ContractDraftCreate, ContractDraftRead, ContractDraftUpdate
router = get_crud_router(Contract, ContractCreate, ContractRead, ContractUpdate)
router = get_crud_router(ContractDraft, ContractDraftCreate, ContractDraftRead, ContractDraftUpdate)

View File

@@ -1,36 +1,36 @@
import uuid
from datetime import datetime
from typing import List
from pydantic import BaseModel, validator
from pydantic import Field
from beanie import PydanticObjectId
from .models import ContractDraft, DraftProvision, Party
from .models import Contract, ContractType, Clause
from ..entity.models import Entity
from ..core.schemas import Writer
from ..core.models import DictionaryEntry
class ContractRead(Contract):
class ContractDraftRead(ContractDraft):
pass
class PartyCreate(BaseModel):
entity: PydanticObjectId
part: str
class ContractCreate(Writer):
type: ContractType
parties: List[PartyCreate]
clauses: List[Clause]
class ContractDraftCreate(Writer):
name: str
title: str
parties: List[Party]
provisions: List[DraftProvision]
variables: List[DictionaryEntry] = Field(
default=[],
format="dictionary",
)
async def validate_foreign_key(self):
return
for p in self.parties:
p.entity = await Entity.get(p.entity)
if p.entity is None:
raise ValueError
class ContractUpdate(BaseModel):
status: str
class ContractDraftUpdate(ContractDraftCreate):
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 Contract
from .contract.models import ContractDraft
DATABASE_URL = "mongodb://root:example@mongo:27017/"
@@ -17,5 +17,5 @@ async def init_db():
)
await init_beanie(database=client.db_name,
document_models=[User, AccessToken, Entity, ContractTemplate, ProvisionTemplate, Order, Contract, ],
document_models=[User, AccessToken, Entity, ContractTemplate, ProvisionTemplate, ContractDraft, ],
allow_index_dropping=True)

View File

@@ -25,7 +25,7 @@ app.include_router(user_router, prefix="/users", tags=["users"], )
app.include_router(entity_router, prefix="/entity", tags=["entity"], )
app.include_router(order_router, prefix="/order", tags=["order"], )
app.include_router(template_router, prefix="/template", tags=["template"], )
app.include_router(contract_router, prefix="/contract", tags=["contract"], )
app.include_router(contract_router, prefix="/contract-draft", tags=["contract-draft"], )
if __name__ == '__main__':
import uvicorn

View File

@@ -1,5 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {ContractsModule} from "./views/contracts/contracts.module";
const routes: Routes = [
{
@@ -29,6 +30,11 @@ const routes: Routes = [
loadChildren: () =>
import('./views/templates/templates.module').then((m) => m.TemplatesModule)
},
{
path: 'contract-drafts',
loadChildren: () =>
import('./views/contracts/contracts.module').then((m) => m.ContractsModule)
},
]
}
];

View File

@@ -31,6 +31,11 @@ export class SidenavComponent {
link: "/templates/contracts",
icon: IconNamesEnum.FileCodeFill
},
{
title: "Contracts Drafts",
link: "/contract-drafts",
icon: IconNamesEnum.PencilSquare
},
]
}

View File

@@ -0,0 +1,44 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DraftCardComponent, DraftListComponent, DraftNewComponent } from "./drafts.component";
const routes: Routes = [
{
path: '',
data: {
title: 'Entities',
},
children: [
{ path: '', redirectTo: 'list', pathMatch: 'full' },
{
path: 'list',
component: DraftListComponent,
data: {
title: 'List',
},
},
{
path: 'new',
component: DraftNewComponent,
data: {
title: 'New',
},
},
{
path: ':id',
component: DraftCardComponent,
data: {
title: 'Card',
},
},
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ContractsRoutingModule {}

View File

@@ -0,0 +1,23 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ContractsRoutingModule } from './contracts-routing.module';
import { CrudModule } from '@common/crud/crud.module'
import { DraftCardComponent, DraftListComponent, DraftNewComponent } from "./drafts.component";
@NgModule({
imports: [
CommonModule,
CrudModule,
ContractsRoutingModule
],
declarations: [
DraftListComponent,
DraftNewComponent,
DraftCardComponent,
]
})
export class ContractsModule {
}

View File

@@ -0,0 +1,39 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
export class BaseEntitiesComponent {
protected resource: string = "contract-draft";
protected schema: string = "ContractDraft";
}
@Component({
template: '<crud-list [resource]="this.resource" [schema]="this.schema" [columns]="this.columns"></crud-list>'
})
export class DraftListComponent extends BaseEntitiesComponent {
columns = ['label', 'address', 'entity_data.type']
}
@Component({
template: '<crud-card [resource]="this.resource" [schema]="this.schema"></crud-card>'
})
export class DraftNewComponent extends BaseEntitiesComponent {
}
@Component({
template: '<crud-card [resource]="this.resource" [resource_id]="this.resource_id" [schema]="this.schema"></crud-card>'
})
export class DraftCardComponent extends BaseEntitiesComponent implements OnInit {
resource_id: string | null = null;
constructor(private route: ActivatedRoute,) {
super();
}
ngOnInit(): void {
this.route.paramMap.subscribe((params: ParamMap) => {
this.resource_id = params.get('id')
})
}
}