exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 4047818b299348606e483d5a0d14f19c53815216
parent 75e3b7d5eca3b32073f3c90b14a53a6100fb0be4
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 27 Nov 2025 16:32:42 +0100

forms for challenger validations

Diffstat:
Mcontrib/typst/Makefile.am | 2++
Acontrib/typst/challenger_postal.typ | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontrib/typst/challenger_sms.typ | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 182 insertions(+), 0 deletions(-)

diff --git a/contrib/typst/Makefile.am b/contrib/typst/Makefile.am @@ -2,6 +2,8 @@ SUBDIRS = . formdatadir = $(datadir)/taler-exchange/typst-forms/ dist_formdata_DATA = \ + challenger_postal.typ \ + challenger_sms.typ \ pointing_finger.svg \ vqf_902_1_customer.typ \ vqf_902_4.typ \ diff --git a/contrib/typst/challenger_postal.typ b/contrib/typst/challenger_postal.typ @@ -0,0 +1,91 @@ +// Form to render postal addresses validated via Challenger. +// Pass JSON data as content dictionary + +#let form(data) = { + set page( + paper: "a4", + margin: (left: 2cm, right: 2cm, top: 2cm, bottom: 2.5cm), + footer: context [ + #grid( + columns: (1fr, 1fr), + align: (left, right), + text(size: 8pt)[ + ], + text(size: 8pt)[ + Page #here().page() of #counter(page).final().first() + ] + ) + ] + ) + + set text(font: "Liberation Sans", size: 10pt) + set par(justify: false, leading: 0.65em) + + // Helper function to get value or empty string + let get(key, default: "") = { + data.at(key, default: default) + } + + // Helper function for checkbox + let checkbox(checked) = { + box( + width: 3mm, + height: 3mm, + stroke: 0.5pt + black, + inset: 0.3mm, + if checked == true or checked == "true" { + place(center + horizon, text(size: 8pt, sym.checkmark)) + } + ) + } + + // Header + align(center, text(size: 11pt, weight: "bold")[CONFIDENTIAL]) + + v(0.5em) + + grid( + columns: (50%, 50%), + gutter: 1em, + image("vss_vqf_verein.png", width: 80%), + align(right)[ + #table( + columns: (1fr, 1fr), + stroke: 0.5pt + black, + inset: 5pt, + align: (left, left), + [VQF member no.], [AMLA File No.], + [#get("VQF_MEMBER_NUMBER")], [#get("FILE_NUMBER")] + ) + ] + ) + + v(1em) + + // Section 1: Validated address + text(size: 11pt, weight: "bold")[Validated address:] + + v(0.5em) + + block(breakable: false)[ + #v(0.5em) + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Contact name:], [#get("CONTACT_NAME")], + [Address:], [#get("ADDRESS_LINES").split("\n").join(linebreak())], + [Country:], [#get("ADDRESS_COUNTRY")], + ) + #v(0.5em) + ] +} + +// Example usage: +#form(( + "VQF_MEMBER_NUMBER": "12345", + "FILE_NUMBER": "42", + "CONTACT_NAME": "Bob Builder", + "ADDRESS_LINES" : "Parkallee 42\n12345 Bielefeld", + "ADDRESS_COUNTRY" : "Germany", +)) +\ No newline at end of file diff --git a/contrib/typst/challenger_sms.typ b/contrib/typst/challenger_sms.typ @@ -0,0 +1,87 @@ +// Form to render SMS (phone) addresses validated via Challenger. +// Pass JSON data as content dictionary + +#let form(data) = { + set page( + paper: "a4", + margin: (left: 2cm, right: 2cm, top: 2cm, bottom: 2.5cm), + footer: context [ + #grid( + columns: (1fr, 1fr), + align: (left, right), + text(size: 8pt)[ + ], + text(size: 8pt)[ + Page #here().page() of #counter(page).final().first() + ] + ) + ] + ) + + set text(font: "Liberation Sans", size: 10pt) + set par(justify: false, leading: 0.65em) + + // Helper function to get value or empty string + let get(key, default: "") = { + data.at(key, default: default) + } + + // Helper function for checkbox + let checkbox(checked) = { + box( + width: 3mm, + height: 3mm, + stroke: 0.5pt + black, + inset: 0.3mm, + if checked == true or checked == "true" { + place(center + horizon, text(size: 8pt, sym.checkmark)) + } + ) + } + + // Header + align(center, text(size: 11pt, weight: "bold")[CONFIDENTIAL]) + + v(0.5em) + + grid( + columns: (50%, 50%), + gutter: 1em, + image("vss_vqf_verein.png", width: 80%), + align(right)[ + #table( + columns: (1fr, 1fr), + stroke: 0.5pt + black, + inset: 5pt, + align: (left, left), + [VQF member no.], [AMLA File No.], + [#get("VQF_MEMBER_NUMBER")], [#get("FILE_NUMBER")] + ) + ] + ) + + v(1em) + + // Section 1: Validated phone number + text(size: 11pt, weight: "bold")[Validated phone number:] + + v(0.5em) + + block(breakable: false)[ + #v(0.5em) + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Phone number:], [#get("CONTACT_PHONE")], + ) + #v(0.5em) + ] +} + +// Example usage: +#form(( + "VQF_MEMBER_NUMBER": "12345", + "FILE_NUMBER": "42", + "CONTACT_PHONE": "+41123456789", +)) +\ No newline at end of file