Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1063: print cardInfoHash on pdf #1095

Merged
merged 3 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions administration/src/cards/PdfFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { PDFDocument, PDFPage, StandardFonts } from 'pdf-lib'
import { DynamicActivationCode, QrCode, StaticVerificationCode } from '../generated/card_pb'
import { Region } from '../generated/graphql'
import { PdfConfig } from '../project-configs/getProjectConfig'
import { uint8ArrayToBase64 } from '../util/base64'
import CardBlueprint from './CardBlueprint'
import hashCardInfo from './hashCardInfo'
import pdfFormElement from './pdf/PdfFormElement'
import pdfQrCodeElement from './pdf/PdfQrCodeElement'
import pdfTextElement from './pdf/PdfTextElement'
Expand Down Expand Up @@ -36,6 +38,8 @@ async function fillContentAreas(
)
}

const cardInfoHash = await hashCardInfo(dynamicCode.value.info!, dynamicCode.value.pepper!)

const form = doc.getForm()
pdfConfig.elements?.form?.forEach(configOptions =>
pdfFormElement(configOptions, {
Expand All @@ -45,6 +49,7 @@ async function fillContentAreas(
info: dynamicCode.value.info!,
region: region,
cardBlueprint,
cardInfoHash: uint8ArrayToBase64(cardInfoHash),
})
)

Expand All @@ -55,6 +60,7 @@ async function fillContentAreas(
info: dynamicCode.value.info!,
region: region,
cardBlueprint,
cardInfoHash: uint8ArrayToBase64(cardInfoHash),
})
)
}
Expand Down
6 changes: 4 additions & 2 deletions administration/src/cards/pdf/PdfFormElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type InfoParams = {
info: CardInfo
region: Region
cardBlueprint: CardBlueprint
cardInfoHash: string
}

export type PdfFormElementProps = {
Expand All @@ -24,14 +25,15 @@ type PdfFormElementRendererProps = {
info: CardInfo
region: Region
cardBlueprint: CardBlueprint
cardInfoHash: string
}

const pdfFormElements: PdfElement<PdfFormElementProps, PdfFormElementRendererProps> = (
{ infoToFormFields, fontSize, width, x, y },
{ page, form, font, info, region, cardBlueprint }
{ page, form, font, info, region, cardBlueprint, cardInfoHash }
) => {
const pageIdx = page.doc.getPageCount()
const formFields = infoToFormFields(form, pageIdx, { info, region, cardBlueprint })
const formFields = infoToFormFields(form, pageIdx, { info, region, cardBlueprint, cardInfoHash })
const lineHeight = font.heightAtSize(fontSize) + 6

formFields.forEach((formField, index) => {
Expand Down
30 changes: 23 additions & 7 deletions administration/src/cards/pdf/PdfTextElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ export type InfoParams = {
info: CardInfo
region: Region
cardBlueprint: CardBlueprint
cardInfoHash: string
}

export type PdfTextElementProps = {
width: number
maxWidth?: number | undefined
fontSize: number
textAlign?: 'left' | 'right' | 'center'
spacing?: number
angle?: number
angle?: number | undefined
color?: Color
infoToText: (info: InfoParams) => string
} & Coordinates
Expand All @@ -26,21 +28,35 @@ type PdfTextElementRendererProps = {
info: CardInfo
region: Region
cardBlueprint: CardBlueprint
cardInfoHash: string
}

const pdfTextElement: PdfElement<PdfTextElementProps, PdfTextElementRendererProps> = (
{ width, x, y, fontSize, infoToText, spacing = 1, angle = 0, color = undefined },
{ page, font, info, region, cardBlueprint }
{ maxWidth, x, y, fontSize, infoToText, spacing = 1, angle = 0, color = undefined, textAlign = 'left' },
{ page, font, info, region, cardBlueprint, cardInfoHash }
) => {
const text = infoToText({ info, region, cardBlueprint })
const text = infoToText({ info, region, cardBlueprint, cardInfoHash })

let xPt: number
switch (textAlign) {
case 'left':
xPt = mmToPt(x)
break
case 'right':
xPt = mmToPt(x) - font.widthOfTextAtSize(text, fontSize)
break
case 'center':
xPt = mmToPt(x) - font.widthOfTextAtSize(text, fontSize) / 2
break
}

const lineHeight = font.heightAtSize(fontSize) + spacing

page.drawText(text, {
font,
x: mmToPt(x),
x: xPt,
y: page.getSize().height - mmToPt(y) - lineHeight,
maxWidth: mmToPt(width),
maxWidth: maxWidth !== undefined ? mmToPt(maxWidth) : undefined,
wordBreaks: text.split('').filter(c => !'\n\f\r\u000B'.includes(c)), // Split on every character
lineHeight,
color,
Expand Down
9 changes: 8 additions & 1 deletion administration/src/project-configs/bayern/pdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ Ausgestellt am ${PlainDate.fromLocalDate(new Date()).format('dd.MM.yyyy')}
von ${region.prefix} ${region.name}`
}

const renderCardHash = ({ cardInfoHash }: InfoParams) => {
return cardInfoHash
}

const pdfConfiguration: PdfConfig = {
title: 'Ehrenamtskarten',
templatePath: pdfTemplate,
issuer: 'Bayerische Staatsministerium für Arbeit und Soziales, Familie und Integration',
elements: {
dynamicActivationQrCodes: [{ x: 108, y: 73, size: 84 }],
text: [{ x: 108, y: 170, width: 84, fontSize: 10, spacing: 4, infoToText: renderPdfInfo }],
text: [
{ x: 108, y: 170, maxWidth: 84, fontSize: 10, spacing: 4, infoToText: renderPdfInfo },
{ x: 149.75, y: 162, fontSize: 6, textAlign: 'center', infoToText: renderCardHash },
],
},
}

Expand Down
11 changes: 8 additions & 3 deletions administration/src/project-configs/nuernberg/pdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const renderPassNumber = ({ info }: InfoParams) => {
return passNumber ? `Nürnberg-Pass-Nr.: ${passNumber?.toString()}` : ''
}

const renderCardHash = ({ cardInfoHash }: InfoParams) => {
return cardInfoHash
}

const pdfConfiguration: PdfConfig = {
title: 'Nürnberg-Pässe',
templatePath: pdfTemplate,
Expand All @@ -69,9 +73,10 @@ const pdfConfiguration: PdfConfig = {
],
dynamicActivationQrCodes: [{ x: 122, y: 110, size: 63 }],
text: [
{ x: 108, y: 243, width: 52, fontSize: 9, spacing: 5, infoToText: renderPdfDetails },
{ x: 129.5, y: 79, width: 44, fontSize: 13, color: rgb(0.17, 0.17, 0.2), infoToText: renderPassId },
{ x: 27, y: 265, width: 46, fontSize: 8, angle: 90, infoToText: renderPassNumber },
{ x: 108, y: 243, maxWidth: 52, fontSize: 9, spacing: 5, infoToText: renderPdfDetails },
{ x: 129.5, y: 79, maxWidth: 44, fontSize: 13, color: rgb(0.17, 0.17, 0.2), infoToText: renderPassId },
{ x: 27, y: 265, maxWidth: 46, fontSize: 8, angle: 90, infoToText: renderPassNumber },
{ x: 153.892, y: 178, fontSize: 6, textAlign: 'center', infoToText: renderCardHash },
],
form: [{ infoToFormFields: createAddressFormFields, x: 25, y: 66, width: 65, fontSize: 10 }],
},
Expand Down