aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx216
1 files changed, 113 insertions, 103 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
index 5ff76e37a..498ea83e3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
@@ -1,6 +1,6 @@
/*
This file is part of GNU Taler
- (C) 2021-2023 Taler Systems S.A.
+ (C) 2021-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
@@ -19,8 +19,15 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { AmountJson, Amounts, stringifyRefundUri } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import {
+ AmountJson,
+ Amounts,
+ TalerMerchantApi,
+ stringifyRefundUri,
+} from "@gnu-taler/taler-util";
+import {
+ useTranslationContext
+} from "@gnu-taler/web-util/browser";
import { format, formatDistance } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
@@ -33,28 +40,30 @@ import { InputGroup } from "../../../../components/form/InputGroup.js";
import { InputLocation } from "../../../../components/form/InputLocation.js";
import { TextField } from "../../../../components/form/TextField.js";
import { ProductList } from "../../../../components/product/ProductList.js";
-import { useBackendContext } from "../../../../context/backend.js";
-import { MerchantBackend } from "../../../../declaration.js";
-import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";
+import { useSessionContext } from "../../../../context/session.js";
+import {
+ datetimeFormatForSettings,
+ usePreference,
+} from "../../../../hooks/preference.js";
import { mergeRefunds } from "../../../../utils/amount.js";
import { RefundModal } from "../list/Table.js";
import { Event, Timeline } from "./Timeline.js";
-type Entity = MerchantBackend.Orders.MerchantOrderStatusResponse;
-type CT = MerchantBackend.ContractTerms;
+type Entity = TalerMerchantApi.MerchantOrderStatusResponse;
+type CT = TalerMerchantApi.ContractTerms;
interface Props {
onBack: () => void;
selected: Entity;
id: string;
- onRefund: (id: string, value: MerchantBackend.Orders.RefundRequest) => void;
+ onRefund: (id: string, value: TalerMerchantApi.RefundRequest) => void;
}
-type Paid = MerchantBackend.Orders.CheckPaymentPaidResponse & {
+type Paid = TalerMerchantApi.CheckPaymentPaidResponse & {
refund_taken: string;
};
-type Unpaid = MerchantBackend.Orders.CheckPaymentUnpaidResponse;
-type Claimed = MerchantBackend.Orders.CheckPaymentClaimedResponse;
+type Unpaid = TalerMerchantApi.CheckPaymentUnpaidResponse;
+type Claimed = TalerMerchantApi.CheckPaymentClaimedResponse;
function ContractTerms({ value }: { value: CT }) {
const { i18n } = useTranslationContext();
@@ -149,8 +158,12 @@ function ClaimedPage({
order,
}: {
id: string;
- order: MerchantBackend.Orders.CheckPaymentClaimedResponse;
+ order: TalerMerchantApi.CheckPaymentClaimedResponse;
}) {
+ const now = new Date();
+ const refundable =
+ order.contract_terms.refund_deadline.t_s !== "never" &&
+ now.getTime() < order.contract_terms.refund_deadline.t_s * 1000;
const events: Event[] = [];
if (order.contract_terms.timestamp.t_s !== "never") {
events.push({
@@ -166,20 +179,20 @@ function ClaimedPage({
type: "deadline",
});
}
- if (order.contract_terms.refund_deadline.t_s !== "never") {
+ if (order.contract_terms.refund_deadline.t_s !== "never" && refundable) {
events.push({
when: new Date(order.contract_terms.refund_deadline.t_s * 1000),
description: "refund deadline",
type: "deadline",
});
}
- if (order.contract_terms.wire_transfer_deadline.t_s !== "never") {
- events.push({
- when: new Date(order.contract_terms.wire_transfer_deadline.t_s * 1000),
- description: "wire deadline",
- type: "deadline",
- });
- }
+ // if (order.contract_terms.wire_transfer_deadline.t_s !== "never") {
+ // events.push({
+ // when: new Date(order.contract_terms.wire_transfer_deadline.t_s * 1000),
+ // description: "wire deadline",
+ // type: "deadline",
+ // });
+ // }
if (
order.contract_terms.delivery_date &&
order.contract_terms.delivery_date.t_s !== "never"
@@ -193,7 +206,7 @@ function ClaimedPage({
const [value, valueHandler] = useState<Partial<Claimed>>(order);
const { i18n } = useTranslationContext();
- const [settings] = useSettings()
+ const [settings] = usePreference();
return (
<div>
@@ -237,10 +250,14 @@ function ClaimedPage({
<b>
<i18n.Translate>claimed at</i18n.Translate>:
</b>{" "}
- {format(
- new Date(order.contract_terms.timestamp.t_s * 1000),
- datetimeFormatForSettings(settings)
- )}
+ {order.contract_terms.timestamp.t_s === "never"
+ ? "never"
+ : format(
+ new Date(
+ order.contract_terms.timestamp.t_s * 1000,
+ ),
+ datetimeFormatForSettings(settings),
+ )}
</p>
</div>
</div>
@@ -311,25 +328,16 @@ function PaidPage({
onRefund,
}: {
id: string;
- order: MerchantBackend.Orders.CheckPaymentPaidResponse;
+ order: TalerMerchantApi.CheckPaymentPaidResponse;
onRefund: (id: string) => void;
}) {
+ const now = new Date();
+ const refundable =
+ order.contract_terms.refund_deadline.t_s !== "never" &&
+ now.getTime() < order.contract_terms.refund_deadline.t_s * 1000;
+
const events: Event[] = [];
- if (order.contract_terms.timestamp.t_s !== "never") {
- events.push({
- when: new Date(order.contract_terms.timestamp.t_s * 1000),
- description: "order created",
- type: "start",
- });
- }
- if (order.contract_terms.pay_deadline.t_s !== "never") {
- events.push({
- when: new Date(order.contract_terms.pay_deadline.t_s * 1000),
- description: "pay deadline",
- type: "deadline",
- });
- }
- if (order.contract_terms.refund_deadline.t_s !== "never") {
+ if (order.contract_terms.refund_deadline.t_s !== "never" && refundable) {
events.push({
when: new Date(order.contract_terms.refund_deadline.t_s * 1000),
description: "refund deadline",
@@ -363,66 +371,71 @@ function PaidPage({
});
}
});
- if (order.wire_details && order.wire_details.length) {
- if (order.wire_details.length > 1) {
- let last: MerchantBackend.Orders.TransactionWireTransfer | null = null;
- let first: MerchantBackend.Orders.TransactionWireTransfer | null = null;
- let total: AmountJson | null = null;
-
- order.wire_details.forEach((w) => {
- if (last === null || last.execution_time.t_s < w.execution_time.t_s) {
- last = w;
- }
- if (first === null || first.execution_time.t_s > w.execution_time.t_s) {
- first = w;
- }
- total =
- total === null
- ? Amounts.parseOrThrow(w.amount)
- : Amounts.add(total, Amounts.parseOrThrow(w.amount)).amount;
- });
- const last_time = last!.execution_time.t_s;
- if (last_time !== "never") {
- events.push({
- when: new Date(last_time * 1000),
- description: `wired ${Amounts.stringify(total!)}`,
- type: "wired-range",
+ const ra = !order.refunded ? undefined : Amounts.parse(order.refund_amount);
+ const am = Amounts.parseOrThrow(order.contract_terms.amount);
+ if (ra && Amounts.cmp(ra, am) === 1) {
+ if (order.wire_details && order.wire_details.length) {
+ if (order.wire_details.length > 1) {
+ let last: TalerMerchantApi.TransactionWireTransfer | null = null;
+ let first: TalerMerchantApi.TransactionWireTransfer | null = null;
+ let total: AmountJson | null = null;
+
+ order.wire_details.forEach((w) => {
+ if (last === null || last.execution_time.t_s < w.execution_time.t_s) {
+ last = w;
+ }
+ if (
+ first === null ||
+ first.execution_time.t_s > w.execution_time.t_s
+ ) {
+ first = w;
+ }
+ total =
+ total === null
+ ? Amounts.parseOrThrow(w.amount)
+ : Amounts.add(total, Amounts.parseOrThrow(w.amount)).amount;
});
- }
- const first_time = first!.execution_time.t_s;
- if (first_time !== "never") {
- events.push({
- when: new Date(first_time * 1000),
- description: `wire transfer started...`,
- type: "wired-range",
- });
- }
- } else {
- order.wire_details.forEach((e) => {
- if (e.execution_time.t_s !== "never") {
+ const last_time = last!.execution_time.t_s;
+ if (last_time !== "never") {
events.push({
- when: new Date(e.execution_time.t_s * 1000),
- description: `wired ${e.amount}`,
- type: "wired",
+ when: new Date(last_time * 1000),
+ description: `wired ${Amounts.stringify(total!)}`,
+ type: "wired-range",
});
}
- });
+ const first_time = first!.execution_time.t_s;
+ if (first_time !== "never") {
+ events.push({
+ when: new Date(first_time * 1000),
+ description: `wire transfer started...`,
+ type: "wired-range",
+ });
+ }
+ } else {
+ order.wire_details.forEach((e) => {
+ if (e.execution_time.t_s !== "never") {
+ events.push({
+ when: new Date(e.execution_time.t_s * 1000),
+ description: `wired ${e.amount}`,
+ type: "wired",
+ });
+ }
+ });
+ }
}
}
- const now = new Date()
const nextEvent = events.find((e) => {
- return e.when.getTime() > now.getTime()
- })
+ return e.when.getTime() > now.getTime();
+ });
const [value, valueHandler] = useState<Partial<Paid>>(order);
- const { url: backendURL } = useBackendContext()
+ const { state } = useSessionContext();
+
const refundurl = stringifyRefundUri({
- merchantBaseUrl: backendURL,
- orderId: order.contract_terms.order_id
- })
- const refundable =
- new Date().getTime() < order.contract_terms.refund_deadline.t_s * 1000;
+ merchantBaseUrl: state.backendUrl.href,
+ orderId: order.contract_terms.order_id,
+ });
const { i18n } = useTranslationContext();
const amount = Amounts.parseOrThrow(order.contract_terms.amount);
@@ -503,15 +516,16 @@ function PaidPage({
textOverflow: "ellipsis",
}}
>
- {nextEvent &&
+ {nextEvent && (
<p>
- <i18n.Translate>Next event in </i18n.Translate> {formatDistance(
+ <i18n.Translate>Next event in </i18n.Translate>{" "}
+ {formatDistance(
nextEvent.when,
new Date(),
// "yyyy/MM/dd HH:mm:ss",
)}
</p>
- }
+ )}
</div>
</div>
</div>
@@ -607,11 +621,11 @@ function UnpaidPage({
order,
}: {
id: string;
- order: MerchantBackend.Orders.CheckPaymentUnpaidResponse;
+ order: TalerMerchantApi.CheckPaymentUnpaidResponse;
}) {
const [value, valueHandler] = useState<Partial<Unpaid>>(order);
const { i18n } = useTranslationContext();
- const [settings] = useSettings()
+ const [settings] = usePreference();
return (
<div>
<section class="hero is-hero-bar">
@@ -659,9 +673,9 @@ function UnpaidPage({
{order.creation_time.t_s === "never"
? "never"
: format(
- new Date(order.creation_time.t_s * 1000),
- datetimeFormatForSettings(settings)
- )}
+ new Date(order.creation_time.t_s * 1000),
+ datetimeFormatForSettings(settings),
+ )}
</p>
</div>
</div>
@@ -764,7 +778,3 @@ export function DetailPage({ id, selected, onRefund, onBack }: Props): VNode {
</Fragment>
);
}
-
-async function copyToClipboard(text: string) {
- return navigator.clipboard.writeText(text);
-}