diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts')
-rw-r--r-- | packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts | 152 |
1 files changed, 84 insertions, 68 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts index b9257215f..1a92c4073 100644 --- a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts @@ -14,14 +14,15 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Amounts } from "@gnu-taler/taler-util"; +import { Amounts, PreparePayResult } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { AmountFieldHandler, TextFieldHandler } from "../../mui/handlers.js"; +import { RecursiveState } from "../../utils/index.js"; import { Props, State } from "./index.js"; export function useComponentState({ @@ -29,43 +30,32 @@ export function useComponentState({ cancel, goToWalletManualWithdraw, onSuccess, -}: Props): State { +}: Props): RecursiveState<State> { const api = useBackendContext(); const { i18n } = useTranslationContext(); const { safely } = useAlertContext(); - const url = talerTemplateUri ? new URL(talerTemplateUri) : undefined; - - const amountParam = !url - ? undefined - : url.searchParams.get("amount") ?? undefined; - const summaryParam = !url - ? undefined - : url.searchParams.get("summary") ?? undefined; + // const url = talerTemplateUri ? new URL(talerTemplateUri) : undefined; + // const parsedAmount = !amountParam ? undefined : Amounts.parse(amountParam); + // const currency = parsedAmount ? parsedAmount.currency : amountParam; - const parsedAmount = !amountParam ? undefined : Amounts.parse(amountParam); - const currency = parsedAmount ? parsedAmount.currency : amountParam; + // const initialAmount = + // parsedAmount ?? (currency ? Amounts.zeroOfCurrency(currency) : undefined); - const initialAmount = - parsedAmount ?? (currency ? Amounts.zeroOfCurrency(currency) : undefined); - const [amount, setAmount] = useState(initialAmount); - const [summary, setSummary] = useState(summaryParam); const [newOrder, setNewOrder] = useState(""); const hook = useAsyncAsHook(async () => { if (!talerTemplateUri) throw Error("ERROR_NO-URI-FOR-PAYMENT-TEMPLATE"); - let payStatus; - if (!amountParam && !summaryParam) { - payStatus = await api.wallet.call( - WalletApiOperation.PreparePayForTemplate, - { - talerPayTemplateUri: talerTemplateUri, - templateParams: {}, - }, - ); + const templateP = await api.wallet.call( + WalletApiOperation.CheckPayForTemplate, { talerPayTemplateUri: talerTemplateUri }, + ); + const requireMoreInfo = !templateP.templateDetails.template_contract.amount || !templateP.templateDetails.template_contract.summary; + let payStatus: PreparePayResult | undefined = undefined; + if (!requireMoreInfo) { + payStatus = await api.wallet.call(WalletApiOperation.PreparePayForTemplate, { talerPayTemplateUri: talerTemplateUri }); } const balance = await api.wallet.call(WalletApiOperation.GetBalances, {}); - return { payStatus, balance, uri: talerTemplateUri }; + return { payStatus, balance, uri: talerTemplateUri, templateP }; }, []); if (!hook) { @@ -108,63 +98,89 @@ export function useComponentState({ }; } - async function createOrder() { - try { - const templateParams: Record<string, string> = {}; - if (amount) { - templateParams["amount"] = Amounts.stringify(amount); + return () => { + const cfg = hook.response.templateP.templateDetails.template_contract; + const def = hook.response.templateP.templateDetails.editable_defaults; + + const fixedAmount = cfg.amount !== undefined ? Amounts.parseOrThrow(cfg.amount) : undefined; + const fixedSummary = cfg.summary !== undefined ? cfg.summary : undefined; + + const defaultAmount = def?.amount !== undefined ? Amounts.parseOrThrow(def.amount) : undefined; + const defaultSummary = def?.summary !== undefined ? def.summary : undefined; + + const zero = fixedAmount ? Amounts.zeroOfAmount(fixedAmount) : + cfg.currency !== undefined ? Amounts.zeroOfCurrency(cfg.currency) : + defaultAmount !== undefined ? Amounts.zeroOfAmount(defaultAmount) : + def?.currency !== undefined ? Amounts.zeroOfCurrency(def.currency) : + Amounts.zeroOfCurrency(hook.response.templateP.supportedCurrencies[0]); + + const [amount, setAmount] = useState(defaultAmount ?? zero); + const [summary, setSummary] = useState(defaultSummary ?? ""); + + async function createOrder() { + try { + const templateParams: Record<string, string> = {}; + if (amount && !fixedAmount) { + templateParams["amount"] = Amounts.stringify(amount); + } + if (summary && !fixedSummary) { + templateParams["summary"] = summary; + } + const payStatus = await api.wallet.call( + WalletApiOperation.PreparePayForTemplate, + { + talerPayTemplateUri: talerTemplateUri, + templateParams, + }, + ); + setNewOrder(payStatus.talerUri!); + } catch (e) { + console.error(e); } - if (summary) { - templateParams["summary"] = summary; - } - const payStatus = await api.wallet.call( - WalletApiOperation.PreparePayForTemplate, - { - talerPayTemplateUri: talerTemplateUri, - templateParams, - }, - ); - setNewOrder(payStatus.talerUri!); - } catch (e) {} - } - const errors = undefinedIfEmpty({ - amount: amount && Amounts.isZero(amount) ? i18n.str`required` : undefined, - summary: summary !== undefined && !summary ? i18n.str`required` : undefined, - }); - return { - status: "fill-template", - error: undefined, - currency: currency!, //currency is always not null - amount: - amount !== undefined - ? ({ + } + + const errors = undefinedIfEmpty({ + amount: fixedAmount !== undefined ? undefined : amount && Amounts.isZero(amount) ? i18n.str`required` : undefined, + summary: fixedSummary !== undefined ? undefined : summary !== undefined && !summary ? i18n.str`required` : undefined, + }); + return { + status: "fill-template", + error: undefined, + minAge: cfg.minimum_age ?? 0, + amount: + fixedAmount === undefined + ? ({ onInput: (a) => { setAmount(a); }, value: amount, error: errors?.amount, } as AmountFieldHandler) - : undefined, - summary: - summary !== undefined - ? ({ + : undefined, + summary: + fixedSummary === undefined + ? ({ onInput: (t) => { setSummary(t); }, value: summary, error: errors?.summary, } as TextFieldHandler) - : undefined, - onCreate: { - onClick: errors - ? undefined - : safely("create order for pay template", createOrder), - }, - }; + : undefined, + onCreate: { + onClick: errors + ? undefined + : safely("create order for pay template", createOrder), + }, + }; + } + } function undefinedIfEmpty<T extends object>(obj: T): T | undefined { - return Object.keys(obj).some((k) => (obj as any)[k] !== undefined) + return Object.keys(obj).some( + (k) => (obj as Record<string, unknown>)[k] !== undefined, + ) ? obj : undefined; } |