exchange

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

commit 2e05d7d387b121c716cd51773878aa348f7341f0
parent 06ce60012494c57983a4a44cb1530aea0ff0d787
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 11 Nov 2025 16:56:37 +0100

add Typst template for VQF 902.13

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

diff --git a/contrib/typst/VQF_902_13.typ b/contrib/typst/VQF_902_13.typ @@ -0,0 +1,495 @@ +// VQF 902.13 Declaration for trusts (T) 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.13#linebreak() + Version of 1 September 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")[Declaration for trusts (T)]) + + 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()[The undersigned hereby declare(s) that as trustee or a member of highest supervisory body of an underlying company of a trust known as:] + + v(0.5em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("ENTITY_NAME")] + ) + + v(1em) + + text()[and, such capacity, provide(s) to best of his/her/their knowledge the following information:] + + v(1.5em) + + // Section 1: Trust Information +[= 1. Name and information pertaining to the trust (tick the two boxes applicable):] + + v(0.5em) + + let entity_type = get("ENTITY_TYPE") + let entity_revoc = get("ENTITY_REVOCABILITY") + + block(breakable: false)[ + #grid( + columns: (auto, 1fr, auto, 1fr), + gutter: 1em, + row-gutter: 0.8em, + [Type of trust:], + [#checkbox(entity_type == "DISCRETIONARY") Discretionary trust], + [or], + [#checkbox(entity_type == "NON_DISCRETIONARY") Non-discretionary trust], + [and], [], [], [], + [Revocability:], + [#checkbox(entity_revoc == "REVOCABLE") Revocable trust], + [or], + [#checkbox(entity_revoc == "IRREVOCABLE") Irrevocable trust], + ) + ] + + v(1.5em) + + // Section 2: Settlor Information +[= 2. Information pertaining to the (ultimate economic, not fiduciary) settlor of the trust (individual(s) or entity/-ies):] + + v(0.5em) + + let settlors = get("FOUNDER_LIST", default: ()) + let has_settlors = type(settlors) == array and settlors.len() > 0 + + for settlor in (if has_settlors {settlors} else {((:),)}) { + let get_settlor(key) = { + if settlor != (:) { + settlor.at(key, default: "") + } else { + "" + } + } + + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [#get_settlor("PERSON_ENTITY_NAME")], + [Actual address of domicile/registered office:], [#get_settlor("PERSON_DOMICILE_REGISTERED_OFFICE")], + [Country:], [#get_settlor("PERSON_COUNTRY")], + [Date of birth:], [#get_settlor("PERSON_DATE_OF_BIRTH")], + [Nationality:], [#get_settlor("PERSON_NATIONALITY")], + [Date of death (if deceased):], [#get_settlor("PERSON_DATE_OF_DEATH")] + ) + ] + let settlor_revoc = get_settlor("FOUNDER_HAS_REVOCATION_RIGHT") + table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [In case of a revocable trust: + \ Does the settlor have the right to revoke the trust?], + [#grid( + columns: (auto, auto), + stroke: 0.5pt + black, + inset: 5pt, + [#checkbox((entity_revoc == "REVOCABLE") and settlor_revoc) Yes], + [#checkbox((entity_revoc == "REVOCABLE") and not settlor_revoc) No], + )] + ) + v(0.5em) + + } + + + v(1.5em) + + // Section 3: Pre-existing Trust +[= 3. If the trust results from a restructuring of a pre-existing trust (re-settlement) or a merger of pre-existing trusts, the following information pertaining to the (actual) settlor of the pre-existing trust(s) has to be given:] + + v(0.5em) + + let has_pred = get("HAS_PREDECESSOR_ENTITY") + let pred_settlors = get("PREDECESSOR_FOUNDER_LIST", default: ()) + let has_pred_settlors = has_pred and type(pred_settlors) == array and pred_settlors.len() > 0 + + if has_pred_settlors { + for pred in pred_settlors { + let get_pred(key) = { + pred.at(key, default: "") + } + + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [#get_pred("PERSON_ENTITY_NAME")], + [Actual address of domicile/registered office:], [#get_pred("PERSON_DOMICILE_REGISTERED_OFFICE")], + [Country:], [#get_pred("PERSON_COUNTRY")], + [Date of birth:], [#get_pred("PERSON_DATE_OF_BIRTH")], + [Nationality:], [#get_pred("PERSON_NATIONALITY")], + [Date of death (if deceased):], [#get_pred("PERSON_DATE_OF_DEATH")] + ) + ] + v(0.5em) + } + } else { + table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [], + [Actual address of domicile/registered office:], [], + [Country:], [], + [Date of birth:], [], + [Nationality:], [], + [Date of death (if deceased):], [] + ) + } + + // Section 4: Beneficiary Information +[= 4. Information] + + v(0.5em) + +[== a) pertaining to the beneficiary/-ies at the time of the signing of this form:] + + v(0.5em) + + let beneficiaries = get("BENEFICIARY_LIST", default: ()) + let has_benef = type(beneficiaries) == array and beneficiaries.len() > 0 + + if has_benef { + for benef in beneficiaries { + let get_benef(key) = { + benef.at(key, default: "") + } + let has_claim = get_benef("BENEFICIARY_HAS_CLAIM_RIGHT") + + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [#get_benef("PERSON_ENTITY_NAME")], + [Actual address of domicile/registered office:], [#get_benef("PERSON_DOMICILE_REGISTERED_OFFICE")], + [Country:], [#get_benef("PERSON_COUNTRY")], + [Date of birth:], [#get_benef("PERSON_DATE_OF_BIRTH")], + [Nationality:], [#get_benef("PERSON_NATIONALITY")] + ) + #table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [Has the beneficiary an actual right to claim a distribution?], + [#grid( + columns: (auto, auto), + stroke: 0.5pt + black, + inset: 5pt, + [#checkbox(has_claim) Yes], + [#checkbox(not has_claim) No], + )] + ) + ] + v(0.5em) + } + } else { + table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [], + [Actual address of domicile/registered office:], [], + [Country:], [], + [Date of birth:], [], + [Nationality:], [] + ) + table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [Has the beneficiary an actual right to claim a distribution?], + [#grid( + columns: (auto, auto), + stroke: 0.5pt + black, + inset: 5pt, + [#checkbox(false) Yes], + [#checkbox(false) No], + )] + ) + } + + v(1em) + +[== b) and in addition to certain beneficiaries or if no beneficiary/-ies has/have been determined, pertaining to (a) group(s) of beneficiaries (e.g. descendants of the settlor) known at the time of the signing of this form:] + + v(0.5em) + + table( + columns: (1fr), + stroke: 0.5pt + black, + inset: 5pt, + [#get("BENEFICIARY_GROUP_DESCRIPTION")] + ) + + v(1.5em) + + // Section 5: Protectors and Other Persons +[= 5. Information pertaining to the protector(s) as well as (a) further person(s) having the right to revoke the trust (in case of revocable trusts) or to appoint the trustee of a trust:] + + v(0.5em) + +[== a) Information pertaining to the protector(s)] + + v(0.5em) + + let protectors = get("PROTECTOR_LIST", default: ()) + let has_prot = type(protectors) == array and protectors.len() > 0 + + if has_prot { + for prot in protectors { + let get_prot(key) = { + prot.at(key, default: "") + } + + let prot_revoc = get_prot("PROTECTOR_HAS_REVOCATION_RIGHT") + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name)/entity:], [#get_prot("PERSON_ENTITY_NAME")], + [Actual address of domicile/registered office:], [#get_prot("PERSON_DOMICILE_REGISTERED_OFFICE")], + [Country:], [#get_prot("PERSON_COUNTRY")], + [Date of birth:], [#get_prot("PERSON_DATE_OF_BIRTH")], + [Nationality:], [#get_prot("PERSON_NATIONALITY")] + ) + #table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [In case of a revocable trust: + \ Does the protector have the right to revoke the trust?], + [#grid( + columns: (auto, auto), + stroke: 0.5pt + black, + inset: 5pt, + [#checkbox(prot_revoc) Yes], + [#checkbox(not prot_revoc) No], + )] + ) + ] + v(0.5em) + } + } else { + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Full name/entity:], [], + [Actual address of domicile/registered office:], [], + [Country:], [], + [Date of birth:], [], + [Nationality:], [] + ) + #table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [In case of a revocable trust: + \ Does the protector have the right to revoke the trust?], + [#grid( + columns: (auto, auto), + stroke: 0.5pt + black, + inset: 5pt, + [#checkbox(false) Yes], + [#checkbox(false) No], + )] + )] + } + + v(0.5em) + + v(1em) + +[== b) Information pertaining to (a) further person(s)] + + v(0.5em) + + let others = get("OTHER_PERSON_LIST", default: ()) + let has_others = type(others) == array and others.len() > 0 + + if has_others { + for other in others { + let get_other(key) = { + other.at(key, default: "") + } + + block(breakable: false)[ + #table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Last name(s), first name(s)/entity:], [#get_other("PERSON_ENTITY_NAME")], + [Actual address of domicile/registered office:], [#get_other("PERSON_DOMICILE_REGISTERED_OFFICE")], + [Country:], [#get_other("PERSON_COUNTRY")], + [Date(s) of birth:], [#get_other("PERSON_DATE_OF_BIRTH")], + [Nationality:], [#get_other("PERSON_NATIONALITY")] + ) + ] + v(0.5em) + } + } else { + table( + columns: (35%, 65%), + stroke: 0.5pt + black, + inset: 5pt, + [Last name(s), first name(s)/entity:], [], + [Actual address of domicile/registered office:], [], + [Country:], [], + [Date(s) of birth:], [], + [Nationality:], [] + ) + } + + v(0.5em) + + let other_revoc = get("OTHER_PERSON_HAS_REVOCATION_RIGHT") + if entity_revoc == "REVOCABLE" [ + #table( + columns: (80%, 20%), + stroke: 0.5pt + black, + inset: 5pt, + [In case of a revocable trust: Has/have this/these further person(s) the right to revoke the trust?], + [#grid( + columns: (auto, 1fr), + gutter: 0.5em, + checkbox(other_revoc), [Yes], + checkbox(not other_revoc), [No], + )] + ) + ] + + v(1.5em) + + text()[The contracting partner(s) hereby declare(s) to be entitled to open a business relationship for the trust above or its underlying company.] + + v(0.5em) + + text()[The contracting partner(s) hereby undertake(s) to automatically inform of any changes to the information contained herein.] + + v(1.5em) + + // Signature + table( + columns: (1fr, 1fr), + 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": "Trustee Company AG\nExample Street 1\n8001 Zurich", + "ENTITY_NAME": "Example Trust", + "ENTITY_TYPE": "DISCRETIONARY", + "ENTITY_REVOCABILITY": "IRREVOCABLE", + "FOUNDER_LIST": ( + ( + "PERSON_ENTITY_NAME": "Jane Smith", + "PERSON_DOMICILE_REGISTERED_OFFICE": "Main St 123\n8001 Zurich", + "PERSON_COUNTRY": "CH", + "PERSON_DATE_OF_BIRTH": "01.01.1955", + "PERSON_NATIONALITY": "CH", + ), + ), + "HAS_PREDECESSOR_ENTITY": false, + "SIGNATURE": "Trustee", + "SIGN_DATE": "10.11.2025", +)) +\ No newline at end of file