From 05f13224fa74850670d833bea48e125c2f631de4 Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Tue, 10 Jun 2025 13:18:48 +0200 Subject: [PATCH] Add generateProcessPdf to service --- src/services/service.ts | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/services/service.ts b/src/services/service.ts index 3084774..ab24bd4 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -9,6 +9,7 @@ import Database from './database.service'; import { navigate } from '../router'; import { storeData, retrieveData, testData } from './storage.service'; import { BackUp } from '~/models/backup.model'; +import { PDFDocument, rgb, StandardFonts } from 'pdf-lib'; export const U32_MAX = 4294967295; @@ -1921,6 +1922,98 @@ export default class Services { } + public async generateProcessPdf(processId: string, processState: ProcessState): Promise { + const pdfDoc = await PDFDocument.create(); + const page = pdfDoc.addPage([595.28, 841.89]); + const font = await pdfDoc.embedFont(StandardFonts.Helvetica); + const fontBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold); + + const drawText = (text: string, x: number, y: number, opts: { size?: number, bold?: boolean } = {}) => { + const fontSize = opts.size || 12; + const usedFont = opts.bold ? fontBold : font; + page.drawText(text, { x, y, size: fontSize, font: usedFont, color: rgb(0, 0, 0) }); + }; + + let y = 800; + + // Header + drawText("Cabinet de Maître Jean Dupont", 50, y, { bold: true }); + drawText("Notaire à Paris", 50, y -= 15); + drawText("12 rue des Archives", 50, y -= 15); + drawText("75003 Paris", 50, y -= 15); + drawText("Téléphone : 01 23 45 67 89", 50, y -= 15); + drawText("Email : contact@notairedupont.fr", 50, y -= 15); + + // Client + y -= 30; + drawText("Client : Mme Sophie Martin", 50, y); + drawText("8 avenue de la Liberté", 50, y -= 15); + drawText("69003 Lyon", 50, y -= 15); + drawText("Email : sophie.martin@email.com", 50, y -= 15); + + // Title + y -= 40; + drawText("Certificat de Validation de Données", 50, y, { size: 14, bold: true }); + + // Certification paragraph + y -= 40; + const certText = `Je soussigné, Maître Jean Dupont, notaire à Paris, certifie par la présente que les données suivantes ont été vérifiées et horodatées à l’aide d’une empreinte cryptographique enregistrée sur la blockchain Bitcoin.`; + page.drawText(certText, { + x: 50, y, + size: 11, + font, + lineHeight: 14, + maxWidth: 500 + }); + + // Dossier number + y -= 60; + drawText("Numéro de dossier : N-2025-0456-PAR", 50, y); + + // Process ID + y -= 40; + drawText(`Identifiant du process: ${processId.split(':')[0]}`, 50, y); + + // Hash table + y -= 40; + + drawText("Nom", 50, y -= 20, { bold: true }); + drawText("Empreinte cryptographique (SHA-256)", 150, y, { bold: true }); + + for (const [label, hash] of Object.entries(processState.pcd_commitment)) { + drawText(label, 50, y -= 18); + drawText(hash, 150, y); + } + + // Add the state id as hash total + drawText('Ensemble', 50, y -= 18); + drawText(processState.state_id, 150, y); + + // Transaction + y -= 40; + drawText("Transaction enregistrée sur la blockchain Bitcoin :", 50, y); + drawText(processState.commited_in, 50, y -= 15); + + // Date & signature + y -= 50; + drawText("Fait à Paris, le 10 juin 2025.", 50, y); + drawText("Généré automatiquement par lecoffre.io", 50, y -= 30); + // drawText("Signature du notaire : ___________________________", 50, y -= 30); + + const pdfBytes = await pdfDoc.save(); + + // Download + const blob = new Blob([pdfBytes], { type: 'application/pdf' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `Certificat_Validation_${processId.slice(0,8)}-${processState.state_id.slice(0,8)}.pdf`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } + // public async getProfilesAttributes(): Promise>> { // const processes = await this.getProcesses(); // const profilesAttributes: Record> = {};