From 458a6ab25439bffcd56850a827fbce091925c89c Mon Sep 17 00:00:00 2001
From: Moritz Utcke
Date: Wed, 9 Apr 2025 21:35:24 -0400
Subject: [PATCH] Ausstellen
---
.github/workflows/prod-pipeline.yml | 2 -
src/lib/server/invoice.ts | 48 +++++++++++++++
src/pages/api/admin/ausstellen.ts | 92 ++++++++++++++++++++++-------
3 files changed, 118 insertions(+), 24 deletions(-)
diff --git a/.github/workflows/prod-pipeline.yml b/.github/workflows/prod-pipeline.yml
index cf4e171d..261b8b90 100644
--- a/.github/workflows/prod-pipeline.yml
+++ b/.github/workflows/prod-pipeline.yml
@@ -1,8 +1,6 @@
name: Production Pipeline
on:
- pull_request:
- branches: [main]
push:
branches: [main]
diff --git a/src/lib/server/invoice.ts b/src/lib/server/invoice.ts
index 9d201cfa..ae5cc794 100644
--- a/src/lib/server/invoice.ts
+++ b/src/lib/server/invoice.ts
@@ -280,3 +280,51 @@ export async function createInvoice(
voucherNumber: abfrage_response["voucherNumber"],
};
}
+
+
+
+/**
+ * Ládt das Reechnungs PDF von LexOffice runter.
+ *
+ * @export
+ * @async
+ * @param {Rechnung} rechnung
+ * @returns {ArrayBuffer}
+ * @throws Falls eine der requests fehlschlägt.
+ */
+export async function getLexOfficeRechnung(rechnung: Rechnung) {
+
+ const response = await fetch(`https://api.lexoffice.io/v1/invoices/${rechnung.lex_office_id}/document`, {
+ method: "GET",
+ headers: {
+ "Accept": `application/json`,
+ "Authorization": `Bearer ${LEX_OFFICE_API_KEY}`,
+ "Content-Type": `application/json`
+ }
+ })
+
+ const body = await response.json()
+
+ if(!("documentFileId" in body)){
+ throw new Error("documentFileId nicht in request.")
+ }
+
+ const file_id = body["documentFileId"];
+
+
+ const fileRequest = await fetch(`https://api.lexoffice.io/v1/files/${file_id}`, {
+ method: "GET",
+ headers: {
+ "Accept": `application/pdf`,
+ "Authorization": `Bearer ${LEX_OFFICE_API_KEY}`,
+ }
+ })
+
+ if (fileRequest.status !== 200) {
+ throw new Error("File request hat nicht funktioniert.")
+ }
+
+ const file = await fileRequest.arrayBuffer()
+
+ return file;
+}
\ No newline at end of file
diff --git a/src/pages/api/admin/ausstellen.ts b/src/pages/api/admin/ausstellen.ts
index fc8ee954..3840f310 100644
--- a/src/pages/api/admin/ausstellen.ts
+++ b/src/pages/api/admin/ausstellen.ts
@@ -18,7 +18,7 @@ import { BASE_URI } from "#lib/constants.js";
import { getAnsichtsausweis, getDatenblatt } from "#lib/server/ausweis.js";
import { PutObjectCommand } from "@aws-sdk/client-s3";
import { s3Client } from "#lib/s3.js";
-import { createInvoice } from "#lib/server/invoice.js";
+import { createInvoice, getLexOfficeRechnung } from "#lib/server/invoice.js";
import { tryCatch } from "#lib/tryCatch.js";
import {
getBedarfsausweisWohnenKomplett,
@@ -121,32 +121,60 @@ export const GET = defineApiRoute({
ausweis.aufnahme.objekt.benutzer
);
- if (pdfAusweis) {
- const command = new PutObjectCommand({
- Bucket: "ibc-pdfs",
- Key: `ID_${ausweis.id}_Energieausweis.pdf`,
- Body: pdfAusweis,
- ACL: "private",
- });
+ const pdfRechnung = await getLexOfficeRechnung(rechnung);
- await s3Client.send(command);
+ if (!pdfAusweis) {
+ throw new APIError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: "Ausweis PDF konnte nicht generiert werden."
+ })
}
- if (pdfDatenblatt) {
- const command = new PutObjectCommand({
- Bucket: "ibc-pdfs",
- Key: `ID_${ausweis.id}_Datenblatt.pdf`,
- Body: pdfDatenblatt,
- ACL: "private",
- });
-
- await s3Client.send(command);
+ if (!pdfDatenblatt) {
+ throw new APIError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: "Datenblatt PDF konnte nicht generiert werden."
+ })
}
- let text: string;
+ if (!pdfRechnung) {
+ throw new APIError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: "Rechnungs PDF konnte nicht generiert werden."
+ })
+ }
+
+ const ausweisCommand = new PutObjectCommand({
+ Bucket: "ibc-pdfs",
+ Key: `ID_${ausweis.id}_Energieausweis.pdf`,
+ Body: pdfAusweis,
+ ACL: "private",
+ });
+
+ await s3Client.send(ausweisCommand);
+
+ const datenblattCommand = new PutObjectCommand({
+ Bucket: "ibc-pdfs",
+ Key: `ID_${ausweis.id}_Datenblatt.pdf`,
+ Body: pdfDatenblatt,
+ ACL: "private",
+ });
+
+ await s3Client.send(datenblattCommand);
+
+ const rechnungsCommand = new PutObjectCommand({
+ Bucket: "ibc-pdfs",
+ Key: `ID_${ausweis.id}_Rechnung.pdf`,
+ Body: pdfDatenblatt,
+ ACL: "private",
+ });
+
+ await s3Client.send(rechnungsCommand);
+
+ let html: string;
if (rechnung.status === Enums.Rechnungsstatus.paid) {
- text = `
+ html = `
Sehr geehrte*r ${user.vorname} ${user.name},
im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Den Rechnungsbetrag haben Sie bereits bezahlt. Vielen Dank.
@@ -173,7 +201,7 @@ fon 040 · 209339850
fax 040 · 209339859
`;
} else {
- text = `
+ html = `
Sehr geehrte*r ${user.vorname} ${user.name},
im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Nachfolgend finden Sie unsere Bankverbindung. Bitte geben Sie als Verwendungszweck die Rechnungsnummer an (siehe unten). Vielen Dank.
@@ -229,8 +257,28 @@ fax 040 · 209339859
await transport.sendMail({
from: `"IBCornelsen" `,
to: user.email,
+ bcc: "info@online-energieausweis.org",
subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.id})`,
- text,
+ html,
+ attachments: [{
+ filename: `ID_${ausweis.id}_Ansichtsausweis.pdf`,
+ encoding: "binary",
+ content: Buffer.from(pdfAusweis),
+ contentType: "application/pdf",
+ contentDisposition: "attachment",
+ }, {
+ filename: `ID_${ausweis.id}_Datenblatt.pdf`,
+ encoding: "binary",
+ content: Buffer.from(pdfDatenblatt),
+ contentType: "application/pdf",
+ contentDisposition: "attachment",
+ }, {
+ filename: `ID_${ausweis.id}_Rechnung.pdf`,
+ encoding: "binary",
+ content: Buffer.from(pdfRechnung),
+ contentType: "application/pdf",
+ contentDisposition: "attachment",
+ }]
});
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {