Skip to content

Commit

Permalink
feat(Utilize translations inside of template + PDFs) (#1484)
Browse files Browse the repository at this point in the history
* inject translations into template interpolation function, inject translations into pdf filler function

* inject translations into pdf builder function for PKH, add buildBelegeList function and print out belege from translations

* catch undefined values with a descriptive error
  • Loading branch information
Spencer6497 authored Dec 6, 2024
1 parent 860d1f3 commit 225bd4b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 9 deletions.
17 changes: 14 additions & 3 deletions app/domains/prozesskostenhilfe/services/pdf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { PDFDocument } from "pdf-lib";
import type { ProzesskostenhilfePDF } from "data/pdf/prozesskostenhilfe/prozesskostenhilfe.generated";
import { getProzesskostenhilfeParameters } from "data/pdf/prozesskostenhilfe/prozesskostenhilfe.generated";
import type { ProzesskostenhilfeFormularContext } from "~/domains/prozesskostenhilfe/formular";
import { belegeStrings } from "~/domains/prozesskostenhilfe/formular/stringReplacements";
import { fillZahlungsverpflichtungen } from "~/domains/prozesskostenhilfe/services/pdf/pdfForm/I_zahlungsverpflichtungen";
import { buildBelegeList } from "~/domains/prozesskostenhilfe/services/pdf/util";
import type { Metadata } from "~/services/pdf/addMetadataToPdf";
import { addMetadataToPdf } from "~/services/pdf/addMetadataToPdf";
import { appendPagesToPdf } from "~/services/pdf/appendPagesToPdf";
Expand All @@ -16,6 +19,7 @@ import {
pdfFromUserData,
type PDFDocumentBuilder,
} from "~/services/pdf/pdfFromUserData";
import type { Translations } from "~/services/translations/getTranslationByKey";
import loadHinweisblatt from "./loadHinweisblatt";
import { fillPerson } from "./pdfForm/A_person";
import { fillRechtsschutzversicherung } from "./pdfForm/B_rechtsschutzversicherung";
Expand All @@ -27,7 +31,6 @@ import { fillAbzuege } from "./pdfForm/F_abzuege";
import { fillEigentum } from "./pdfForm/G_eigentum";
import { fillGrundvoraussetzungen } from "./pdfForm/grundvoraussetzungen";
import { fillWohnkosten } from "./pdfForm/H_wohnkosten";
import { fillZahlungsverpflichtungen } from "./pdfForm/I_zahlungsverpflichtungen";
import { fillBelastungen } from "./pdfForm/J_belastungen";
import { fillFooter } from "./pdfForm/K_footer";
import { printNameInSignatureFormField } from "./printNameInSignatureFormField";
Expand All @@ -51,7 +54,7 @@ const METADATA: Metadata = {

const buildProzesskostenhilfePDFDocument: PDFDocumentBuilder<
ProzesskostenhilfeFormularContext
> = (doc, documentStruct, userData, attachment) => {
> = (doc, documentStruct, userData, attachment, translations) => {
// Attachment holds content of form fields which is too long - output as needed
createAttachmentPages({
doc,
Expand All @@ -60,11 +63,18 @@ const buildProzesskostenhilfePDFDocument: PDFDocumentBuilder<
attachment,
headerText: "Anhang: Antrag auf Bewilligung von Prozesskostenhilfe",
});
if (requiresBelege(userData)) {
buildBelegeList({ doc, documentStruct, userData, translations });
}
createFooter(doc, documentStruct, "Anhang");
};

const requiresBelege = (userData: ProzesskostenhilfeFormularContext) =>
Object.values(belegeStrings(userData)).some((val) => val === true);

export async function prozesskostenhilfePdfFromUserdata(
userData: ProzesskostenhilfeFormularContext,
flowTranslations?: Translations,
) {
const { pdfValues, attachment } = pdfFillReducer({
userData,
Expand Down Expand Up @@ -100,11 +110,12 @@ export async function prozesskostenhilfePdfFromUserdata(
METADATA,
);

if (attachment && attachment.length > 0) {
if ((attachment && attachment.length > 0) || requiresBelege(userData)) {
const pdfKitBuffer = await pdfFromUserData(
userData,
buildProzesskostenhilfePDFDocument,
attachment,
flowTranslations,
);

const mainPdfDocument = await PDFDocument.load(pdfKitBuffer);
Expand Down
48 changes: 48 additions & 0 deletions app/domains/prozesskostenhilfe/services/pdf/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import get from "lodash/get";
import type PDFDocument from "pdfkit";
import type { ProzesskostenhilfeFormularContext } from "~/domains/prozesskostenhilfe/formular";
import { belegeStrings } from "~/domains/prozesskostenhilfe/formular/stringReplacements";
import type { FinancialEntry } from "~/domains/shared/formular/finanzielleAngaben/context";
import { createHeading } from "~/services/pdf/createHeading";
import { pdfStyles } from "~/services/pdf/pdfStyles";
import type { Translations } from "~/services/translations/getTranslationByKey";

export const getTotalMonthlyFinancialEntries = (
financialEntries: FinancialEntry[],
Expand All @@ -24,3 +31,44 @@ export const getTotalMonthlyFinancialEntries = (
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});

export const buildBelegeList = ({
doc,
documentStruct,
userData,
translations,
}: {
doc: typeof PDFDocument;
documentStruct: PDFKit.PDFStructureElement;
userData: ProzesskostenhilfeFormularContext;
translations?: Translations;
}) => {
if (!translations) return;
const conditions = belegeStrings(userData);
createHeading(doc, documentStruct, translations.belegeAnhangHeading, "H2");
doc.moveUp(1);
doc
.fontSize(pdfStyles.page.fontSize)
.font(pdfStyles.page.font)
.text(translations.belegeAnhangSubheading)
.moveDown(1);
const belegeList = Object.entries(conditions)
.filter(([, val]) => val === true)
.map(([key]) => {
const translationKey = `${key}Text`;
return get(
translations,
translationKey,
`<Beleg String not found for ${translationKey}, please ensure a matching translation exists in Strapi>`,
);
});
documentStruct.add(
doc.struct("P", {}, () => {
doc.list(belegeList, {
bulletRadius: 2,
paragraphGap: 8,
indent: pdfStyles.list.paddingLeft,
});
}),
);
};
30 changes: 26 additions & 4 deletions app/routes/shared/pdfDownloadLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,30 @@ import type { FluggastrechteFlugdatenContext } from "~/domains/fluggastrechte/fo
import { fluggastrechtePdfFromUserdata } from "~/domains/fluggastrechte/services/pdf/fluggastrechtePdfFromUserdata";
import type { ProzesskostenhilfeFormularContext } from "~/domains/prozesskostenhilfe/formular";
import { prozesskostenhilfePdfFromUserdata } from "~/domains/prozesskostenhilfe/services/pdf";
import { fetchTranslations } from "~/services/cms/index.server";
import { pruneIrrelevantData } from "~/services/flow/pruner";
import { createPdfResponseHeaders } from "~/services/pdf/createPdfResponseHeaders";
import { getSessionData } from "~/services/session.server";
import type { Translations } from "~/services/translations/getTranslationByKey";
import { pdfDateFormat, today } from "~/util/date";

type PdfFlowContexts =
| BeratungshilfeFormularContext
| FluggastrechteFlugdatenContext
| ProzesskostenhilfeFormularContext;

export type PdfConfig = PdfFlowContexts extends infer T
? T extends PdfFlowContexts
? {
pdfFunction: (
userData: T,
translations?: Translations,
) => Promise<Uint8Array>;
filenameFunction: () => string;
}
: never
: never;

const pdfConfigs = {
"/beratungshilfe/antrag": {
pdfFunction: async (userData: BeratungshilfeFormularContext) =>
Expand All @@ -20,8 +39,10 @@ const pdfConfigs = {
`Antrag_Beratungshilfe_${pdfDateFormat(today())}.pdf`,
},
"/prozesskostenhilfe/formular": {
pdfFunction: async (userData: ProzesskostenhilfeFormularContext) =>
await prozesskostenhilfePdfFromUserdata(userData),
pdfFunction: async (
userData: ProzesskostenhilfeFormularContext,
translations?: Translations,
) => await prozesskostenhilfePdfFromUserdata(userData, translations),
filenameFunction: () =>
`Antrag_Prozesskostenhilfe_${pdfDateFormat(today())}.pdf`,
},
Expand All @@ -31,13 +52,14 @@ const pdfConfigs = {
filenameFunction: () =>
`Fluggastrechte_Klage_${pdfDateFormat(today())}.pdf`,
},
} as const satisfies Partial<Record<FlowId, unknown>>;
} satisfies Partial<Record<FlowId, PdfConfig>>;

export async function pdfDownloadLoader({ request }: LoaderFunctionArgs) {
const { pathname } = new URL(request.url);
const { flowId } = parsePathname(pathname);
if (!(flowId in pdfConfigs))
return new Response(`No pdf config for flowId: ${flowId}`, { status: 501 });
const flowTranslations = await fetchTranslations(flowId);
const { pdfFunction, filenameFunction } =
pdfConfigs[flowId as keyof typeof pdfConfigs];

Expand All @@ -47,7 +69,7 @@ export async function pdfDownloadLoader({ request }: LoaderFunctionArgs) {
);
if (_.isEmpty(userData)) return redirect(flowId);

const fileContent = await pdfFunction(userData);
const fileContent = await pdfFunction(userData, flowTranslations);
const fileSize = fileContent.length;
const filename = filenameFunction();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ export const buildFormularServerTranslations = async ({
const cmsContent = interpolateSerializableObject(
structureCmsContent(formPageContent),
typeof currentFlow.stringReplacements !== "undefined"
? currentFlow.stringReplacements(userDataWithPageData)
? {
...currentFlow.stringReplacements(userDataWithPageData),
...stringTranslations,
}
: {},
);

Expand Down
5 changes: 4 additions & 1 deletion app/services/pdf/pdfFromUserData.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import type PDFDocument from "pdfkit";
import type { AllContexts } from "~/domains/common";
import { createPdfKitDocument } from "~/services/pdf/createPdfKitDocument";
import type { Translations } from "~/services/translations/getTranslationByKey";
import type { AttachmentEntries } from "./attachment";

export type PDFDocumentBuilder<TContext extends AllContexts> = (
doc: typeof PDFDocument,
documentStruct: PDFKit.PDFStructureElement,
userData: TContext,
attachment?: AttachmentEntries,
translations?: Translations,
) => void;

export async function pdfFromUserData<TContext extends AllContexts>(
userData: TContext,
buildPDFDocument: PDFDocumentBuilder<TContext>,
attachment?: AttachmentEntries,
translations?: Translations,
): Promise<Buffer> {
return new Promise((resolve, reject) => {
const doc = createPdfKitDocument();
Expand All @@ -33,7 +36,7 @@ export async function pdfFromUserData<TContext extends AllContexts>(
const documentStruct = doc.struct("Document");
doc.addStructure(documentStruct);

buildPDFDocument(doc, documentStruct, userData, attachment);
buildPDFDocument(doc, documentStruct, userData, attachment, translations);

documentStruct.end();
doc.end();
Expand Down

0 comments on commit 225bd4b

Please sign in to comment.