Refactor code structure for improved readability and maintainability

This commit is contained in:
Torsten Schulz (local)
2025-10-23 09:15:46 +02:00
parent ed25373b1c
commit f14597006e
4 changed files with 173 additions and 10 deletions

View File

@@ -260,37 +260,40 @@ async function create() {
// place SEPA inputs 1cm left (≈28.35pt) from previous and slightly up; adjust to align with labels
const inputX = sepaLeft + 220 - 28.35
// reduce vertical raise so inputs sit on same baseline as labels (previously too high)
const inputYAdjust = 6
const inputYAdjust = 6 + 5.67 // Move SEPA inputs (except date) up by additional 2mm (≈5.67pt)
// adjust page2DownShift so inputs move up by 0.75mm (net)
// 0.75mm = 0.075cm -> ~2.12625 pt
const page2DownShift = 0.075 * 28.35 // 0.075 cm -> ~2.12625 pt
// apply labelsShift only to the SEPA form labels/inputs so paragraphs remain unaffected
let syFields = sy + labelsShift
page2.drawText('Mitglied (Vorname und Name)', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_mitglied').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_mitglied').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('Kontoinhaber (Vorname und Name):', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_kontoinhaber').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_kontoinhaber').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('Straße und Hausnummer:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_strasse').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_strasse').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('PLZ und Ort:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_plz_ort').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_plz_ort').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('Kreditinstitut:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_bank').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_bank').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('IBAN:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
form.createTextField('sepa_iban').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
form.createTextField('sepa_iban').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
page2.drawText('BIC:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
// BIC remains full width as requested
form.createTextField('sepa_bic').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust, width: 220, height: fieldHeight2, font: helv })
form.createTextField('sepa_bic').addToPage(page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: 220, height: fieldHeight2, font: helv })
syFields -= lineGap * 1.1
// add signature and date lines 2cm below last field
@@ -444,6 +447,66 @@ Das Vereinsmitglied trifft die Entscheidung zur Veröffentlichung seiner Daten i
py = drawWrappedOnPage3('folgende allgemeine Daten zu meiner Person:', leftX, py, normalSize, helv)
py -= blockSpacing
// Rebuild a simple, single-column, non-overlapping form area on page 3
const formLeft = leftX
const formFieldW = 360
const formFieldH = 14
const formGap = 22
// start a bit lower to separate from the block text
py -= 28
// Row layout
const colGap = 220
// Shifts (in points): 1 cm = ~28.35 pt
const leftColShift = 0.3 * 28.35 // 0.3 cm -> ~8.505 pt
const vornameLabelShift = 1.0 * 28.35 // 1.0 cm -> ~28.35 pt
const vornameFieldShift = 1.3 * 28.35 // 1.3 cm -> ~36.855 pt
const leftColX = formLeft + leftColShift
const rightColX = formLeft + colGap
// Row 1: Name (left) and Vorname (right)
// Keep the left label at the original formLeft, move only the input field slightly right by 0.1cm
const leftInputShift = 0.35 * 28.35 // 0.35 cm -> ~9.9225 pt
// extra small horizontal nudge for all non-date inputs: 1mm
const extraHShift = 0.1 * 28.35 // 0.1 cm (1 mm) -> ~2.835 pt
// vertical shift for all input fields (including date): 0.6 cm up
const verticalFieldShift = 0.6 * 28.35 // 0.6 cm -> ~17.01 pt
// downward nudge for non-date inputs requested now: 0.2 cm -> ~5.67 pt
const nonDateDownShift = 0.2 * 28.35 // 0.2 cm -> ~5.67 pt
page3.drawText('Name:', { x: formLeft, y: py, size: normalSize, font: helv })
form.createTextField('page3_name').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
// Vorname label and field moved further right as requested
page3.drawText('Vorname:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
form.createTextField('page3_vorname').addToPage(page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
py -= formGap
// Anschrift (full width)
page3.drawText('Anschrift:', { x: formLeft, y: py, size: normalSize, font: helv })
form.createTextField('page3_anschrift').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: formFieldW + 40, height: formFieldH, font: helv })
py -= formGap
// Row 3: Telefonnummer (left) and E-Mail (right)
// Keep left label at formLeft, shift only the input field by leftInputShift
page3.drawText('Telefonnummer:', { x: formLeft, y: py, size: normalSize, font: helv })
form.createTextField('page3_telefon').addToPage(page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
page3.drawText('E-Mail-Adresse:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
form.createTextField('page3_email').addToPage(page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 180, height: formFieldH, font: helv })
py -= formGap
// remove fax field/label per request (space preserved)
py -= formGap
py -= formGap
// Date and signature line
const dateFieldW = 120
page3.drawText('Frankfurt/Main-Harheim, den', { x: formLeft, y: py, size: normalSize, font: helv })
const dateX = formLeft + helv.widthOfTextAtSize('Frankfurt/Main-Harheim, den ', normalSize)
// date field also moves up by verticalFieldShift (but not horizontally shifted by extraHShift)
// now move the date and signature line 0.2cm down as requested
const dateFieldY = py - formFieldH + verticalFieldShift - nonDateDownShift
form.createTextField('page3_datum').addToPage(page3, { x: dateX, y: dateFieldY, width: dateFieldW, height: formFieldH, font: helv })
// signature line starts directly under the (moved) date field
page3.drawRectangle({ x: dateX, y: dateFieldY - 6, width: 300, height: 1, color: rgb(0,0,0) })
// label under signature line
const sigLabel = 'Datum, Unterschrift (bei Jugendlichen gesetzlicher Vertreter)'
const sigLabelSize = 10
page3.drawText(sigLabel, { x: dateX, y: dateFieldY - 18, size: sigLabelSize, font: helv })
const pdfBytes = await pdfDoc.save()
fs.writeFileSync('server/templates/mitgliedschaft-fillable.pdf', pdfBytes)
console.log('Wrote server/templates/mitgliedschaft-fillable.pdf')

View File

@@ -0,0 +1,100 @@
import fs from 'fs'
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
async function fill() {
const templatePath = 'server/templates/mitgliedschaft-fillable.pdf'
if (!fs.existsSync(templatePath)) {
console.error('Template not found:', templatePath)
process.exit(1)
}
const existingPdfBytes = fs.readFileSync(templatePath)
const pdfDoc = await PDFDocument.load(existingPdfBytes)
const form = pdfDoc.getForm()
// Simple sample data
const sample = {
nachname: 'Müller',
vorname: 'Anna',
strasse: 'Hauptstr. 12',
plz_ort: '60389 Frankfurt',
geburtsdatum: '01.01.1990',
telefon: '069 123456',
email: 'anna.mueller@example.de',
telefon_mobil: '0151 2345678',
mitglied_aktiv: true,
mitglied_passiv: false,
sepa_mitglied: 'Anna Müller',
sepa_kontoinhaber: 'Anna Müller',
sepa_strasse: 'Hauptstr. 12',
sepa_plz_ort: '60389 Frankfurt',
sepa_bank: 'Sparkasse',
sepa_iban: 'DE00123456781234567890',
sepa_bic: 'PBNKDEFF',
sepa_datum: '23.10.2025',
sign_datum: '23.10.2025',
page3_name: 'Müller',
page3_vorname: 'Anna',
page3_anschrift: 'Hauptstr. 12, 60389 Frankfurt',
page3_telefon: '069 123456',
page3_fax: '069 654321',
page3_email: 'anna.mueller@example.de',
page3_datum: '23.10.2025'
}
function safeSetText(name, value) {
try {
const f = form.getTextField(name)
f.setText(value)
} catch (e) {
// ignore missing fields
}
}
safeSetText('nachname', sample.nachname)
safeSetText('vorname', sample.vorname)
safeSetText('strasse', sample.strasse)
safeSetText('plz_ort', sample.plz_ort)
safeSetText('geburtsdatum', sample.geburtsdatum)
safeSetText('telefon', sample.telefon)
safeSetText('email', sample.email)
safeSetText('telefon_mobil', sample.telefon_mobil)
try {
const cbA = form.getCheckBox('mitglied_aktiv')
if (sample.mitglied_aktiv) cbA.check(); else cbA.uncheck()
} catch(e) {}
try {
const cbP = form.getCheckBox('mitglied_passiv')
if (sample.mitglied_passiv) cbP.check(); else cbP.uncheck()
} catch(e) {}
safeSetText('sepa_mitglied', sample.sepa_mitglied)
safeSetText('sepa_kontoinhaber', sample.sepa_kontoinhaber)
safeSetText('sepa_strasse', sample.sepa_strasse)
safeSetText('sepa_plz_ort', sample.sepa_plz_ort)
safeSetText('sepa_bank', sample.sepa_bank)
safeSetText('sepa_iban', sample.sepa_iban)
safeSetText('sepa_bic', sample.sepa_bic)
safeSetText('sepa_datum', sample.sepa_datum)
safeSetText('sign_datum', sample.sign_datum)
// page3 fields
safeSetText('page3_name', sample.page3_name)
safeSetText('page3_vorname', sample.page3_vorname)
safeSetText('page3_anschrift', sample.page3_anschrift)
safeSetText('page3_telefon', sample.page3_telefon)
safeSetText('page3_fax', sample.page3_fax)
safeSetText('page3_email', sample.page3_email)
safeSetText('page3_datum', sample.page3_datum)
// flatten all fields
try { form.flatten() } catch (e) {}
const out = await pdfDoc.save()
if (!fs.existsSync('temp')) fs.mkdirSync('temp')
fs.writeFileSync('temp/mitgliedschaft-sample-filled.pdf', out)
console.log('Wrote temp/mitgliedschaft-sample-filled.pdf')
}
fill().catch(e => { console.error(e); process.exit(1) })

Binary file not shown.