From 491bd2db7dd2ef1f56027d6f8f9bf900b4457017 Mon Sep 17 00:00:00 2001 From: Cay Date: Tue, 6 Jan 2026 19:17:40 +0000 Subject: [PATCH] Awnderung der HTML von Invoice --- controllers/invoicePdf.controller.js | 30 +-- controllers/invoicePdf.controller.js_original | 109 +++++++++++ views/invoices/invoice.ejs | 173 ++++++++++++++---- views/invoices/invoice.ejs_original | 76 ++++++++ 4 files changed, 339 insertions(+), 49 deletions(-) create mode 100644 controllers/invoicePdf.controller.js_original create mode 100644 views/invoices/invoice.ejs_original diff --git a/controllers/invoicePdf.controller.js b/controllers/invoicePdf.controller.js index 3074a7c..40cf12b 100644 --- a/controllers/invoicePdf.controller.js +++ b/controllers/invoicePdf.controller.js @@ -18,18 +18,16 @@ async function createInvoicePdf(req, res) { return res.status(404).send("Patient nicht gefunden"); } - // 2️⃣ Leistungen laden (noch nicht abgerechnet) + // 2️⃣ Leistungen laden const [rows] = await db.promise().query(` SELECT ps.quantity, COALESCE(ps.price_override, s.price) AS price, - CASE WHEN UPPER(TRIM(?)) = 'ES' THEN COALESCE(NULLIF(s.name_es, ''), s.name_de) ELSE s.name_de END AS name - FROM patient_services ps JOIN services s ON ps.service_id = s.id WHERE ps.patient_id = ? @@ -49,10 +47,15 @@ async function createInvoicePdf(req, res) { const total = services.reduce((sum, s) => sum + s.total, 0); - // 3️⃣ HTML aus EJS erzeugen + // 3️⃣ HTML rendern (NOCH OHNE invoiceId) + const invoice = { + number: "—", + date: new Date().toLocaleDateString("de-DE") + }; + const html = await ejs.renderFile( path.join(__dirname, "../views/invoices/invoice.ejs"), - { patient, services, total } + { patient, services, total, invoice } ); // 4️⃣ PDF erzeugen @@ -61,18 +64,17 @@ async function createInvoicePdf(req, res) { { format: "A4" } ); - // 5️⃣ Dateiname + Pfad - const date = new Date().toISOString().split("T")[0]; // YYYY-MM-DD - const fileName = `invoice_${patientId}_${date}.pdf`; + // 5️⃣ Datei speichern + const dateStr = new Date().toISOString().split("T")[0]; + const fileName = `invoice_${patientId}_${dateStr}.pdf`; const outputPath = path.join(__dirname, "..", "documents", fileName); - // 6️⃣ PDF speichern fs.writeFileSync(outputPath, pdfBuffer); - // 7️⃣ OPTIONAL: Rechnung in DB speichern (empfohlen) + // 6️⃣ Rechnung EINMAL in DB speichern const [invoiceResult] = await db.promise().query(` - INSERT INTO invoices - (patient_id, invoice_date, total_amount, file_path, created_by, status) + INSERT INTO invoices + (patient_id, invoice_date, total_amount, file_path, created_by, status) VALUES (?, CURDATE(), ?, ?, ?, 'open') `, [ patientId, @@ -83,7 +85,7 @@ async function createInvoicePdf(req, res) { const invoiceId = invoiceResult.insertId; - // 8️⃣ Leistungen verknüpfen + // 7️⃣ Leistungen verknüpfen await db.promise().query(` UPDATE patient_services SET invoice_id = ? @@ -91,7 +93,7 @@ async function createInvoicePdf(req, res) { AND invoice_id IS NULL `, [invoiceId, patientId]); - // 9️⃣ PDF anzeigen + // 8️⃣ PDF anzeigen res.setHeader("Content-Type", "application/pdf"); res.setHeader( "Content-Disposition", diff --git a/controllers/invoicePdf.controller.js_original b/controllers/invoicePdf.controller.js_original new file mode 100644 index 0000000..3074a7c --- /dev/null +++ b/controllers/invoicePdf.controller.js_original @@ -0,0 +1,109 @@ +const db = require("../db"); +const ejs = require("ejs"); +const path = require("path"); +const fs = require("fs"); +const pdf = require("html-pdf-node"); + +async function createInvoicePdf(req, res) { + const patientId = req.params.id; + + try { + // 1️⃣ Patient laden + const [[patient]] = await db.promise().query( + "SELECT * FROM patients WHERE id = ?", + [patientId] + ); + + if (!patient) { + return res.status(404).send("Patient nicht gefunden"); + } + + // 2️⃣ Leistungen laden (noch nicht abgerechnet) + const [rows] = await db.promise().query(` + SELECT + ps.quantity, + COALESCE(ps.price_override, s.price) AS price, + + CASE + WHEN UPPER(TRIM(?)) = 'ES' + THEN COALESCE(NULLIF(s.name_es, ''), s.name_de) + ELSE s.name_de + END AS name + + FROM patient_services ps + JOIN services s ON ps.service_id = s.id + WHERE ps.patient_id = ? + AND ps.invoice_id IS NULL + `, [patient.country, patientId]); + + if (rows.length === 0) { + return res.send("Keine Leistungen vorhanden"); + } + + const services = rows.map(s => ({ + quantity: Number(s.quantity), + name: s.name, + price: Number(s.price), + total: Number(s.price) * Number(s.quantity) + })); + + const total = services.reduce((sum, s) => sum + s.total, 0); + + // 3️⃣ HTML aus EJS erzeugen + const html = await ejs.renderFile( + path.join(__dirname, "../views/invoices/invoice.ejs"), + { patient, services, total } + ); + + // 4️⃣ PDF erzeugen + const pdfBuffer = await pdf.generatePdf( + { content: html }, + { format: "A4" } + ); + + // 5️⃣ Dateiname + Pfad + const date = new Date().toISOString().split("T")[0]; // YYYY-MM-DD + const fileName = `invoice_${patientId}_${date}.pdf`; + const outputPath = path.join(__dirname, "..", "documents", fileName); + + // 6️⃣ PDF speichern + fs.writeFileSync(outputPath, pdfBuffer); + + // 7️⃣ OPTIONAL: Rechnung in DB speichern (empfohlen) + const [invoiceResult] = await db.promise().query(` + INSERT INTO invoices + (patient_id, invoice_date, total_amount, file_path, created_by, status) + VALUES (?, CURDATE(), ?, ?, ?, 'open') + `, [ + patientId, + total, + `documents/${fileName}`, + req.session.user.id + ]); + + const invoiceId = invoiceResult.insertId; + + // 8️⃣ Leistungen verknüpfen + await db.promise().query(` + UPDATE patient_services + SET invoice_id = ? + WHERE patient_id = ? + AND invoice_id IS NULL + `, [invoiceId, patientId]); + + // 9️⃣ PDF anzeigen + res.setHeader("Content-Type", "application/pdf"); + res.setHeader( + "Content-Disposition", + `inline; filename="${fileName}"` + ); + + res.send(pdfBuffer); + + } catch (err) { + console.error("❌ PDF ERROR:", err); + res.status(500).send("Fehler beim Erstellen der Rechnung"); + } +} + +module.exports = { createInvoicePdf }; diff --git a/views/invoices/invoice.ejs b/views/invoices/invoice.ejs index 38f5f40..24b3174 100644 --- a/views/invoices/invoice.ejs +++ b/views/invoices/invoice.ejs @@ -1,16 +1,28 @@ - - -

Rechnung

+ +
-

-Patient: <%= patient.firstname %> <%= patient.lastname %>
-Adresse:
-<%= patient.street %> <%= patient.house_number %>
-<%= patient.postal_code %> <%= patient.city %> -

+ +
+ + +
- - - - - - - - - - - <% services.forEach(s => { %> - - - - - - - <% }) %> - + +
+ MedCenter Tenerife S.L.
+ C.I.F. B76766302

+ + Praxis El Médano
+ Calle Teobaldo Power 5
+ 38612 El Médano
+ Fon: 922 157 527 / 657 497 996

+ + Praxis Los Cristianos
+ Avenida de Suecia 10
+ 38650 Los Cristianos
+ Fon: 922 157 527 / 654 520 717 +
+ + + +

RECHNUNG / FACTURA

+ + +
MengeLeistungPreisSumme
<%= s.quantity %><%= s.name %><%= s.price.toFixed(2) %> €<%= s.total.toFixed(2) %> €
+ + + + + + + + + + + + + + + + + +
Factura número<%= invoice.number %>Fecha<%= invoice.date %>
Rechnungsnummer<%= invoice.number %>Datum<%= invoice.date %>
N.I.E. / DNI<%= patient.dni || "" %>Geburtsdatum<%= patient.birthdate || "" %>
-

Gesamt: <%= total.toFixed(2) %> €

+
+ + +Patient:
+<%= patient.firstname %> <%= patient.lastname %>
+<%= patient.street %> <%= patient.house_number %>
+<%= patient.postal_code %> <%= patient.city %> + +

+ + +Diagnosis / Diagnose:
+ + +

+ + +

Für unsere Leistungen erlauben wir uns Ihnen folgendes in Rechnung zu stellen:

+ + + + + + + + + + + + +<% services.forEach(s => { %> + + + + + + +<% }) %> + +
MengeTerapia / BehandlungPreis (€)Summe (€)
<%= s.quantity %><%= s.name %><%= s.price.toFixed(2) %><%= s.total.toFixed(2) %>
+ +
+T O T A L: <%= total.toFixed(2) %> € +
+ +
+ + +Forma de pago / Zahlungsform:
+Efectivo □    Tarjeta □
+Barzahlung    EC/Kreditkarte + +

+ + +Santander
+IBAN: ES37 0049 4507 8925 1002 3301
+BIC: BSCHESMMXXX + + - diff --git a/views/invoices/invoice.ejs_original b/views/invoices/invoice.ejs_original new file mode 100644 index 0000000..38f5f40 --- /dev/null +++ b/views/invoices/invoice.ejs_original @@ -0,0 +1,76 @@ + + + + + + + + + +

Rechnung

+ +

+Patient: <%= patient.firstname %> <%= patient.lastname %>
+Adresse:
+<%= patient.street %> <%= patient.house_number %>
+<%= patient.postal_code %> <%= patient.city %> +

+ + + + + + + + + + + + <% services.forEach(s => { %> + + + + + + + <% }) %> + +
MengeLeistungPreisSumme
<%= s.quantity %><%= s.name %><%= s.price.toFixed(2) %> €<%= s.total.toFixed(2) %> €
+ +

Gesamt: <%= total.toFixed(2) %> €

+ + + +