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:
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