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