Contract Signing and contract printing

This commit is contained in:
2023-03-08 21:59:10 +01:00
parent eaa79c3541
commit 5605ee9497
10 changed files with 230 additions and 46 deletions

View File

@@ -1,11 +1,11 @@
import datetime
import os
import base64
from fastapi import APIRouter
from fastapi import APIRouter, HTTPException
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.templating import Jinja2Templates
from beanie.operators import ElemMatch
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
@@ -13,7 +13,7 @@ from pathlib import Path
from app.entity.models import Entity
from app.template.models import ProvisionTemplate
from ..models import ContractDraft, Contract, replace_variables_in_value
from ..models import ContractDraft, Contract, ContractStatus, replace_variables_in_value
async def build_model(model):
@@ -77,32 +77,55 @@ async def render_css(host, contract):
})
@print_router.get("/preview/draft/{draftId}", response_class=HTMLResponse)
async def preview_draft(draftId: str) -> str:
draft = await build_model(await ContractDraft.get(draftId))
@print_router.get("/preview/draft/{draft_id}", response_class=HTMLResponse)
async def preview_draft(draft_id: str) -> str:
draft = await build_model(await ContractDraft.get(draft_id))
return await render_print('localhost', draft)
@print_router.get("/preview/{signature_id}", response_class=HTMLResponse)
async def preview_contract(signature_id: str) -> str:
crit = ElemMatch(Contract.parties, {"signature_uuid": signature_id})
contract = await Contract.find_one(crit)
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)
@print_router.get("/pdf", response_class=FileResponse)
async def create_pdf() -> str:
draft = await build_model(await ContractDraft.get("63e92534aafed8b509f229c4"))
@print_router.get("/pdf/{contract_id}", response_class=FileResponse)
async def create_pdf(contract_id: str) -> str:
contract = await Contract.get(contract_id)
contract_path = "media/contracts/{}.pdf".format(contract_id)
if not os.path.isfile(contract_path):
if contract.status != ContractStatus.signed:
raise HTTPException(status_code=400, detail="Contract is not in a printable state")
font_config = FontConfiguration()
html = HTML(string=await render_print('nginx', draft))
css = CSS(string=await render_css('nginx', draft), font_config=font_config)
for p in contract.parties:
signature_path = f'media/signatures/{p.signature_uuid}.png'
p.signature_png = retrieve_signature_png(signature_path)
# os.remove(signature_path)
html.write_pdf('out.pdf', stylesheets=[css], font_config=font_config)
font_config = FontConfiguration()
html = HTML(string=await render_print('nginx', contract))
css = CSS(string=await render_css('nginx', contract), font_config=font_config)
html.write_pdf(contract_path, stylesheets=[css], font_config=font_config)
update_query = {"$set": {
'status': 'printed'
}}
await contract.update(update_query)
return FileResponse(
"out.pdf",
contract_path,
media_type="application/pdf",
filename=draft.name)
filename=contract.name)
def retrieve_signature_png(filepath):
with open(filepath, "rb") as f:
b_content = f.read()
base64_utf8_str = base64.b64encode(b_content).decode('utf-8')
ext = filepath.split('.')[-1]
return f'data:image/{ext};base64,{base64_utf8_str}'

View File

@@ -60,7 +60,14 @@
<p class="mention">(Signatures précédée de la mention « Lu et approuvé »)</p>
<table class="signatures">
<tr>
{% for party in contract.parties %}<td>{{ party.part|safe }}:</td>{% endfor %}
{% for party in contract.parties %}
<td>
{{ party.part|safe }}:<br/>
{% if party.signature_png %}
<img src="{{ party.signature_png }}" />
{% endif %}
</td>
{% endfor %}
</tr>
</table>
</div>