#2-protocol #10
8 changed files with 950 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -130,3 +130,4 @@ dist
|
|||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
export
|
804
package-lock.json
generated
804
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -32,6 +32,7 @@
|
|||
"mysql": "^2.18.1",
|
||||
"node-schedule": "^2.1.1",
|
||||
"nodemailer": "^6.9.14",
|
||||
"pdf-creator-node": "^2.3.5",
|
||||
"qrcode": "^1.5.4",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"socket.io": "^4.7.5",
|
||||
|
|
|
@ -22,6 +22,7 @@ import { SynchronizeProtocolDecisionCommand } from "../../command/protocolDecisi
|
|||
import { SynchronizeProtocolVotingCommand } from "../../command/protocolVotingCommand";
|
||||
import { ProtocolVotingViewModel } from "../../viewmodel/admin/protocolVoting.models";
|
||||
import ProtocolVotingCommandHandler from "../../command/protocolVotingCommandHandler";
|
||||
import { PdfExport } from "../../helpers/pdfExport";
|
||||
|
||||
/**
|
||||
* @description get all protocols
|
||||
|
@ -289,3 +290,47 @@ export async function synchronizeProtocolPrecenseById(req: Request, res: Respons
|
|||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description render protocol to file by id
|
||||
* @param req {Request} Express req object
|
||||
* @param res {Response} Express res object
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
export async function printPdf(req: Request, res: Response): Promise<any> {
|
||||
let protocolId = parseInt(req.params.protocolId);
|
||||
let protocol = await ProtocolService.getById(protocolId);
|
||||
let agenda = await ProtocolAgendaService.getAll(protocolId);
|
||||
let decisions = await ProtocolDecisionService.getAll(protocolId);
|
||||
let presence = await ProtocolPresenceService.getAll(protocolId);
|
||||
let votings = await ProtocolVotingService.getAll(protocolId);
|
||||
|
||||
await PdfExport.renderFile({
|
||||
template: "protocol.template.html",
|
||||
title: protocol.title,
|
||||
data: {
|
||||
title: protocol.title,
|
||||
summary: protocol.summary,
|
||||
date: new Date(protocol.date).toLocaleDateString("de-DE", {
|
||||
weekday: "long",
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
}),
|
||||
start: new Date(protocol.starttime).toLocaleTimeString("de-DE", {
|
||||
minute: "2-digit",
|
||||
hour: "2-digit",
|
||||
}),
|
||||
end: new Date(protocol.endtime).toLocaleTimeString("de-DE", {
|
||||
minute: "2-digit",
|
||||
hour: "2-digit",
|
||||
}),
|
||||
agenda,
|
||||
decisions,
|
||||
presence: presence.map((p) => p.member),
|
||||
votings,
|
||||
},
|
||||
});
|
||||
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
|
34
src/helpers/pdfExport.ts
Normal file
34
src/helpers/pdfExport.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { readFileSync } from "fs";
|
||||
import pdf, { Options } from "pdf-creator-node";
|
||||
|
||||
var options = (title: string = "pdf-export Mitgliederverwaltung"): Options => ({
|
||||
format: "A4",
|
||||
orientation: "portrait",
|
||||
border: "10mm",
|
||||
header: {
|
||||
height: "10mm",
|
||||
contents: `<h1 style="text-align: center;">${title}</h1>`,
|
||||
},
|
||||
footer: {
|
||||
height: "5mm",
|
||||
contents: {
|
||||
default: '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export abstract class PdfExport {
|
||||
static getTemplate(template: string) {
|
||||
return readFileSync(process.cwd() + "/src/templates/" + template, "utf8");
|
||||
}
|
||||
|
||||
static async renderFile({ template, title, data }: { template: string; title: string; data: any }) {
|
||||
let document = {
|
||||
html: this.getTemplate(template),
|
||||
data,
|
||||
path: process.cwd() + `/export/${title}.pdf`,
|
||||
};
|
||||
|
||||
await pdf.create(document, options(title));
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import {
|
|||
getProtocolDecisonsById,
|
||||
getProtocolPrecenseById,
|
||||
getProtocolVotingsById,
|
||||
printPdf,
|
||||
synchronizeProtocolAgendaById,
|
||||
synchronizeProtocolById,
|
||||
synchronizeProtocolDecisonsById,
|
||||
|
@ -59,6 +60,10 @@ router.post("/:protocolId/voting", async (req: Request, res: Response) => {
|
|||
await createProtocolVotingsById(req, res);
|
||||
});
|
||||
|
||||
router.post("/:protocolId/render", async (req: Request, res: Response) => {
|
||||
await printPdf(req, res);
|
||||
});
|
||||
|
||||
router.patch("/:id/synchronize", async (req: Request, res: Response) => {
|
||||
await synchronizeProtocolById(req, res);
|
||||
});
|
||||
|
|
36
src/templates/protocol.template.html
Normal file
36
src/templates/protocol.template.html
Normal file
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Protokoll</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{title}}</h1>
|
||||
<p>Am {{date}} von {{start}} Uhr bis {{end}} Uhr</p>
|
||||
<p>{{sumary}}</p>
|
||||
<h2>Anwesenheit</h2>
|
||||
<ul>
|
||||
{{#each presence}}
|
||||
<li>{{this.firstname}} {{this.lastname}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h2>Agenda</h2>
|
||||
<ul>
|
||||
{{#each agenda}}
|
||||
<li>{{this}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h2>Entscheidungen</h2>
|
||||
<ul>
|
||||
{{#each decisions}}
|
||||
<li>{{this}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<h2>Abstimmungen</h2>
|
||||
<ul>
|
||||
{{#each votings}}
|
||||
<li>{{this}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
27
src/types/pdf-creator-node.d.ts
vendored
Normal file
27
src/types/pdf-creator-node.d.ts
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// types/pdf-creator-node.d.ts
|
||||
declare module "pdf-creator-node" {
|
||||
interface Document {
|
||||
html: string;
|
||||
data: any;
|
||||
path: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
format: string;
|
||||
orientation: string;
|
||||
border: string;
|
||||
header?: {
|
||||
height: string;
|
||||
contents: string;
|
||||
};
|
||||
footer?: {
|
||||
height: string;
|
||||
contents: string | { [key: string]: string | number };
|
||||
};
|
||||
}
|
||||
|
||||
function create(document: Document, options: Options): Promise<any>;
|
||||
|
||||
export { create, Document, Options };
|
||||
}
|
Loading…
Reference in a new issue