aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx')
-rw-r--r--packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx204
1 files changed, 204 insertions, 0 deletions
diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
new file mode 100644
index 000000000..0efc68632
--- /dev/null
+++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
@@ -0,0 +1,204 @@
+import { Fragment, VNode, h } from "preact";
+import { useState } from "preact/hooks";
+import { NiceForm } from "../NiceForm.js";
+import { FlexibleForm } from "../forms/index.js";
+import { UIFormField } from "../handlers/forms.js";
+import { AmlEvent } from "./CaseDetails.js";
+import { AmlExchangeBackend } from "../types.js";
+import { AbsoluteTime, AmountJson, TranslatedString } from "@gnu-taler/taler-util";
+import { format } from "date-fns";
+
+export function ShowConsolidated({
+ history,
+ until,
+}: {
+ history: AmlEvent[];
+ until: AbsoluteTime;
+}): VNode {
+ const cons = getConsolidated(history, until);
+
+ const form: FlexibleForm<Consolidated> = {
+ versionId: "1",
+ behavior: (form) => {
+ return {
+ aml: {
+ threshold: {
+ hidden: !form.aml
+ },
+ since: {
+ hidden: !form.aml
+ },
+ state: {
+ hidden: !form.aml
+ }
+ }
+ };
+ },
+ design: [
+ {
+ title: "AML" as TranslatedString,
+ fields: [
+ {
+ type: "amount",
+ props: {
+ label: "Threshold" as TranslatedString,
+ name: "aml.threshold",
+ },
+ },
+ {
+ type: "choiceHorizontal",
+ props: {
+ label: "State" as TranslatedString,
+ name: "aml.state",
+ converter: amlStateConverter,
+ choices: [
+ {
+ label: "Frozen" as TranslatedString,
+ value: AmlExchangeBackend.AmlState.frozen,
+ },
+ {
+ label: "Pending" as TranslatedString,
+ value: AmlExchangeBackend.AmlState.pending,
+ },
+ {
+ label: "Normal" as TranslatedString,
+ value: AmlExchangeBackend.AmlState.normal,
+ },
+ ],
+ },
+ },
+ ],
+ },
+ Object.entries(cons.kyc).length > 0
+ ? {
+ title: "KYC" as TranslatedString,
+ fields: Object.entries(cons.kyc).map(([key, field]) => {
+ const result: UIFormField = {
+ type: "text",
+ props: {
+ label: key as TranslatedString,
+ name: `kyc.${key}.value`,
+ help: `${field.provider} since ${field.since.t_ms === "never"
+ ? "never"
+ : format(field.since.t_ms, "dd/MM/yyyy")
+ }` as TranslatedString,
+ },
+ };
+ return result;
+ }),
+ }
+ : undefined,
+ ],
+ };
+ return (
+ <Fragment>
+ <h1 class="text-base font-semibold leading-7 text-black">
+ Consolidated information
+ {until.t_ms === "never"
+ ? ""
+ : `after ${format(until.t_ms, "dd MMMM yyyy")}` }
+ </h1>
+ <NiceForm
+ key={`${String(Date.now())}`}
+ form={form}
+ initial={cons}
+ onUpdate={() => { }}
+ />
+ </Fragment>
+ );
+}
+
+interface Consolidated {
+ aml: {
+ state: AmlExchangeBackend.AmlState;
+ threshold: AmountJson;
+ since: AbsoluteTime;
+ };
+ kyc: {
+ [field: string]: {
+ value: any;
+ provider: string;
+ since: AbsoluteTime;
+ };
+ };
+}
+
+function getConsolidated(
+ history: AmlEvent[],
+ when: AbsoluteTime,
+): Consolidated {
+ const initial: Consolidated = {
+ aml: {
+ state: AmlExchangeBackend.AmlState.normal,
+ threshold: {
+ currency: "ARS",
+ value: 1000,
+ fraction: 0,
+ },
+ since: AbsoluteTime.never()
+ },
+ kyc: {},
+ };
+ return history.reduce((prev, cur) => {
+ if (AbsoluteTime.cmp(when, cur.when) < 0) {
+ return prev;
+ }
+ switch (cur.type) {
+ case "kyc-expiration": {
+ cur.fields.forEach((field) => {
+ delete prev.kyc[field];
+ });
+ break;
+ }
+ case "aml-form": {
+ prev.aml = {
+ since: cur.when,
+ state: cur.state,
+ threshold: cur.threshold
+ }
+ break;
+ }
+ case "kyc-collection": {
+ Object.keys(cur.values).forEach((field) => {
+ prev.kyc[field] = {
+ value: (cur.values as any)[field],
+ provider: cur.provider,
+ since: cur.when,
+ };
+ });
+ break;
+ }
+ }
+ return prev;
+ }, initial);
+}
+
+export const amlStateConverter = {
+ toStringUI: stringifyAmlState,
+ fromStringUI: parseAmlState,
+};
+
+function stringifyAmlState(s: AmlExchangeBackend.AmlState | undefined): string {
+ if (s === undefined) return "";
+ switch (s) {
+ case AmlExchangeBackend.AmlState.normal:
+ return "normal";
+ case AmlExchangeBackend.AmlState.pending:
+ return "pending";
+ case AmlExchangeBackend.AmlState.frozen:
+ return "frozen";
+ }
+}
+
+function parseAmlState(s: string | undefined): AmlExchangeBackend.AmlState {
+ switch (s) {
+ case "normal":
+ return AmlExchangeBackend.AmlState.normal;
+ case "pending":
+ return AmlExchangeBackend.AmlState.pending;
+ case "frozen":
+ return AmlExchangeBackend.AmlState.frozen;
+ default:
+ throw Error(`unknown AML state: ${s}`);
+ }
+}