exchange

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

commit f1cfbea2e889e7459634690c405c20e4b2b0e7d8
parent 2e05d7d387b121c716cd51773878aa348f7341f0
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 11 Nov 2025 21:09:21 +0100

do VQF 902.15 typst form

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

diff --git a/contrib/typst/VQF_902_15.typ b/contrib/typst/VQF_902_15.typ @@ -0,0 +1,320 @@ +// VQF 902.15 Life Insurance Policies (I) 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.15#linebreak() + Version of 22 January 2021 + ], + 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) + + let get(key, default: "") = { + data.at(key, default: default) + } + + 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")[Information on life insurance policies with separately managed accounts/securities accounts (so-called insurance wrappers) (I)]) + + v(-1em) + line(length:100%) + + v(1em) + + text(weight: "bold")[Contracting partner:] + + v(0.5em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("IDENTITY_CONTRACTING_PARTNER")] + ) + + v(1em) + + text(weight: "bold")[Name or number of the contractual relationship between the contracting party and the financial intermediary:] + + v(0.5em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("CONTRACTUAL_RELATIONSHIP_NAME")] + ) + + v(1em) + + text(weight: "bold")[Insurance policy:] + + v(0.5em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("INSURANCE_POLICY_DETAILS")] + ) + + v(1em) + + text()[The contracting partner confirms in accordance with Art. 41a SRO Regulations that it is a licensed and state-supervised insurance company and that it has entered into the above-mentioned contractual relationship the assets connected to the life insurance policy also mentioned above.] + + v(0.5em) + + text()[In relation with the above insurance policy, the contracting partner gives the following further details:] + + v(1.5em) + + // Section 1: Policy Holder +[= 1. Policy holder] + + v(0.5em) + + let policy_holders = get("POLICY_HOLDER_LIST", default: ()) + let has_holders = type(policy_holders) == array and policy_holders.len() > 0 + + for holder in (if has_holders {policy_holders} else {((:),)}) { + let get_holder(key) = { + if holder != (:) { + holder.at(key, default: "") + } else { + "" + } + } + + text()[Full name/entity:] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get_holder("PERSON_ENTITY_NAME")] + ) + + v(0.5em) + + table( + columns: (40%, 10%, 50%), + stroke: 0.5pt + black, + inset: 5pt, + [Date of birth:], + [], + [Nationality:], + [#get_holder("PERSON_DATE_OF_BIRTH")], + [], + [#get_holder("PERSON_NATIONALITY")] + ) + + v(0.5em) + + text()[Actual address of domicile/registered office (incl. country):] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get_holder("PERSON_DOMICILE_REGISTERED_OFFICE")] + ) + + v(1em) + } + + v(0.5em) + + // Section 2: Premium Payer +[= 2. Person actually (not in a fiduciary capacity) paying the premiums (to be filled in if not identical with point 1 above):] + + v(0.5em) + + let same_payer = get("PREMIUM_PAYER_SAME_AS_HOLDER") + let premium_payers = get("PREMIUM_PAYER_LIST", default: ()) + let has_payers = not same_payer and type(premium_payers) == array and premium_payers.len() > 0 + + if has_payers { + for payer in premium_payers { + let get_payer(key) = { + payer.at(key, default: "") + } + + text()[Full anme/entity:] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get_payer("PERSON_ENTITY_NAME")] + ) + + v(0.5em) + + table( + columns: (40%, 10%, 50%), + stroke: 0.5pt + black, + inset: 5pt, + [Date of birth:], + [], + [Nationality:], + [#get_payer("PERSON_DATE_OF_BIRTH")], + [], + [#get_payer("PERSON_NATIONALITY")] + ) + + v(0.5em) + + text()[Actual address of domicile/registered office (incl. country):] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get_payer("PERSON_DOMICILE_REGISTERED_OFFICE")] + ) + + v(1em) + } + } else { + text()[Full name/entity:] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [] + ) + + v(0.5em) + + table( + columns: (40%, 10%, 50%), + stroke: 0.5pt + black, + inset: 5pt, + [Date of birth:], + [], + [Nationality:], + [], + [], + [] + ) + + v(0.5em) + + text()[Actual address of domicile/registered office (incl. country):] + + v(0.3em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [] + ) + + v(1em) + } + + v(1em) + + text()[The contracting partner hereby undertakes to automatically inform the financial intermediary of any changes. The contracting partner hereby also declares having been given permission by the above individuals and/or entities to transmit their data to the financial intermediary.] + + v(1.5em) + + // Signature + table( + columns: (40%, 10%, 50%), + stroke: 0.5pt + black, + inset: 5pt, + [Date:], + [], + [Signature(s):], + [#get("SIGN_DATE")], + [], + [#get("SIGNATURE")] + ) + + v(1em) + + text(size: 9pt, style: "italic")[ + It is a criminal offence to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery). + ] +} + +// Example usage: +#form(( + "VQF_MEMBER_NUMBER": "12345", + "FILE_NUMBER": "42", + "IDENTITY_CONTRACTING_PARTNER": "Insurance Company AG\nInsurance Street 1\n8001 Zurich\nSwitzerland", + "CONTRACTUAL_RELATIONSHIP_NAME": "Policy #12345-ABC", + "INSURANCE_POLICY_DETAILS": "Life insurance policy with separate account management\nPolicy Number: LI-2025-001\nIssued: 01.01.2025", + "POLICY_HOLDER_LIST": ( + ( + "PERSON_ENTITY_NAME": "John Doe", + "PERSON_DATE_OF_BIRTH": "01.01.1970", + "PERSON_NATIONALITY": "CH", + "PERSON_DOMICILE_REGISTERED_OFFICE": "Main Street 123\n8001 Zurich\nSwitzerland" + ), + ), + "PREMIUM_PAYER_SAME_AS_HOLDER": true, + "SIGNATURE": "Insurance Company Representative", + "SIGN_DATE": "10.11.2025", +)) +\ No newline at end of file