diff options
author | Sebastian <sebasjm@gmail.com> | 2023-06-05 10:04:09 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-06-05 10:04:09 -0300 |
commit | c680f5aa71b08e978444df07f93c381f9d47ab82 (patch) | |
tree | 81903fac003bb1e202cf69551e06ba41a6e960a5 /packages/aml-backoffice-ui/src/forms | |
parent | df53866e6b148ea5fd2ab57e906a4aa36b535ed3 (diff) | |
download | wallet-core-c680f5aa71b08e978444df07f93c381f9d47ab82.tar.xz |
rename aml
Diffstat (limited to 'packages/aml-backoffice-ui/src/forms')
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_11e.ts | 154 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_12e.ts | 440 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_13e.ts | 527 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_15e.ts | 197 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_1e.ts | 695 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_4e.ts | 822 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_5e.ts | 281 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/902_9e.ts | 138 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/index.ts | 146 | ||||
-rw-r--r-- | packages/aml-backoffice-ui/src/forms/simplest.ts | 103 |
10 files changed, 3503 insertions, 0 deletions
diff --git a/packages/aml-backoffice-ui/src/forms/902_11e.ts b/packages/aml-backoffice-ui/src/forms/902_11e.ts new file mode 100644 index 000000000..24df6a44c --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_11e.ts @@ -0,0 +1,154 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_11.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: + "Establishing of the controlling person of operating legal entities and partnerships both not quoted on the stock exchange" as TranslatedString, + description: + "for operating legal entities and partnership that are contracting partner as well as analogously for operating legal entities and partnership that are beneficial owners." as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "contractingPartner", + label: "Contracting partner" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "declares", + label: + "The contracting partner hereby declares that" as TranslatedString, + required: true, + choices: [ + { + label: + "the person(s) listed below is/are holding 25% or more of the contracting partner's shares (capital shares or voting rights)" as TranslatedString, + value: "25-or-more", + }, + { + label: + "if the capital shares or voting rights cannot be determined or in case there are no capital shares or voting rights 25% or more, the contracting partner hereby declares that the person(s) listed below is/are controlling the contracting partner in other ways" as TranslatedString, + value: "controlling-in-other-ways", + }, + { + label: + "in case this/these person(s) cannot be determined or this/these person(s) does/do not exist, the contracting partner hereby declares that the person(s) listed below is/are the managing director(s)" as TranslatedString, + value: "managing-director", + }, + ], + }, + }, + { + type: "array", + props: { + name: "businessEstablisher", + label: "Persons" as TranslatedString, + required: true, + tooltip: "hola" as TranslatedString, + placeholder: "this is the placeholder" as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "lastName", + label: "Last name(s)" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "firstName", + label: "First name(s)" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "address", + label: "Actual address of domicile" as TranslatedString, + required: true, + }, + }, + ], + labelField: "lastName", + }, + }, + { + type: "choiceStacked", + props: { + name: "fiduciaryAssets", + label: "Fiduciary holding assets" as TranslatedString, + help: "Is a third person the beneficial owner of the assets held in the account/securities account?" as TranslatedString, + required: true, + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: "Yes" as TranslatedString, + value: "yes", + description: + "The relevant information regarding the beneficial owner has to be obtained by filling in a separate VQF doc. No. 902.9" as TranslatedString, + }, + ], + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_11.Form>, + ): FormState<Form902_11.Form> { + return { + person: { + hidden: + v.declares !== "controlling-in-other-ways" && + v.declares !== "managing-director", + }, + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_11 { + interface Person { + lastName: string; + firstName: string; + address: string; + } + export interface Form extends Simplest.WithResolution { + contractingPartner: string; + declares: "25-or-more" | "controlling-in-other-ways" | "managing-director"; + person: Person[]; + fiduciaryAssets: "no" | "yes"; + signature: string; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_12e.ts b/packages/aml-backoffice-ui/src/forms/902_12e.ts new file mode 100644 index 000000000..c80539511 --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_12e.ts @@ -0,0 +1,440 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_12.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: "Foundations" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "contractingPartner", + label: "Contracting partner" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "knownAs", + label: + "The undersigned hereby declare(s) that as board member of the foundation, or of the highest supervisory body of an underlying company of a foundation, known as" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "foundation.name", + label: + "Name and information pertaining to the foundation" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "foundation.type", + label: "Type of foundation" as TranslatedString, + choices: [ + { + label: "Discretionary foundation" as TranslatedString, + value: "discretionary", + }, + { + label: "Non-discretionary foundation" as TranslatedString, + value: "non-discretionary", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + name: "foundation.revocability", + label: "Revocability" as TranslatedString, + choices: [ + { + label: "Revocable foundation" as TranslatedString, + value: "revocable", + }, + { + label: "Irrevocable foundation" as TranslatedString, + value: "irrevocable", + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Information pertaining to the (ultimate economic, not fiduciary) founder (individual(s) or entity/ies)" as TranslatedString, + labelField: "fullName", + name: "founders", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfDeath", + label: "Date of death" as TranslatedString, + help: "if deceased" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToRevoke", + required: true, + label: + "Does the founder have the right to revoke the foundation?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "If the foundation results from the restructuring of pre-existing foundation (re-settlement) or the merger of pre-existing foundations, the following information pertaining to the (actual) founder(s) of the pre-existing foundation(s) has to be given" as TranslatedString, + labelField: "fullName", + name: "preExistingFounders", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfDeath", + label: "Date of death" as TranslatedString, + help: "if deceased" as TranslatedString, + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Pertaining to the beneficiary/-ies at the time of the signing of this form" as TranslatedString, + labelField: "fullName", + name: "beneficiaryWhenSigning", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToClaim", + label: + "Has the beneficiary an actual right to claim distribution?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + { + type: "textArea", + props: { + label: + "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the founder) known at the time of the signing of this form" as TranslatedString, + name: "beneficiaryExtra", + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Information pertaining to further persons having the right to determine or nominate representatives (e.g.) members of the foundation board), if these representatives may dispose over the assets or have the right to change the distribution of the assets or the nomination of beneficiaries" as TranslatedString, + labelField: "fullName", + name: "withRightToNominate", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToClaim", + label: + "has the person the right to revoke the foundation?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + { + type: "textArea", + props: { + label: + "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the founder) known at the time of the signing of this form" as TranslatedString, + name: "beneficiaryExtra", + }, + }, + ], + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "signature", + label: "Signature" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_12.Form>, + ): FormState<Form902_12.Form> { + return { + founders: { + elements: (v.founders ?? []).map((f) => { + return { + rightToRevoke: { + hidden: v.foundation?.revocability !== "revocable", + }, + }; + }), + }, + withRightToNominate: { + elements: (v.withRightToNominate ?? []).map((f) => { + return { + rightToRevoke: { + hidden: v.foundation?.revocability !== "revocable", + }, + }; + }), + }, + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_12 { + interface Foundation { + name: string; + type: "discretionary" | "non-discretionary"; + revocability: "revocable" | "irrevocable"; + } + interface Person { + fullName: string; + address: string; + country: string; + dateOfBirth: AbsoluteTime; + nationality: string; + } + type WithRevoke<T> = { + rightToRevoke: "yes" | "no"; + } & T; + type WithClaim<T> = { + rightToClaim: "yes" | "no"; + } & T; + type WithDeath<T> = { + dateOfDeath: AbsoluteTime; + } & T; + + type Founder = WithRevoke<WithDeath<Person>>; + type Beneficiary = WithClaim<Person>; + + export interface Form extends Simplest.WithResolution { + contractingPartner: string; + knownAs: string; + boardMember: string; + foundation: Foundation; + founders: Array<Founder>; + preExistingFounders: Array<Founder>; + beneficiaryWhenSigning: Array<Beneficiary>; + beneficiaryExtra: Array<Beneficiary>; + withRightToNominate: Array<WithRevoke<Person>>; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_13e.ts b/packages/aml-backoffice-ui/src/forms/902_13e.ts new file mode 100644 index 000000000..63870f00a --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_13e.ts @@ -0,0 +1,527 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_13.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: "Declaration for trusts" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "contractingPartner", + label: "Contracting partner" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "knownAs", + label: + "The undersigned hereby declare(s) that as trustee or a member of highest supervisory body of an underlying company of a trust known as" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "trust.name", + label: + "Name and information pertaining to the trust" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "trust.type", + label: "Type of trust" as TranslatedString, + choices: [ + { + label: "Discretionary trust" as TranslatedString, + value: "discretionary", + }, + { + label: "Non-discretionary trust" as TranslatedString, + value: "non-discretionary", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + name: "trust.revocability", + label: "Revocability" as TranslatedString, + choices: [ + { + label: "Revocable foundation" as TranslatedString, + value: "revocable", + }, + { + label: "Irrevocable foundation" as TranslatedString, + value: "irrevocable", + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Information pertaining to the (ultimate economic, not fiduciary) settlor of the trust (individual(s) or entity/ies)" as TranslatedString, + labelField: "fullName", + name: "settlors", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfDeath", + label: "Date of death" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "if deceased. format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToRevoke", + required: true, + label: + "Does the founder have the right to revoke the trust?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "If the trust results from the restructuring of pre-existing trust (re-settlement) or the merger of pre-existing trusts, the following information pertaining to the (actual) settlor of the pre-existing trust(s) has to be given" as TranslatedString, + labelField: "fullName", + name: "preExistingSettlors", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfDeath", + label: "Date of death" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "if deceased. format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Pertaining to the beneficiary/-ies at the time of the signing of this form" as TranslatedString, + labelField: "fullName", + name: "beneficiaryWhenSigning", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToClaim", + label: + "Has the beneficiary an actual right to claim distribution?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + { + type: "textArea", + props: { + label: + "in addition to certain beneficiaries or if there is/are no defined beneficiary/ies pertaining to (a) group(s) of beneficiaries (e.g. descendants of the settlor) known at the time of the signing of this form" as TranslatedString, + name: "beneficiaryExtra", + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "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" as TranslatedString, + labelField: "asd", + name: "nothing", + fields: [], + }, + }, + + { + type: "array", + props: { + label: + "Information pertaining to the protectors" as TranslatedString, + labelField: "fullName", + name: "protectors", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToClaim", + label: + "Does the protector have the right to revoke the trust?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + ], + }, + }, + { + type: "array", + props: { + label: + "Information pertaining to further persons" as TranslatedString, + labelField: "fullName", + name: "furtherPersons", + fields: [ + { + type: "text", + props: { + name: "fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: + "Actual address of domicile/registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "country", + label: "Country" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "rightToClaim", + label: + "Has this further person the right to revoke the trust?" as TranslatedString, + choices: [ + { + label: "Yes" as TranslatedString, + value: "yes", + }, + { + label: "No" as TranslatedString, + value: "no", + }, + ], + }, + }, + ], + }, + }, + { + type: "date", + props: { + name: "when", + label: "Date" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "signature", + label: "Signature" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_13.Form>, + ): FormState<Form902_13.Form> { + return { + settlors: { + elements: (v.settlors ?? []).map((f) => { + return { + rightToRevoke: { + hidden: v.foundation?.revocability !== "revocable", + }, + }; + }), + }, + protectors: { + elements: (v.protectors ?? []).map((f) => { + return { + rightToRevoke: { + hidden: v.foundation?.revocability !== "revocable", + }, + }; + }), + }, + furtherPersons: { + elements: (v.furtherPersons ?? []).map((f) => { + return { + rightToRevoke: { + hidden: v.foundation?.revocability !== "revocable", + }, + }; + }), + }, + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_13 { + interface Foundation { + name: string; + type: "discretionary" | "non-discretionary"; + revocability: "revocable" | "irrevocable"; + } + interface Person { + fullName: string; + address: string; + country: string; + dateOfBirth: AbsoluteTime; + nationality: string; + } + type WithRevoke<T> = { + rightToRevoke: "yes" | "no"; + } & T; + type WithClaim<T> = { + rightToClaim: "yes" | "no"; + } & T; + type WithDeath<T> = { + dateOfDeath: AbsoluteTime; + } & T; + + type Founder = WithRevoke<WithDeath<Person>>; + type Beneficiary = WithClaim<Person>; + + export interface Form extends Simplest.WithResolution { + contractingPartner: string; + knownAs: string; + boardMember: string; + foundation: Foundation; + settlors: Array<Founder>; + preExistingSettlors: Array<Founder>; + beneficiaryWhenSigning: Array<Beneficiary>; + beneficiaryExtra: Array<Beneficiary>; + protectors: Array<WithRevoke<Person>>; + furtherPersons: Array<WithRevoke<Person>>; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_15e.ts b/packages/aml-backoffice-ui/src/forms/902_15e.ts new file mode 100644 index 000000000..19a16d3f2 --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_15e.ts @@ -0,0 +1,197 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_15.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: + "Information on life insurance policies with separately managed accounts/securities accounts" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "contractingPartner", + label: "Contracting partner" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "contractualRelationship", + label: + "Name or number of the contractual relationship between the contracting party and the financial intermediary" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "insurancePolicy", + label: "Insurance policy" as TranslatedString, + }, + }, + { + type: "caption", + props: { + label: + "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." as TranslatedString, + }, + }, + { + type: "caption", + props: { + label: + "In relation with the above insurance policy, the contracting partner gives the following further details" as TranslatedString, + }, + }, + { + type: "group", + props: { + before: "Policy holder" as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "holder.fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "holder.address", + label: + "Actual address of domicile/registered office (incl. country)" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "holder.dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "holder.nationality", + label: "Nationality" as TranslatedString, + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: + "Person actually (not in a fiduciary capacity) paying the premiums (to be filled in if not identical with point 1 above)" as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "premiumPayer.fullName", + label: + "Last name(s), first name(s)/entity" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "premiumPayer.address", + label: + "Actual address of domicile/registered office (incl. country)" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "premiumPayer.dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "premiumPayer.nationality", + label: "Nationality" as TranslatedString, + }, + }, + ], + }, + }, + { + type: "caption", + props: { + label: + "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" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "signature", + label: "Signature" as TranslatedString, + }, + }, + { + type: "caption", + props: { + label: + "It is a criminal offense to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_15.Form>, + ): FormState<Form902_15.Form> { + return { + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_15 { + interface Person { + fullName: string; + address: string; + dateOfBirth: AbsoluteTime; + nationality: string; + } + + export interface Form extends Simplest.WithResolution { + contractingPartner: string; + contractualRelationship: string; + insurancePolicy: string; + holder: Person; + premiumsPayer: Person; + signature: string; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_1e.ts b/packages/aml-backoffice-ui/src/forms/902_1e.ts new file mode 100644 index 000000000..654085443 --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_1e.ts @@ -0,0 +1,695 @@ +import { + AbsoluteTime, + AmountJson, + Amounts, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FlexibleForm, languageList } from "./index.js"; +import { FormState } from "../handlers/FormProvider.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { amlStateConverter } from "../pages/CaseDetails.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_1.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: "This form was completed by" as TranslatedString, + description: + "The customer has to be identified on entering into a permanent business relationship or on concluding a cash transaction, which meets the according threshold." as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "fullName", + label: "Full name" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + ], + }, + { + title: "Information on customer" as TranslatedString, + description: + "The customer is the person with whom the member concludes the contract with regard to the financial service provided (civil law). Does the member act as director of a domiciliary company, this domiciliary company is the customer." as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + name: "customerType", + label: "Type of customer" as TranslatedString, + required: true, + choices: [ + { + label: "Natural person" as TranslatedString, + value: "natural", + }, + { + label: "Legal entity" as TranslatedString, + value: "legal", + }, + ], + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.fullName", + label: "Full name" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.address", + label: "Residential address" as TranslatedString, + required: true, + }, + }, + { + type: "integer", + props: { + name: "naturalCustomer.telephone", + label: "Telephone" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.email", + label: "E-mail" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "naturalCustomer.dateOfBirth", + label: "Date of birth" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.nationality", + label: "Nationality" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.document", + label: "Identification document" as TranslatedString, + required: true, + }, + }, + { + type: "file", + props: { + name: "naturalCustomer.documentAttachment", + label: "Document attachment" as TranslatedString, + required: true, + maxBites: 2 * 1024 * 1024, + accept: ".png", + help: "Max size of 2 mega bytes" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.companyName", + label: "Company name" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.office", + label: "Registered office" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "naturalCustomer.companyDocument", + label: "Company identification document" as TranslatedString, + }, + }, + { + type: "file", + props: { + name: "naturalCustomer.companyDocumentAttachment", + label: "Document attachment" as TranslatedString, + required: true, + maxBites: 2 * 1024 * 1024, + accept: ".png", + help: "Max size of 2 mega bytes" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.companyName", + label: "Company name" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.domicile", + label: "Domicile" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.contactPerson", + label: "Contact person" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.telephone", + label: "Telephone" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.email", + label: "E-mail" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "legalCustomer.document", + label: "Identification document" as TranslatedString, + help: "Not older than 12 month" as TranslatedString, + }, + }, + { + type: "file", + props: { + name: "legalCustomer.documentAttachment", + label: "Document attachment" as TranslatedString, + required: true, + maxBites: 2 * 1024 * 1024, + accept: ".png", + help: "Max size of 2 mega bytes" as TranslatedString, + }, + }, + ], + }, + { + title: + "Information on the natural persons who establish the business relationship for legal entities and partnerships" as TranslatedString, + description: + "For legal entities and partnerships the identity of the natural persons who establish the business relationship must be verified." as TranslatedString, + fields: [ + { + type: "array", + props: { + name: "businessEstablisher", + label: "Persons" as TranslatedString, + required: true, + tooltip: "hola" as TranslatedString, + placeholder: "this is the placeholder" as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "fullName", + label: "Full name" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "address", + label: "Residential address" as TranslatedString, + required: true, + }, + }, + { + type: "date", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + required: true, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "typeOfAuthorization", + label: + "Type of authorization (signatory of representation)" as TranslatedString, + required: true, + }, + }, + { + type: "file", + props: { + name: "documentAttachment", + label: + "Identification document attachment" as TranslatedString, + required: true, + maxBites: 2 * 1024 * 1024, + accept: ".png", + help: "Max size of 2 mega bytes" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "powerOfAttorneyArrangements", + label: "Power of attorney arrangements" as TranslatedString, + required: true, + choices: [ + { + label: "CR extract" as TranslatedString, + value: "cr", + }, + { + label: "Mandate" as TranslatedString, + value: "mandate", + }, + { + label: "Other" as TranslatedString, + value: "other", + }, + ], + }, + }, + { + type: "text", + props: { + name: "powerOfAttorneyArrangementsOther", + label: "Power of attorney arrangements" as TranslatedString, + required: true, + }, + }, + ], + labelField: "fullName", + }, + }, + ], + }, + { + title: "Acceptance of business relationship" as TranslatedString, + fields: [ + { + type: "date", + props: { + name: "acceptance.when", + pattern: "dd/MM/yyyy", + label: "Date (conclusion of contract)" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + name: "acceptance.acceptedBy", + label: "Accepted by" as TranslatedString, + required: true, + choices: [ + { + label: "Face-to-face meeting with customer" as TranslatedString, + value: "face-to-face", + }, + { + label: + "Correspondence: authenticated copy of identification document obtained" as TranslatedString, + value: "correspondence-document", + }, + { + label: + "Correspondence: residential address validated" as TranslatedString, + value: "correspondence-address", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + name: "acceptance.typeOfCorrespondence", + label: "Type of correspondence service" as TranslatedString, + choices: [ + { + label: "to the customer" as TranslatedString, + value: "customer", + }, + { + label: "hold at bank" as TranslatedString, + value: "bank", + }, + { + label: "to the member" as TranslatedString, + value: "member", + }, + { + label: "to a third party" as TranslatedString, + value: "third-party", + }, + ], + }, + }, + { + type: "text", + props: { + name: "acceptance.thirdPartyFullName", + label: "Third party full name" as TranslatedString, + required: true, + }, + }, + { + type: "text", + props: { + name: "acceptance.thirdPartyAddress", + label: "Third party address" as TranslatedString, + required: true, + }, + }, + { + type: "selectMultiple", + props: { + name: "acceptance.language", + label: "Languages" as TranslatedString, + choices: languageList, + unique: true, + }, + }, + { + type: "textArea", + props: { + name: "acceptance.furtherInformation", + label: "Further information" as TranslatedString, + }, + }, + ], + }, + { + title: + "Information on the beneficial owner of the assets and/or controlling person" as TranslatedString, + description: + "Establishment of the beneficial owner of the assets and/or controlling person" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + name: "establishment", + label: "The customer is" as TranslatedString, + required: true, + choices: [ + { + label: + "a natural person and there are no doubts that this person is the sole beneficial owner of the assets" as TranslatedString, + value: "natural", + }, + { + label: + "a foundation (or a similar construct; incl. underlying companies)" as TranslatedString, + value: "foundation", + }, + { + label: + "a trust (incl. underlying companies)" as TranslatedString, + value: "trust", + }, + { + label: + "a life insurance policy with separately managed accounts/securities accounts" as TranslatedString, + value: "insurance-wrapper", + }, + { + label: "all other cases" as TranslatedString, + value: "other", + }, + ], + }, + }, + ], + }, + { + title: + "Evaluation with regard to embargo procedures/terrorism lists on establishing the business relationship" as TranslatedString, + description: + "Verification whether the customer, beneficial owners of the assets, controlling persons, authorized representatives or other involved persons are listed on an embargo/terrorism list (date of verification/result)" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "embargoEvaluation", + help: "The evaluation must be made at the beginning of the business relationship and has to be repeated in the case of permanent business relationship every time the according lists are updated." as TranslatedString, + label: "Evaluation" as TranslatedString, + }, + }, + ], + }, + { + title: + "In the case of cash transactions/occasional customers: Information on type and purpose of business relationship" as TranslatedString, + description: + "These details are only necessary for occasional customers, i.e. money exchange, money and asset transfer or other cash transactions provided that no customer profile (VQF doc. No. 902.5) is created" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + name: "cashTransactions.typeOfBusiness", + label: "Type of business relationship" as TranslatedString, + choices: [ + { + label: "Money exchange" as TranslatedString, + value: "money-exchange", + }, + { + label: "Money and asset transfer" as TranslatedString, + value: "money-and-asset-transfer", + }, + { + label: + "Other cash transactions. Specify below" as TranslatedString, + value: "other", + }, + ], + }, + }, + { + type: "text", + props: { + name: "cashTransactions.otherTypeOfBusiness", + required: true, + label: "Specify other cash transactions:" as TranslatedString, + }, + }, + { + type: "textArea", + props: { + name: "cashTransactions.purpose", + label: + "Purpose of the business relationship (purpose of service requested)" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_1.Form>, + ): FormState<Form902_1.Form> { + return { + fullName: { + disabled: true, + }, + when: { + disabled: true, + }, + businessEstablisher: { + elements: (v.businessEstablisher ?? []).map((be) => { + return { + powerOfAttorneyArrangementsOther: { + hidden: be.powerOfAttorneyArrangements !== "other", + }, + }; + }), + }, + acceptance: { + thirdPartyFullName: { + hidden: v.acceptance?.typeOfCorrespondence !== "third-party", + }, + thirdPartyAddress: { + hidden: v.acceptance?.typeOfCorrespondence !== "third-party", + }, + }, + cashTransactions: { + otherTypeOfBusiness: { + hidden: v.cashTransactions?.typeOfBusiness !== "other", + }, + }, + naturalCustomer: { + fullName: { + hidden: v.customerType !== "natural", + }, + address: { + hidden: v.customerType !== "natural", + }, + telephone: { + hidden: v.customerType !== "natural", + }, + email: { + hidden: v.customerType !== "natural", + }, + dateOfBirth: { + hidden: v.customerType !== "natural", + }, + nationality: { + hidden: v.customerType !== "natural", + }, + document: { + hidden: v.customerType !== "natural", + }, + companyName: { + hidden: v.customerType !== "natural", + }, + office: { + hidden: v.customerType !== "natural", + }, + companyDocument: { + hidden: v.customerType !== "natural", + }, + companyDocumentAttachment: { + hidden: v.customerType !== "natural", + }, + documentAttachment: { + hidden: v.customerType !== "natural", + }, + }, + legalCustomer: { + companyName: { + hidden: v.customerType !== "legal", + }, + contactPerson: { + hidden: v.customerType !== "legal", + }, + document: { + hidden: v.customerType !== "legal", + }, + domicile: { + hidden: v.customerType !== "legal", + }, + email: { + hidden: v.customerType !== "legal", + }, + telephone: { + hidden: v.customerType !== "legal", + }, + documentAttachment: { + hidden: v.customerType !== "legal", + }, + }, + }; + }, +}); + +namespace Form902_1 { + interface LegalEntityCustomer { + companyName: string; + domicile: string; + contactPerson: string; + telephone: string; + email: string; + document: string; + documentAttachment: string; + } + interface NaturalCustomer { + fullName: string; + address: string; + telephone: string; + email: string; + dateOfBirth: AbsoluteTime; + nationality: string; + document: string; + documentAttachment: string; + companyName: string; + office: string; + companyDocument: string; + companyDocumentAttachment: string; + } + + interface Person { + fullName: string; + address: string; + dateOfBirth: AbsoluteTime; + nationality: string; + typeOfAuthorization: string; + document: string; + documentAttachment: string; + powerOfAttorneyArrangements: "cr" | "mandate" | "other"; + powerOfAttorneyArrangementsOther: string; + } + + interface Acceptance { + when: AbsoluteTime; + acceptedBy: "face-to-face" | "authenticated-copy"; + typeOfCorrespondence: string; + language: string[]; + furtherInformation: string; + thirdPartyFullName: string; + thirdPartyAddress: string; + } + + interface BeneficialOwner { + establishment: + | "natural-person" + | "foundation" + | "trust" + | "insurance-wrapper" + | "other"; + } + + interface CashTransactions { + typeOfBusiness: "money-exchange" | "money-and-asset-transfer" | "other"; + otherTypeOfBusiness: string; + purpose: string; + } + + export interface Form extends Simplest.WithResolution { + fullName: string; + customerType: "natural" | "legal"; + naturalCustomer: NaturalCustomer; + legalCustomer: LegalEntityCustomer; + businessEstablisher: Array<Person>; + acceptance: Acceptance; + beneficialOwner: BeneficialOwner; + embargoEvaluation: string; + cashTransactions: CashTransactions; + // enclosures: Enclosures; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_4e.ts b/packages/aml-backoffice-ui/src/forms/902_4e.ts new file mode 100644 index 000000000..f77a2f63a --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_4e.ts @@ -0,0 +1,822 @@ +import { + AbsoluteTime, + AmountJson, + Amounts, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { ArrowRightIcon } from "@heroicons/react/24/outline"; +import { h as create } from "preact"; +import { ChevronRightIcon } from "@heroicons/react/24/solid"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { amlStateConverter } from "../pages/CaseDetails.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_4.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: "Risk Profile AMLA" as TranslatedString, + description: + "Evaluation of business relationship with increased risk and definition of criteria for transaction monitoring." as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "The member performs additional clarifications if the business relationship or the transaction is classified as increased risk (Art. 56 SRO Regulations)" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "text", + props: { + name: "customer", + label: "Customer" as TranslatedString, + help: "Pursuant identification form (VQF doc. Nr. 902.1) numeral 1" as TranslatedString, + }, + }, + ], + }, + { + title: "This form was completed by" as TranslatedString, + fields: [ + { + type: "text", + props: { + label: "Full name" as TranslatedString, + name: "fullName", + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + ], + }, + { + title: + "Evaluation of politically exposed persons (PEP-Check)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members for every business relationship" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "choiceStacked", + props: { + label: "Foreign PEP" as TranslatedString, + tooltip: + "Definition see Art. 7 lit. g numeral 1 SRO Regulations" as TranslatedString, + help: "Is the customer, the beneficial owner or the controlling person or authorized representative a foreign PEP or closely related to such a person?" as TranslatedString, + name: "pep.foreign", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: "Yes" as TranslatedString, + description: + "The business relationship is compulsory classified as increased risk" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: + "Domestic PEP and PEP of International Organizations" as TranslatedString, + tooltip: + "Definition see Art. 7 lit. g numeral 2 and 3 SRO Regulations " as TranslatedString, + help: "Is the customer, the beneficial owner or the controlling person or authorized representative a domestic PEP or PEP in International Organizations or closely related to such a person?" as TranslatedString, + name: "pep.domestic", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: + "Yes, but NOT risk criterion pursuant to numeral 3 subsequently increased." as TranslatedString, + value: "yes-but-no-risk", + }, + { + label: + "Yes, AND a risk criterion pursuant to numeral 3 subsequently increased." as TranslatedString, + description: + "Classification of the business relationship as increased risk is compulsory" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "pep.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: + 'Evaluation "high risk" or non-cooperative country' as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members for every business relationship" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "choiceStacked", + props: { + label: '"High risk" or non-cooperative country' as TranslatedString, + help: 'Is the customer, the beneficial owner or the controlling person or authorized representative in a country considered by the FATF "high risk" or non-cooperative and for which FATF requires increased diligence?' as TranslatedString, + name: "highRisk.evaluation", + choices: [ + { + label: "No" as TranslatedString, + value: "no", + }, + { + label: "Yes" as TranslatedString, + description: + "considered as business relationship with increased risk" as TranslatedString, + value: "yes", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "highRisk.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: "Evaluation of business relationship risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "This evaluation has to be completed by all members who have in total more than 20 customers for every business relationship. At least two risk categories have to be chosen and assessed" as TranslatedString, + before: create(ArrowRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "group", + props: { + before: "a) Country risk (nationality)" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: "Domicile/residential address" as TranslatedString, + name: "evaluation.nationality.address", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + { + label: "Controlling person" as TranslatedString, + value: "controlling", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Nationality" as TranslatedString, + name: "evaluation.nationality.nationality", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.nationality.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "b) Country risk (business activity)" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: "Place of business activity" as TranslatedString, + name: "evaluation.business.place", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.business.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "c) Country risk (payments)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Country of origin and destination of frequent payments (if known)" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.payments.risk", + choices: [ + { + label: + "Risk 0 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "low", + }, + { + label: + "Risk 1 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "medium", + }, + { + label: + "Risk 2 acc. to VQF country list (VQF doc. no. 902.4.1)" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "d) Industry risk" as TranslatedString, + fields: [ + { + type: "choiceStacked", + props: { + label: + "Nature of customer's business activity" as TranslatedString, + name: "evaluation.industry.nature", + choices: [ + { + label: "Customer" as TranslatedString, + value: "customer", + }, + { + label: + "Beneficial owner of the assets" as TranslatedString, + value: "owner", + }, + ], + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.payments.risk", + choices: [ + { + label: + "Clearly defined, transparent, easily comprehensible business activity well known to the member" as TranslatedString, + value: "low", + }, + { + label: + "Business activity with a high level of cash transactions" as TranslatedString, + value: "medium-cash", + }, + { + label: + "Business activity not well known to the member" as TranslatedString, + value: "medium-unknown", + }, + { + label: + "Trade in munitions/arms, raw gem stones/diamonds, jewelry, international trade in exotic animals, casino and lottery business, trade in erotic wares" as TranslatedString, + value: "high-restricted", + }, + { + label: + "Member has no personal knowledge of the customer's industry" as TranslatedString, + value: "high-unknown", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "e) Contact risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Types of contact to the customer/ beneficial owner of the assets" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.contact.risk", + choices: [ + { + label: + "Personal acquaintance between member and customer/beneficial owner of the assets over several years (at least 2) prior to entering into the business relationship" as TranslatedString, + value: "low", + }, + { + label: + "The customer/beneficial owner was not personally known to the member for several years (at least 2) prior to entering into the business relationship; however (a) no business was entered into in the absence of the customer/beneficial owner, or (b) the customer was at least introduced/brokered by a trusted third party" as TranslatedString, + value: "medium", + }, + { + label: + "The customer/beneficial owner was not personally known to the member and business was entered into in the absence of the former (relationship by correspondence) and the customer was not introduced/brokered by a trusted third party" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "f) Product risk" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Nature of services and products requested by the customer" as TranslatedString, + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.product.risk", + choices: [ + { + label: + "Easy to understand, transparent services and products whose financial background is easy to comprehend and verify" as TranslatedString, + value: "low", + }, + { + label: + "More sophisticated services/products whose financial background is not readily easy to comprehend and verify" as TranslatedString, + value: "medium", + }, + { + label: + "Main focus on offshore business (especially: relationships with domiciliary companies or other such offshore organisations)" as TranslatedString, + value: "high-offshore", + }, + { + label: + "Complex structures in particular by using a domiciliary company with fiduciary shareholders in a non-transparent jurisdiction, without comprehensible reason or for the purpose of short-term asset placement" as TranslatedString, + value: "high-structure", + }, + { + label: + "The customer or beneficial owner of the assets has a large number of accounts with pass-through transactions (pass-through accounts)" as TranslatedString, + value: "high-accounts", + }, + { + label: + "Complex services/products whose financial background can’t be understood or verified with considerable effort" as TranslatedString, + value: "high-service", + }, + { + label: + "Frequent transactions with increased risks" as TranslatedString, + value: "high-freq-tx", + }, + ], + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: "g) Criteria defined by the member" as TranslatedString, + fields: [ + { + type: "text", + props: { + label: "Criteria definition" as TranslatedString, + name: "evaluation.custom.definition", + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk level" as TranslatedString, + name: "evaluation.custom.risk", + choices: [ + { + label: "Low" as TranslatedString, + value: "low", + }, + { + label: "Medium" as TranslatedString, + value: "medium", + }, + { + label: "High" as TranslatedString, + value: "high", + }, + ], + }, + }, + ], + }, + }, + { + type: "caption", + props: { + label: + "Overall assessment of the business relationship" as TranslatedString, + }, + }, + { + type: "group", + props: { + before: + "A business relationship is classified as increased risk if:" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Business relationship with PEP pursuant to numeral 1 (no exception possible)" as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "caption", + props: { + label: + 'Relationship with a person from a "high risk" or non-cooperative country according to numeral 2 (no exceptions possible)' as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + { + type: "caption", + props: { + label: + "Min. one criterion pursuant to numeral 3 was assessed with risk 2 or min. two criteria pursuant to numeral 3 were assessed with risk 1 (exception: justification by the member below why the business relationship overall does not have to be classified as increased risk despite the fact that individual risk criteria are increased)" as TranslatedString, + before: create(ChevronRightIcon, { class: "h-6 w-6" }), + }, + }, + ], + }, + }, + { + type: "textArea", + props: { + label: + "Justification for differing risk assessment" as TranslatedString, + name: "evaluation.overall.justification", + }, + }, + { + type: "choiceStacked", + props: { + label: "Risk classified" as TranslatedString, + name: "evaluation.overall.risk", + choices: [ + { + label: + "Business relationship _without_ increased risk" as TranslatedString, + value: "without", + }, + { + label: + "Business relationship __with__ increased risk" as TranslatedString, + value: "with", + }, + ], + }, + }, + { + type: "date", + props: { + label: + "The decision of the Senior executive body on the acceptance of a business relationship with a PEP was obtained on" as TranslatedString, + name: "evaluation.when", + pattern: "dd/MM/yyyy", + placeholder: "dd/MM/yyyy" as TranslatedString, + }, + }, + ], + }, + { + title: + "Criteria for identification of increased risk transactions (transaction monitoring)" as TranslatedString, + fields: [ + { + type: "group", + props: { + before: "Criteria" as TranslatedString, + fields: [ + { + type: "caption", + props: { + label: + "Classification as as increased risk is compulsory if" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + "Transactions for which assets with an equivalent value of CHF 100'000.- or more are physically introduced at the beginning of the business relationship, either at once or in a staggered manner" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + 'Money and asset transfers ("money transfer") whereby a single transaction or multiple transactions which appear to be related reach or exceed the amount of CHF 5,000.-' as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-6 h-6" }), + label: + 'Payments from or to a country that is considered to be "high risk" or non-cooperative by the FATF and for which increased diligence is required' as TranslatedString, + }, + }, + ], + }, + }, + { + type: "group", + props: { + before: + "Additional criteria defined by the member" as TranslatedString, + fields: [ + { + type: "caption", + props: { + before: create(ArrowRightIcon, { class: "w-6 h-6" }), + label: + "All members have to define min. 1 additional criterion for every business relationship to identify unusual transactions" as TranslatedString, + }, + }, + { + type: "textArea", + props: { + label: "Description" as TranslatedString, + name: "criteria.additional", + }, + }, + { + type: "group", + props: { + before: + "Possible criteria (Art. 59 para. 2 SRO Regulations)" as TranslatedString, + fields: [ + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "the amount of inflowing and outflowing assets" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "type, volume and frequency of transactions usual to the business relationship (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "type, volume and frequency of transactions usual to comparable business relationships (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + "description of expected transaction patterns which the client notify the member of (considerable variance would be unusual)" as TranslatedString, + }, + }, + { + type: "caption", + props: { + before: create(ChevronRightIcon, { class: "w-4 h-4" }), + label: + 'The country of origin or destination of payments, especially in the case of payments from or to a country considered by the FATF as "high risk" or non-cooperative' as TranslatedString, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_4.Form>, + ): FormState<Form902_4.Form> { + return { + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_4 { + export interface Form extends Simplest.WithResolution { + customer: string; + fullName: string; + pep: { + foreign: "yes" | "no"; + domestic: "yes" | "no" | "yes-but-no-risk"; + when: AbsoluteTime; + }; + highRisk: { + evaluation: "yes" | "no"; + when: AbsoluteTime; + }; + evaluation: { + nationality: { + address: "customer" | "owner" | "controlling"; + nationality: "customer" | "owner"; + risk: "low" | "medium" | "high"; + }; + business: { + place: "customer" | "owner"; + risk: "low" | "medium" | "high"; + }; + payments: { + risk: "low" | "medium" | "high"; + }; + industry: { + nature: "customer" | "owner"; + risk: + | "low" + | "medium-cash" + | "medium-unknown" + | "high-restricted" + | "high-unknown"; + }; + contact: { + risk: "low" | "medium" | "high"; + }; + product: { + risk: + | "low" + | "medium" + | "high-offshore" + | "high-structure" + | "high-accounts" + | "high-service" + | "high-freq-tx"; + }; + custom: { + definition: string; + risk: "low" | "medium" | "high"; + }; + overall: { + justification: string; + risk: "with" | "without"; + }; + when: AbsoluteTime; + }; + criteria: { + additional: string; + }; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_5e.ts b/packages/aml-backoffice-ui/src/forms/902_5e.ts new file mode 100644 index 000000000..bd27b7a7f --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_5e.ts @@ -0,0 +1,281 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm, currencyList } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_5.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: "Customer Profile" as TranslatedString, + description: + "The information below has to refer to the persons from whom the assets originate ultimately (e.g. beneficial owner of the assets, founder/creator of a trust or foundation). Is the customer an operational legal entity or partnership the information may refer to the entity itself (not to the controlling person), unless the entity holds the assets in trust for a third party." as TranslatedString, + fields: [ + { + type: "text", + props: { + name: "customer", + label: "Customer" as TranslatedString, + help: "Pursuant Identification Form (VQF doc. No. 902.1) numeral 1" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "fullName", + label: "Full name" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + ], + }, + { + title: "Business activity" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + label: "Profession, business activities" as TranslatedString, + name: "businessActivity", + help: "former, current, potentially planned" as TranslatedString, + }, + }, + ], + }, + { + title: "Financial circumstances" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + label: "Income and assets, liabilities" as TranslatedString, + name: "financial", + help: "estimated" as TranslatedString, + }, + }, + ], + }, + { + title: "Origin of the deposited assets involved" as TranslatedString, + fields: [ + { + type: "text", + props: { + label: "Nature" as TranslatedString, + name: "originOfAssets.nature", + help: "nature of the involved assets" as TranslatedString, + }, + }, + { + type: "selectOne", + props: { + name: "originOfAssets.currency", + label: "Currency" as TranslatedString, + choices: currencyList, + }, + }, + { + type: "integer", + props: { + label: "Amount" as TranslatedString, + name: "originOfAssets.amount", + }, + }, + { + type: "choiceStacked", + props: { + label: "Category" as TranslatedString, + name: "originOfAssets.category", + choices: [ + { + label: "Savings" as TranslatedString, + value: "savings", + }, + { + label: "Own business operations" as TranslatedString, + value: "own-business", + }, + { + label: "Inheritance" as TranslatedString, + value: "inheritance", + }, + { + label: "Other, what?" as TranslatedString, + value: "other", + }, + ], + }, + }, + { + type: "text", + props: { + label: "Other category" as TranslatedString, + name: "originOfAssets.categoryOther", + required: true, + }, + }, + { + type: "textArea", + props: { + label: + "Detailed description of the origins/economical background of the assets involved in the business relationship" as TranslatedString, + name: "originOfAssets.details", + }, + }, + ], + }, + { + title: + "Nature and purpose of the business relationship" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + label: "Purpose of the business relationship" as TranslatedString, + name: "nature.purpose", + help: "nature of the involved assets" as TranslatedString, + }, + }, + { + type: "textArea", + props: { + label: + "Information on the planned development of the business relationship and the assets" as TranslatedString, + name: "nature.plan", + }, + }, + { + type: "textArea", + props: { + label: + "Especially in the case of cash or money and asset transfer transactions with regular customers: Details on usual business volume, Information on the beneficiaries, (Full name, address, bank account)" as TranslatedString, + name: "nature.cashOrMoneyTransfer", + }, + }, + ], + }, + { + title: "Relationship with third parties" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + label: + "Relation of the customer to the beneficial owner involved in the business relationship" as TranslatedString, + name: "relations.beneficialOwners", + }, + }, + { + type: "textArea", + props: { + label: + "Relation of the customer to the controlling persons involved in the business relationship" as TranslatedString, + name: "relations.controllingPersons", + }, + }, + { + type: "textArea", + props: { + label: + "Relation of the customer to the authorized signatories involved in the business relationship" as TranslatedString, + name: "relations.authorizedSignatories", + }, + }, + { + type: "textArea", + props: { + label: + "Relation of the customer to other persons involved in the business relationship" as TranslatedString, + name: "relations.otherPersons", + }, + }, + { + type: "textArea", + props: { + label: "Relation to other AMLA-Files" as TranslatedString, + name: "relations.withOtherAmlaFiles", + }, + }, + { + type: "textArea", + props: { + label: "Introducer / agents / references" as TranslatedString, + name: "relations.references", + }, + }, + ], + }, + { + title: "Further information" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + label: "Other relevant information" as TranslatedString, + name: "furtherInformation", + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_5.Form>, + ): FormState<Form902_5.Form> { + return { + when: { + disabled: true, + }, + originOfAssets: { + categoryOther: { + hidden: v.originOfAssets?.category !== "other", + }, + }, + }; + }, +}); + +namespace Form902_5 { + export interface Form extends Simplest.WithResolution { + customer: string; + fullName: string; + businessActivity: string; + financial: string; + originOfAssets: { + nature: string; + currency: string; + amount: number; + category: "savings" | "own-business" | "inheritance" | "other"; + categoryOther: string; + details: string; + }; + nature: { + purpose: string; + plan: string; + cashOrMoneyTransfer: string; + }; + relations: { + beneficialOwners: string; + controllingPersons: string; + authorizedSignatories: string; + otherPersons: string; + withOtherAmlaFiles: string; + references: string; + }; + furtherInformation: string; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/902_9e.ts b/packages/aml-backoffice-ui/src/forms/902_9e.ts new file mode 100644 index 000000000..e79597bfb --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/902_9e.ts @@ -0,0 +1,138 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { AmlState } from "../types.js"; +import { Simplest, resolutionSection } from "./simplest.js"; + +export const v1 = (current: State): FlexibleForm<Form902_9.Form> => ({ + versionId: "2023-05-15", + design: [ + { + title: + "Declaration of identity of the beneficial owner" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "contractingPartner", + label: "Contracting partner" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "when", + pattern: "dd/MM/yyyy", + label: "Date" as TranslatedString, + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "caption", + props: { + label: + "The contracting partner hereby declares that the person(s) listed below is/are the beneficial owner(s) of the assets involved in the business relationship. If the contracting partner is also the sole beneficial owner of the assets, the contracting partner's detail must be set out below" as TranslatedString, + }, + }, + { + type: "array", + props: { + label: "Persons" as TranslatedString, + labelField: "surname", + name: "persons", + fields: [ + { + type: "text", + props: { + name: "surname", + label: "Surname(s)" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "firstName", + label: "First name(s)" as TranslatedString, + }, + }, + { + type: "date", + props: { + name: "dateOfBirth", + label: "Date of birth" as TranslatedString, + pattern: "dd/MM/yyyy", + help: "format 'dd/MM/yyyy'" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "nationality", + label: "Nationality" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "address", + label: "Actual address of domicile" as TranslatedString, + }, + }, + ], + }, + }, + { + type: "caption", + props: { + label: + "The contracting partner hereby undertakes to inform automatically of any changes to the information contained herein" as TranslatedString, + }, + }, + { + type: "text", + props: { + name: "signature", + label: "Signature" as TranslatedString, + }, + }, + { + type: "caption", + props: { + label: + "It is a criminal offense to deliberately provide false information on this form (article 251 of the Swiss Criminal Code, document forgery)" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Form902_9.Form>, + ): FormState<Form902_9.Form> { + return { + when: { + disabled: true, + }, + }; + }, +}); + +namespace Form902_9 { + interface Person { + surname: string; + firstName: string; + dateOfBirth: AbsoluteTime; + nationality: string; + address: string; + } + export interface Form extends Simplest.WithResolution { + contractingPartner: string; + persons: Person; + signature: string; + } +} diff --git a/packages/aml-backoffice-ui/src/forms/index.ts b/packages/aml-backoffice-ui/src/forms/index.ts new file mode 100644 index 000000000..c236bbaa3 --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/index.ts @@ -0,0 +1,146 @@ +import { TranslatedString } from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { DoubleColumnForm } from "../handlers/forms.js"; + +export interface FlexibleForm<T extends object> { + versionId: string; + design: DoubleColumnForm; + behavior: (form: Partial<T>) => FormState<T>; +} + +export const languageList = [ + { + label: "Mandarin Chinese" as TranslatedString, + value: "cmn", + }, + { + label: "Spanish" as TranslatedString, + value: "spa", + }, + { + label: "English" as TranslatedString, + value: "eng", + }, + { + label: "Hindi" as TranslatedString, + value: "hin", + }, + { + label: "Portuguese" as TranslatedString, + value: "por", + }, + { + label: "Bengali" as TranslatedString, + value: "ben", + }, + { + label: "Russian" as TranslatedString, + value: "rus", + }, + { + label: "Japanese" as TranslatedString, + value: "jpn", + }, + { + label: "Yue" as TranslatedString, + value: "yue", + }, + { + label: "Vietnamese" as TranslatedString, + value: "vie", + }, + { + label: "Turkish" as TranslatedString, + value: "tur", + }, + { + label: "Wu" as TranslatedString, + value: "wuu", + }, + { + label: "Marathi" as TranslatedString, + value: "mar", + }, + { + label: "Telugu" as TranslatedString, + value: "ten", + }, + { + label: "Korean" as TranslatedString, + value: "kor", + }, + { + label: "French" as TranslatedString, + value: "fra", + }, + { + label: "Tamil" as TranslatedString, + value: "tam", + }, + { + label: "Egyptian Arabic" as TranslatedString, + value: "arz", + }, + { + label: "Standard German" as TranslatedString, + value: "deu", + }, + { + label: "Urdu" as TranslatedString, + value: "urd", + }, + { + label: "Javanese" as TranslatedString, + value: "jav", + }, + { + label: "Punjabi" as TranslatedString, + value: "pan", + }, + { + label: "Italian" as TranslatedString, + value: "ita", + }, + { + label: "Gujarati" as TranslatedString, + value: "guj", + }, + { + label: "Iranian Persian" as TranslatedString, + value: "pes", + }, + { + label: "Bhojpuri" as TranslatedString, + value: "bho", + }, + { + label: "Hausa" as TranslatedString, + value: "hau", + }, +]; +export const currencyList = [ + { + label: "United States dollar" as TranslatedString, + value: "usd", + }, + { + label: "Euro" as TranslatedString, + value: "eur", + }, + { + label: "Swiss franc" as TranslatedString, + value: "chf", + }, + { + label: "Argentine peso" as TranslatedString, + value: "ars", + }, + { + label: "Mexican peso" as TranslatedString, + value: "mxn", + }, + { + label: "Brazilian real" as TranslatedString, + value: "brl", + }, +]; diff --git a/packages/aml-backoffice-ui/src/forms/simplest.ts b/packages/aml-backoffice-ui/src/forms/simplest.ts new file mode 100644 index 000000000..7eda03fef --- /dev/null +++ b/packages/aml-backoffice-ui/src/forms/simplest.ts @@ -0,0 +1,103 @@ +import { + AbsoluteTime, + AmountJson, + Amounts, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { FormState } from "../handlers/FormProvider.js"; +import { FlexibleForm } from "./index.js"; +import { AmlState } from "../types.js"; +import { amlStateConverter } from "../pages/CaseDetails.js"; +import { State } from "../pages/AntiMoneyLaunderingForm.js"; +import { DoubleColumnFormSection, UIFormField } from "../handlers/forms.js"; + +export const v1 = (current: State): FlexibleForm<Simplest.Form> => ({ + versionId: "2023-05-25", + design: [ + { + title: "Simple form" as TranslatedString, + fields: [ + { + type: "textArea", + props: { + name: "comment", + label: "Comments" as TranslatedString, + }, + }, + ], + }, + resolutionSection(current), + ], + behavior: function formBehavior( + v: Partial<Simplest.Form>, + ): FormState<Simplest.Form> { + return { + when: { + disabled: true, + }, + threshold: { + disabled: v.state === AmlState.frozen, + }, + }; + }, +}); + +export namespace Simplest { + export interface WithResolution { + when: AbsoluteTime; + threshold: AmountJson; + state: AmlState; + } + export interface Form extends WithResolution { + comment: string; + } +} + +export function resolutionSection(current: State): DoubleColumnFormSection { + return { + title: "Resolution" as TranslatedString, + description: `Current state is ${amlStateConverter.toStringUI( + current.state, + )} and threshold at ${Amounts.stringifyValue( + current.threshold, + )}` as TranslatedString, + fields: [ + { + type: "date", + props: { + name: "when", + label: "Decision Time" as TranslatedString, + }, + }, + { + type: "choiceHorizontal", + props: { + name: "state", + label: "New state" as TranslatedString, + converter: amlStateConverter, + choices: [ + { + value: AmlState.frozen, + label: "Frozen" as TranslatedString, + }, + { + value: AmlState.pending, + label: "Pending" as TranslatedString, + }, + { + value: AmlState.normal, + label: "Normal" as TranslatedString, + }, + ], + }, + }, + { + type: "amount", + props: { + name: "threshold", + label: "New threshold" as TranslatedString, + }, + }, + ], + }; +} |