Bedarfsausweis Ausstellen: Fixing PDF Mime Type + LexOffice Rechnung anhängen

This commit is contained in:
Carl Mahnke
2025-04-24 14:20:31 +02:00
parent b64282a7ca
commit d157ed3c0f
2 changed files with 63 additions and 24 deletions

View File

@@ -14,18 +14,15 @@ export const createCaller = createCallerFactory({
"admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"), "admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"), "aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"ausweise": await import("../src/pages/api/ausweise/index.ts"), "ausweise": await import("../src/pages/api/ausweise/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"), "bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"),
"bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"), "bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"),
"bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"), "bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"),
"bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"), "bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"),
"bilder/[id]": await import("../src/pages/api/bilder/[id].ts"), "bilder/[id]": await import("../src/pages/api/bilder/[id].ts"),
"geg-nachweis-gewerbe/[id]": await import("../src/pages/api/geg-nachweis-gewerbe/[id].ts"),
"geg-nachweis-gewerbe": await import("../src/pages/api/geg-nachweis-gewerbe/index.ts"),
"geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"), "geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"),
"geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"), "geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"),
"geg-nachweis-gewerbe/[id]": await import("../src/pages/api/geg-nachweis-gewerbe/[id].ts"),
"geg-nachweis-gewerbe": await import("../src/pages/api/geg-nachweis-gewerbe/index.ts"),
"objekt": await import("../src/pages/api/objekt/index.ts"), "objekt": await import("../src/pages/api/objekt/index.ts"),
"rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"), "rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"),
"rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"), "rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"),
@@ -37,6 +34,9 @@ export const createCaller = createCallerFactory({
"verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"), "verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"),
"verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"), "verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"),
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"), "verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"), "webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"),
"aufnahme/[id]/bilder": await import("../src/pages/api/aufnahme/[id]/bilder.ts"), "aufnahme/[id]/bilder": await import("../src/pages/api/aufnahme/[id]/bilder.ts"),
"aufnahme/[id]": await import("../src/pages/api/aufnahme/[id]/index.ts"), "aufnahme/[id]": await import("../src/pages/api/aufnahme/[id]/index.ts"),

View File

@@ -31,6 +31,14 @@ import isBase64 from "is-base64";
import Mail from "nodemailer/lib/mailer/index.js"; import Mail from "nodemailer/lib/mailer/index.js";
import mime from "mime" import mime from "mime"
const streamToBuffer = async (stream) => {
return new Promise((resolve, reject) => {
const chunks = [];
stream.on("data", (chunk) => chunks.push(chunk));
stream.on("error", reject);
stream.on("end", () => resolve(Buffer.concat(chunks)));
});
};
export const POST = defineApiRoute({ export const POST = defineApiRoute({
input: z.object({ input: z.object({
@@ -131,14 +139,35 @@ export const POST = defineApiRoute({
} }
// Hier müssen wir warten, damit wir sichergehen können, dass die Rechnung bei LexOffice existiert. // Hier müssen wir warten, damit wir sichergehen können, dass die Rechnung bei LexOffice existiert.
// const [pdfRechnung, pdfRechnungError] = await tryCatch(getLexOfficeRechnung(rechnung)); let pdfRechnung, pdfRechnungError;
// if (pdfRechnungError) { try {
// throw new APIError({ const rechnungsCheckCommand = new GetObjectCommand({
// code: "INTERNAL_SERVER_ERROR", Bucket: "ibc-pdfs",
// message: "Rechnungs PDF konnte nicht generiert werden.", Key: `ID_${ausweis.id}_Rechnung.pdf`,
// }); });
// }
const s3Response = await s3Client.send(rechnungsCheckCommand);
pdfRechnung = await streamToBuffer(s3Response.Body);
} catch (error) {
pdfRechnungError = error;
}
if (pdfRechnung && !pdfRechnungError) {
console.log('PDF from S3');
} else {
[pdfRechnung, pdfRechnungError] = await tryCatch(getLexOfficeRechnung(rechnung));
console.log('PDF from LexOffice');
}
if (pdfRechnungError) {
// console.error(pdfRechnungError);
throw new APIError({
code: "INTERNAL_SERVER_ERROR",
message: "Rechnungs PDF konnte nicht generiert werden.",
});
}
const processedFiles: Mail.Attachment[] = [] const processedFiles: Mail.Attachment[] = []
@@ -152,10 +181,8 @@ export const POST = defineApiRoute({
}); });
} }
const dataWithoutPrefix = data.replace( const dataWithoutPrefix = data.replace(/^data:.*;base64,/, "");
/^data:image\/\w+;base64,/,
""
);
const buffer = Buffer.from(dataWithoutPrefix, "base64"); const buffer = Buffer.from(dataWithoutPrefix, "base64");
const mimeType = mime.getType(name.split(".").pop() as string) const mimeType = mime.getType(name.split(".").pop() as string)
@@ -192,14 +219,26 @@ export const POST = defineApiRoute({
await s3Client.send(command); await s3Client.send(command);
} }
const rechnungsCommand = new PutObjectCommand({ if (pdfRechnung) {
Bucket: "ibc-pdfs", processedFiles.push({
Key: `ID_${ausweis.id}_Rechnung.pdf`, filename: `ID_${ausweis.id}_Rechnung.pdf`,
Body: Buffer.from(pdfRechnung), encoding: "binary",
ACL: "private", content: Buffer.from(pdfRechnung),
}); contentType: "application/pdf",
});
}
if (!rechnungsCheckCommand && pdfRechnung != null ){
const rechnungsCommand = new PutObjectCommand({
Bucket: "ibc-pdfs",
Key: `ID_${ausweis.id}_Rechnung.pdf`,
Body: Buffer.from(pdfRechnung),
ACL: "private",
});
await s3Client.send(rechnungsCommand);
}
await s3Client.send(rechnungsCommand);
// Falls Postversand angefragt wurde müssen wir die Dateien auf den Postserver hochladen // Falls Postversand angefragt wurde müssen wir die Dateien auf den Postserver hochladen
if (post) { if (post) {