exchange

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

commit c4c3844cd45e8011db7eb97f9310abaa84757c8c
parent 5d73821fd6f9ce2c4283f684a05b3d9550684b7d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 10 Nov 2025 23:24:32 +0100

add Typst template for VQF_902_14

Diffstat:
Acontrib/typst/VQF_902_14.typ | 242+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 242 insertions(+), 0 deletions(-)

diff --git a/contrib/typst/VQF_902_14.typ b/contrib/typst/VQF_902_14.typ @@ -0,0 +1,241 @@ +// VQF 902.14 Special Clarifications Template +// 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)[ + VQF doc. Nr. 902.14#linebreak() + Version of 1 December 2015 + ], + 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) + + align(left, text(size: 14pt, weight: "bold")[Special Clarifications]) + + v(-1em) + line(length:100%) + + grid( + columns: (auto, 1fr), + gutter: 0.5em, + align: (left, left), + image("pointing_finger.svg", height: 2em), + text(size: 9pt)[ + When a business relationship or transaction is associated with increased risk, appears unusual or evidence exists that the assets are the proceeds of a felony or a qualified tax offence, the member has to perform additional clarifications. + ] + ) + + v(1em) + + text(weight: "bold")[Customer:#footnote[Pursuant Identification form (VQF doc. No. 902.1) numeral 1.]] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("CUSTOMER_NAME")] + ) + + v(0.5em) + + text(weight: "bold")[This form was completed by:] + + v(0.3em) + + table( + columns: (1fr, 1fr), + stroke: 0.5pt + black, + inset: 5pt, + align: (left, left), + [Full name], [#get("FILED_BY_NAME")], + [Date], [#get("FILING_DATE")], + ) + + v(1.5em) + + // Section 1: Reason for Special Clarifications + text(size: 11pt, weight: "bold")[1. Reason for special clarifications] + + v(0.5em) + + table( + columns: (45%,55%), + stroke: 0.5pt + black, + inset: 5pt, + [Description of the circumstances/transactions, which triggered the special clarifications], + [#get("INCRISK_REASON")] + ) + + v(1.5em) + + // Section 2: Used Means of Clarification + text(size: 11pt, weight: "bold")[2. Used means of clarification] + + v(0.5em) + + let means = get("INCRISK_MEANS") + + grid( + columns: (auto), + inset: 5pt, + stroke: 0.5pt + black, + [#block(breakable: false)[ + #grid( + columns: (auto, 1fr), + gutter: 0.5em, + row-gutter: 0.5em, + checkbox(means == "GATHERING"), + [Gathering of information from the customer, beneficial owner of the assets, controlling person], + + checkbox(means == "CONSULTATION"), + [Consultation of generally accessible sources and databases], + + checkbox(means == "ENQUIRIES"), + [Enquiries with trustworthy persons (e.g. custodian bank)], + + checkbox(means == "OTHER"), + [Other, which? #if means == "OTHER" [#get("INCRISK_MEANS_OTHER")]] + ) + ]]) + + v(1.5em) + + // Section 3: Supplemental Files + text(size: 11pt, weight: "bold")[3. Summary and plausibility check of the gathered information] + + v(0.3em) + + grid( + columns: (auto, 1fr), + gutter: 0.5em, + align: (left, left), + image("pointing_finger.svg", height: 2em), + text(size: 9pt)[ + The results of the clarifications have to be documented and their plausibility has to be checked. + ] + ) + + v(1.5em) + + table( + columns: (100%), + stroke: 0.5pt + black, + inset: 5pt, + [#get("INCRISK_SUMMARY")] + ) + + v(1em) + + table( + columns: (auto, 1fr), + stroke: 0.5pt + black, + inset: 5pt, + [Gathered/Consulted documents], + [#get("INCRISK_DOCUMENTS")] + ) + + + + + // Section 4: Result + text(size: 11pt, weight: "bold")[4. Result of the special clarification] + + v(0.5em) + + let result = get("INCRISK_RESULT") + + grid( + columns: (auto), + inset: 5pt, + stroke: 0.5pt + black, + block(breakable: false)[ + #grid( + columns: (auto, 1fr), + gutter: 0.5em, + row-gutter: 0.8em, + + checkbox(result == "NO_SUSPICION"), + [The plausibility of the circumstances could be checked, no reasonable suspicion pursuant to Art. 9 AMLA (possibly update of customer profile (VQF doc. No. 902.5) and/or risk profile (VQF doc. No. 902.4))], + + checkbox(result == "REASONABLE_SUSPICION"), + [Reasonable suspicion pursuant to Art. 9 AMLA, duty to file a report with MROS], + + checkbox(result == "SIMPLE_SUSPICION"), + [Simple suspicion pursuant to Art. 305#super[ter] Para. 2 StGB, right to notify MROS], + + checkbox(result == "OTHER"), + [Other, what? #if result == "OTHER" [#get("INCRISK_RESULT_OTHER")]] + ) + ]) + +} + +// Example usage: +#form(( + "VQF_MEMBER_NUMBER": "12345", + "FILE_NUMBER": "42", + "CUSTOMER_NAME": "John Doe", + "FILED_BY_NAME": "Jane Smith", + "FILING_DATE": "10.11.2025", + "INCRISK_REASON": "Unusual transaction pattern detected", + "INCRISK_MEANS": "GATHERING", + "INCRISK_SUMMARY": "Customer provided satisfactory explanation", + "INCRISK_DOCUMENTS": "Bank statements, invoices", + "INCRISK_RESULT": "NO_SUSPICION", +)) +\ No newline at end of file