Merge branch 'master' of git.dorfsvald.net:ewandor/cht-lawfirm
This commit is contained in:
@@ -2,7 +2,7 @@ import datetime
|
||||
import os
|
||||
import base64
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
from fastapi.responses import HTMLResponse, FileResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
@@ -61,47 +61,47 @@ print_router = APIRouter()
|
||||
templates = Jinja2Templates(directory=str(BASE_PATH / "templates"))
|
||||
|
||||
|
||||
async def render_print(host, contract):
|
||||
async def render_print(root_url, contract):
|
||||
template = templates.get_template("print.html")
|
||||
return template.render({
|
||||
"contract": contract,
|
||||
"static_host": host
|
||||
"root_url": root_url
|
||||
})
|
||||
|
||||
|
||||
async def render_css(host, contract):
|
||||
async def render_css(root_url, contract):
|
||||
template = templates.get_template("styles.css")
|
||||
return template.render({
|
||||
"contract": contract,
|
||||
"static_host": host
|
||||
"root_url": root_url
|
||||
})
|
||||
|
||||
|
||||
@print_router.get("/preview/draft/{draft_id}", response_class=HTMLResponse)
|
||||
async def preview_draft(draft_id: str) -> str:
|
||||
async def preview_draft(draft_id: str, request: Request) -> str:
|
||||
draft = await build_model(await ContractDraft.get(draft_id))
|
||||
|
||||
return await render_print('localhost', draft)
|
||||
return await render_print(f'{request.url.scheme}://{request.url.hostname}', draft)
|
||||
|
||||
|
||||
@print_router.get("/preview/signature/{signature_id}", response_class=HTMLResponse)
|
||||
async def preview_contract_by_signature(signature_id: str) -> str:
|
||||
async def preview_contract_by_signature(signature_id: str, request: Request) -> str:
|
||||
contract = await Contract.find_by_signature_id(signature_id)
|
||||
for p in contract.parties:
|
||||
if p.signature_affixed:
|
||||
p.signature_png = retrieve_signature_png(f'media/signatures/{p.signature_uuid}.png')
|
||||
|
||||
return await render_print('localhost', contract)
|
||||
return await render_print(f'{request.url.scheme}://{request.url.hostname}', contract)
|
||||
|
||||
|
||||
@print_router.get("/preview/{contract_id}", response_class=HTMLResponse)
|
||||
async def preview_contract(contract_id: str) -> str:
|
||||
async def preview_contract(contract_id: str, request: Request) -> str:
|
||||
contract = await Contract.get(contract_id)
|
||||
for p in contract.parties:
|
||||
if p.signature_affixed:
|
||||
p.signature_png = retrieve_signature_png(f'media/signatures/{p.signature_uuid}.png')
|
||||
|
||||
return await render_print('localhost', contract)
|
||||
return await render_print(f'{request.url.scheme}://{request.url.hostname}', contract)
|
||||
|
||||
|
||||
@print_router.get("/pdf/{contract_id}", response_class=FileResponse)
|
||||
@@ -118,8 +118,8 @@ async def create_pdf(contract_id: str) -> str:
|
||||
# os.remove(signature_path)
|
||||
|
||||
font_config = FontConfiguration()
|
||||
html = HTML(string=await render_print('nginx', contract))
|
||||
css = CSS(string=await render_css('nginx', contract), font_config=font_config)
|
||||
html = HTML(string=await render_print('http://nginx', contract))
|
||||
css = CSS(string=await render_css('http://nginx', contract), font_config=font_config)
|
||||
|
||||
html.write_pdf(contract_path, stylesheets=[css], font_config=font_config)
|
||||
update_query = {"$set": {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="frontpage">
|
||||
<div id="front-page-header">
|
||||
<table><tr>
|
||||
<td><img id="top-logo" src="http://{{ static_host }}/assets/logotransparent.png" alt="Cooper, Hillman & Toshi logo"></td>
|
||||
<td><img id="top-logo" src="{{ root_url }}/assets/logotransparent.png" alt="Cooper, Hillman & Toshi logo"></td>
|
||||
<td id="office-info">Cooper, Hillman & Toshi LLP<br />6834 Innocence Boulevard<br />LOS SANTOS - SA<br /><a href="#">consulting@cht.law.com</a></td>
|
||||
</tr></table>
|
||||
<h1>{{ contract.title|upper }}</h1>
|
||||
@@ -27,7 +27,7 @@
|
||||
{{ party.entity.entity_data.title }} société de {{ party.entity.entity_data.activity }} enregistrée auprès du gouvernement de San Andreas et domiciliée au {{ party.entity.address }}{% if party.representative %}, représentée par {{ party.representative.entity_data.firstname }} {{ party.representative.entity_data.middlenames }} {{ party.representative.entity_data.lastname }}{% endif %}
|
||||
{% elif party.entity.entity_data.type == "individual" %}
|
||||
{{ party.entity.entity_data.firstname }} {{ party.entity.entity_data.middlenames }} {{ party.entity.entity_data.lastname }}
|
||||
{% if party.entity.entity_data.day_of_birth %} né le {{ party.entity.entity_data.day_of_birth.strftime('%d/%m/%Y') }} {% if true %} à {{ party.entity.entity_data.place_of_birth }}{% endif %},{% endif %}
|
||||
{% if party.entity.entity_data.day_of_birth %} né le {{ party.entity.entity_data.day_of_birth.strftime('%d/%m/%Y') }} {% if party.entity.entity_data.place_of_birth %} à {{ party.entity.entity_data.place_of_birth }}{% endif %},{% endif %}
|
||||
{% if party.entity.address %} résidant à {{ party.entity.address }}, {% endif %}
|
||||
{% elif party.entity.entity_data.type == "institution" %}
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
|
||||
@font-face {
|
||||
font-family: 'Century Schoolbook';
|
||||
src: url('http://{{ static_host }}/assets/century-schoolbook/CenturySchoolbookRegular.ttf');
|
||||
src: url('{{ root_url }}/assets/century-schoolbook/CenturySchoolbookRegular.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Century Schoolbook";
|
||||
src: url("http://{{ static_host }}/assets/century-schoolbook/CenturySchoolbookBold.ttf");
|
||||
src: url("{{ root_url }}/assets/century-schoolbook/CenturySchoolbookBold.ttf");
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Century Schoolbook";
|
||||
src: url("http://{{ static_host }}/assets/century-schoolbook/CenturySchoolbookItalic.ttf");
|
||||
src: url("{{ root_url }}/assets/century-schoolbook/CenturySchoolbookItalic.ttf");
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Century Schoolbook";
|
||||
src: url("http://{{ static_host }}/assets/century-schoolbook/CenturySchoolbookBoldItalic.ttf");
|
||||
src: url("{{ root_url }}/assets/century-schoolbook/CenturySchoolbookBoldItalic.ttf");
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
content: "© Cooper, Hillman & Toshi LLC - {{ contract.name }} - Page " counter(page) "/" counter(pages);
|
||||
font-size: 0.8em;
|
||||
}
|
||||
background: url('http://{{ static_host }}/assets/watermark.png') no-repeat;
|
||||
background: url('{{ root_url }}/assets/watermark.png') no-repeat;
|
||||
background-size:contain;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,17 @@ class ContractDraftRead(ContractDraft):
|
||||
|
||||
|
||||
class ContractDraftCreate(Writer):
|
||||
name: str
|
||||
title: str
|
||||
parties: List[DraftParty]
|
||||
provisions: List[DraftProvision]
|
||||
name: str = Field(title='Nom')
|
||||
title: str = Field(title='Titre')
|
||||
parties: List[DraftParty] = Field(title='Parties')
|
||||
provisions: List[DraftProvision] = Field(
|
||||
props={"items-per-row": "1", "numbered": True},
|
||||
title='Clauses'
|
||||
)
|
||||
variables: List[DictionaryEntry] = Field(
|
||||
default=[],
|
||||
format="dictionary",
|
||||
title='Variables'
|
||||
)
|
||||
|
||||
async def validate_foreign_key(self):
|
||||
|
||||
@@ -23,10 +23,9 @@ class Individual(EntityType):
|
||||
props={"items-per-row": "4", "numbered": True},
|
||||
title="Surnoms"
|
||||
)
|
||||
day_of_birth: date = Field(title='Date de naissance')
|
||||
day_of_birth: date = Field(default=None, title='Date de naissance')
|
||||
place_of_birth: str = Field(default="", title='Lieu de naissance')
|
||||
|
||||
|
||||
@property
|
||||
def label(self) -> str:
|
||||
if len(self.surnames) > 0:
|
||||
|
||||
@@ -97,7 +97,7 @@ export class DraftsNewComponent extends BaseDraftsComponent implements OnInit {
|
||||
(resourceReceived)="this.onResourceReceived($event)"
|
||||
>
|
||||
</base-card>
|
||||
<a class="btn btn-link" href="http://localhost/api/v1/contract/print/preview/draft/{{this.resource_id}}" target="_blank">Preview</a>
|
||||
<a class="btn btn-link" href="/api/v1/contract/print/preview/draft/{{this.resource_id}}" target="_blank">Preview</a>
|
||||
<ng-container *ngIf="this.isReadyForPublication;">
|
||||
<formly-form [fields]="newContractFormfields" [form]="newContractForm" [model]="newContractModel"></formly-form>
|
||||
<button class="btn btn-success" (click)="publish()">Publish</button>
|
||||
@@ -105,18 +105,20 @@ export class DraftsNewComponent extends BaseDraftsComponent implements OnInit {
|
||||
`
|
||||
})
|
||||
export class DraftsCardComponent extends BaseDraftsComponent implements OnInit {
|
||||
resource_id: string | null = null;templateModel: {} = {};
|
||||
resource_id: string | null = null;
|
||||
templateModel: {} = {};
|
||||
isReadyForPublication = false;
|
||||
newContractFormfields: FormlyFieldConfig[] = [];
|
||||
newContractForm: FormGroup = new FormGroup({});
|
||||
newContractModel: any = {
|
||||
date: formatDate(new Date(),'YYYY-MM-dd', 'EN_US', 'CET'),
|
||||
date: new Date(),
|
||||
location: "Los Santos, SA",
|
||||
draft_id: null
|
||||
}
|
||||
|
||||
fieldJson = {
|
||||
type: "object",
|
||||
required: ["date", "location", "draft_id"],
|
||||
properties: {
|
||||
date: {
|
||||
type: "string",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
import { Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { formatDate } from "@angular/common";
|
||||
import { NgbDateStruct, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
|
||||
|
||||
@@ -15,12 +14,12 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
<div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
|
||||
<formly-validation-message [field]="field"></formly-validation-message>
|
||||
</div>
|
||||
<input type="hidden"
|
||||
[formControl]="formControl"
|
||||
[formlyAttributes]="field"
|
||||
/>
|
||||
<div class="input-group" *ngIf="! this.field.props.readonly">
|
||||
<input type="hidden"
|
||||
[formControl]="formControl"
|
||||
[formlyAttributes]="field"
|
||||
[class.is-invalid]="showError"
|
||||
/>
|
||||
<button class="btn btn-outline-secondary" (click)="d.toggle()" type="button"><i-bs name="calendar-date-fill"></i-bs></button>
|
||||
<input
|
||||
class="form-control"
|
||||
placeholder="yyyy-mm-dd"
|
||||
@@ -29,33 +28,40 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
(ngModelChange)="changeDatetime($event)"
|
||||
ngbDatepicker
|
||||
#d="ngbDatepicker"
|
||||
[class.is-invalid]="showError"
|
||||
/>
|
||||
<button class="btn btn-outline-secondary" (click)="d.toggle()" type="button"><i-bs name="calendar-date-fill"></i-bs></button>
|
||||
</div>
|
||||
<div class="input-group" *ngIf="this.field.props.readonly">
|
||||
<input class="form-control" value="{{ this.datetime.toLocaleString() }}" disabled=""/>
|
||||
<input class="form-control" value="{{ this.datetime ? this.datetime.toLocaleString() : '' }}" disabled=""/>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class DateTypeComponent extends FieldType<FieldTypeConfig> implements OnInit
|
||||
{
|
||||
public date : NgbDateStruct;
|
||||
public datetime : Date = new Date();
|
||||
public date : NgbDateStruct | null = null;
|
||||
public datetime : Date | null = null;
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.date = this.getDateStruct(new Date());
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.formControl.value === undefined) {
|
||||
this.changeDatetime({});
|
||||
} else {
|
||||
this.datetime = new Date(this.formControl.value);
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
}
|
||||
|
||||
this.formControl.valueChanges.subscribe(value => {
|
||||
this.datetime = new Date(value)
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
if (value) {
|
||||
this.datetime = new Date(value);
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
} else {
|
||||
this.datetime = null;
|
||||
this.date = null;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -68,12 +74,21 @@ export class DateTypeComponent extends FieldType<FieldTypeConfig> implements OnI
|
||||
}
|
||||
|
||||
changeDatetime(event: any) {
|
||||
this.datetime.setFullYear(this.date.year)
|
||||
this.datetime.setMonth(this.date.month - 1)
|
||||
this.datetime.setDate(this.date.day)
|
||||
if (this.date) {
|
||||
if (!this.datetime) {
|
||||
this.datetime = new Date();
|
||||
}
|
||||
this.datetime.setFullYear(this.date.year)
|
||||
this.datetime.setMonth(this.date.month - 1)
|
||||
this.datetime.setDate(this.date.day)
|
||||
|
||||
this.formControl.setValue(
|
||||
formatDate(this.datetime, 'YYYY-MM-dd', 'EN_US', 'CET')
|
||||
)
|
||||
this.formControl.setValue(
|
||||
formatDate(this.datetime, 'YYYY-MM-dd', 'EN_US', 'CET')
|
||||
)
|
||||
} else {
|
||||
this.datetime = null;
|
||||
this.date = null;
|
||||
this.formControl.setValue('')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
import { Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { formatDate } from "@angular/common";
|
||||
import { NgbDateStruct, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
@@ -12,12 +11,12 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
class="form-label">{{ props.label }}
|
||||
<span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
|
||||
</label>
|
||||
<input type="hidden"
|
||||
[formControl]="formControl"
|
||||
[formlyAttributes]="field"
|
||||
/>
|
||||
<div class="input-group" *ngIf="! this.field.props.readonly">
|
||||
<input type="hidden"
|
||||
[formControl]="formControl"
|
||||
[formlyAttributes]="field"
|
||||
[class.is-invalid]="showError"
|
||||
/>
|
||||
<button class="btn btn-outline-secondary bi bi-calendar3" (click)="d.toggle()" type="button"></button>
|
||||
<input
|
||||
class="form-control"
|
||||
placeholder="yyyy-mm-dd"
|
||||
@@ -26,8 +25,8 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
(ngModelChange)="changeDatetime($event)"
|
||||
ngbDatepicker
|
||||
#d="ngbDatepicker"
|
||||
[class.is-invalid]="showError"
|
||||
/>
|
||||
<button class="btn btn-outline-secondary bi bi-calendar3" (click)="d.toggle()" type="button"></button>
|
||||
<ngb-timepicker
|
||||
(ngModelChange)="changeDatetime($event)"
|
||||
[(ngModel)]="time"
|
||||
@@ -35,15 +34,15 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
|
||||
</ngb-timepicker>
|
||||
</div>
|
||||
<div class="input-group" *ngIf="this.field.props.readonly">
|
||||
<input class="form-control" value="{{ this.datetime.toLocaleString() }}" disabled=""/>
|
||||
<input class="form-control" value="{{ this.datetime ? this.datetime.toLocaleString() : '' }}" disabled=""/>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class DatetimeTypeComponent extends FieldType<FieldTypeConfig> implements OnInit
|
||||
{
|
||||
public time : NgbTimeStruct;
|
||||
public date : NgbDateStruct;
|
||||
public datetime : Date = new Date()
|
||||
public time : NgbTimeStruct | null = null;
|
||||
public date : NgbDateStruct | null = null;
|
||||
public datetime : Date | null = null;
|
||||
|
||||
|
||||
constructor() {
|
||||
@@ -55,12 +54,21 @@ export class DatetimeTypeComponent extends FieldType<FieldTypeConfig> implements
|
||||
ngOnInit() {
|
||||
if (this.formControl.value === undefined) {
|
||||
this.changeDatetime({});
|
||||
} else {
|
||||
this.datetime = new Date(this.formControl.value);
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
}
|
||||
|
||||
this.formControl.valueChanges.subscribe(value => {
|
||||
this.datetime = new Date(value)
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
this.time = this.getTimeStruct(this.datetime);
|
||||
if (value) {
|
||||
this.datetime = new Date(value);
|
||||
this.date = this.getDateStruct(this.datetime);
|
||||
this.time = this.getTimeStruct(this.datetime);
|
||||
} else {
|
||||
this.datetime = null;
|
||||
this.date = null;
|
||||
this.time = null;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -81,15 +89,25 @@ export class DatetimeTypeComponent extends FieldType<FieldTypeConfig> implements
|
||||
}
|
||||
|
||||
changeDatetime(event: any) {
|
||||
this.datetime.setFullYear(this.date.year)
|
||||
this.datetime.setMonth(this.date.month - 1)
|
||||
this.datetime.setDate(this.date.day)
|
||||
this.datetime.setHours(this.time.hour)
|
||||
this.datetime.setMinutes(this.time.minute)
|
||||
this.datetime.setSeconds(this.time.second)
|
||||
if (this.date && this.time) {
|
||||
if (!this.datetime) {
|
||||
this.datetime = new Date();
|
||||
}
|
||||
this.datetime.setFullYear(this.date.year)
|
||||
this.datetime.setMonth(this.date.month - 1)
|
||||
this.datetime.setDate(this.date.day)
|
||||
this.datetime.setHours(this.time.hour)
|
||||
this.datetime.setMinutes(this.time.minute)
|
||||
this.datetime.setSeconds(this.time.second)
|
||||
|
||||
this.formControl.setValue(
|
||||
formatDate(this.datetime, 'YYYY-MM-ddTHH:mm:ss.SSS', 'EN_US', 'CET')
|
||||
)
|
||||
this.formControl.setValue(
|
||||
formatDate(this.datetime, 'YYYY-MM-ddTHH:mm:ss.SSS', 'EN_US', 'CET')
|
||||
)
|
||||
} else {
|
||||
this.datetime = null;
|
||||
this.date = null;
|
||||
this.time = null;
|
||||
this.formControl.setValue('')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user