/*
This file is part of GNU Taler
(C) 2022-2024 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
import {
AbsoluteTime,
AmountJson,
TranslatedString,
} from "@gnu-taler/taler-util";
import {
DefaultForm,
FlexibleForm,
UIFormField,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { format } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { amlStateConverter } from "../utils/converter.js";
import { AmlExchangeBackend } from "../utils/types.js";
import { AmlEvent } from "./CaseDetails.js";
export function ShowConsolidated({
history,
until,
}: {
history: AmlEvent[];
until: AbsoluteTime;
}): VNode {
const { i18n } = useTranslationContext();
const cons = getConsolidated(history, until);
const form: FlexibleForm = {
behavior: (form) => {
return {
aml: {
threshold: {
hidden: !form.aml,
},
since: {
hidden: !form.aml,
},
state: {
hidden: !form.aml,
},
},
};
},
design: [
{
title: i18n.str`AML`,
fields: [
{
type: "amount",
props: {
label: i18n.str`Threshold`,
name: "aml.threshold",
},
},
{
type: "choiceHorizontal",
props: {
label: i18n.str`State`,
name: "aml.state",
converter: amlStateConverter,
choices: [
{
label: i18n.str`Frozen`,
value: AmlExchangeBackend.AmlState.frozen,
},
{
label: i18n.str`Pending`,
value: AmlExchangeBackend.AmlState.pending,
},
{
label: i18n.str`Normal`,
value: AmlExchangeBackend.AmlState.normal,
},
],
},
},
],
},
Object.entries(cons.kyc).length > 0
? {
title: i18n.str`KYC`,
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 (
Consolidated information{" "}
{until.t_ms === "never"
? ""
: `after ${format(until.t_ms, "dd MMMM yyyy")}`}
{}}
/>
);
}
interface Consolidated {
aml: {
state: AmlExchangeBackend.AmlState;
threshold: AmountJson;
since: AbsoluteTime;
};
kyc: {
[field: string]: {
value: unknown;
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) => {
const value = (cur.values as Record)[field];
prev.kyc[field] = {
value,
provider: cur.provider,
since: cur.when,
};
});
break;
}
}
return prev;
}, initial);
}