summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-05-10 11:23:16 -0300
committerSebastian <sebasjm@gmail.com>2022-05-10 11:23:53 -0300
commitdb548d9a8a69f085561d029a3782bb0dcee64d09 (patch)
tree07cbfd9bb6bfd9142125ffb5b2f62596e45bd391 /packages
parent9aabcf8e9c9ab1ca01f477dade290f7d304b5e82 (diff)
downloadmerchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.tar.gz
merchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.tar.bz2
merchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.zip
show refund uri
Diffstat (limited to 'packages')
-rw-r--r--packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx26
-rw-r--r--packages/merchant-backoffice/src/paths/instance/orders/list/Table.tsx84
-rw-r--r--packages/merchant-backoffice/src/schemas/index.ts9
3 files changed, 68 insertions, 51 deletions
diff --git a/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx b/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx
index 6947a6b..9671bfd 100644
--- a/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx
+++ b/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx
@@ -32,6 +32,7 @@ import { InputGroup } from "../../../../components/form/InputGroup";
import { InputLocation } from "../../../../components/form/InputLocation";
import { TextField } from "../../../../components/form/TextField";
import { ProductList } from "../../../../components/product/ProductList";
+import { useBackendContext } from "../../../../context/backend";
import { MerchantBackend } from "../../../../declaration";
import { Translate, useTranslator } from "../../../../i18n";
import { mergeRefunds } from "../../../../utils/amount";
@@ -417,7 +418,10 @@ function PaidPage({
}
const [value, valueHandler] = useState<Partial<Paid>>(order);
-
+ const { url } = useBackendContext();
+ const refundHost = url.replace(/.*:\/\//, ""); // remove protocol part
+ const proto = url.startsWith("http://") ? "taler+http" : "taler";
+ const refundurl = `${proto}://refund/${refundHost}/${order.contract_terms.order_id}/`;
const refundable =
new Date().getTime() < order.contract_terms.refund_deadline.t_s * 1000;
const i18n = useTranslator();
@@ -557,6 +561,16 @@ function PaidPage({
{order.order_status_url}
</a>
</TextField>
+ {order.refunded && (
+ <TextField<Paid>
+ name="order_status_url"
+ label={i18n`Refund URI`}
+ >
+ <a target="_blank" rel="noreferrer" href={refundurl}>
+ {refundurl}
+ </a>
+ </TextField>
+ )}
</FormProvider>
</div>
</div>
@@ -676,11 +690,11 @@ function UnpaidPage({
readonly
label={i18n`Order status URL`}
/>
- <Input<Unpaid>
- name="taler_pay_uri"
- readonly
- label={i18n`Payment URI`}
- />
+ <TextField<Unpaid> name="taler_pay_uri" label={i18n`Payment URI`}>
+ <a target="_blank" rel="noreferrer" href={value.taler_pay_uri}>
+ {value.taler_pay_uri}
+ </a>
+ </TextField>
</FormProvider>
</div>
<div class="column" />
diff --git a/packages/merchant-backoffice/src/paths/instance/orders/list/Table.tsx b/packages/merchant-backoffice/src/paths/instance/orders/list/Table.tsx
index 6b41200..60d5fae 100644
--- a/packages/merchant-backoffice/src/paths/instance/orders/list/Table.tsx
+++ b/packages/merchant-backoffice/src/paths/instance/orders/list/Table.tsx
@@ -19,25 +19,23 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
+import { Amounts } from "@gnu-taler/taler-util";
import { format } from "date-fns";
import { h, VNode } from "preact";
import { StateUpdater, useState } from "preact/hooks";
import {
- FormProvider,
FormErrors,
+ FormProvider,
} from "../../../../components/form/FormProvider";
import { Input } from "../../../../components/form/Input";
import { InputCurrency } from "../../../../components/form/InputCurrency";
import { InputGroup } from "../../../../components/form/InputGroup";
import { InputSelector } from "../../../../components/form/InputSelector";
import { ConfirmModal } from "../../../../components/modal";
+import { useConfigContext } from "../../../../context/config";
import { MerchantBackend, WithId } from "../../../../declaration";
import { Translate, useTranslator } from "../../../../i18n";
-import { RefundSchema } from "../../../../schemas";
import { mergeRefunds } from "../../../../utils/amount";
-import { Amounts } from "@gnu-taler/taler-util";
-import { useConfigContext } from "../../../../context/config";
-import * as yup from "yup";
type Entity = MerchantBackend.Orders.OrderHistoryEntry & WithId;
interface Props {
@@ -259,30 +257,7 @@ export function RefundModal({
type State = { mainReason?: string; description?: string; refund?: string };
const [form, setValue] = useState<State>({});
const i18n = useTranslator();
- const [errors, setErrors] = useState<FormErrors<State>>({});
-
- const validateAndConfirm = () => {
- try {
- RefundSchema.validateSync(form, { abortEarly: false });
- if (!form.refund) return;
- onConfirm({
- refund: form.refund,
- reason: `${form.mainReason}: ${form.description}`,
- });
- } catch (err) {
- if (err instanceof yup.ValidationError) {
- const errors = err.inner as any[];
- const pathMessages = errors.reduce(
- (prev, cur) =>
- !cur.path ? prev : { ...prev, [cur.path]: cur.message },
- {}
- );
- setErrors(pathMessages);
- } else {
- console.log(err);
- }
- }
- };
+ // const [errors, setErrors] = useState<FormErrors<State>>({});
const refunds = (
order.order_status === "paid" ? order.refund_details : []
@@ -306,22 +281,59 @@ export function RefundModal({
: orderPrice;
const isRefundable = Amounts.isNonZero(totalRefundable);
+ const duplicatedText = i18n`duplicated`;
+
+ const errors: FormErrors<State> = {
+ mainReason: !form.mainReason ? i18n`required` : undefined,
+ description:
+ !form.description && form.mainReason !== duplicatedText
+ ? i18n`required`
+ : undefined,
+ refund: !form.refund
+ ? i18n`required`
+ : !Amounts.parse(form.refund)
+ ? i18n`invalid format`
+ : Amounts.cmp(totalRefundable, Amounts.parse(form.refund)!) === -1
+ ? i18n`this value exceed the refundable amount`
+ : undefined,
+ };
+ const hasErrors = Object.keys(errors).some(
+ (k) => (errors as any)[k] !== undefined
+ );
+
+ const validateAndConfirm = () => {
+ try {
+ if (!form.refund) return;
+ onConfirm({
+ refund: Amounts.stringify(
+ Amounts.add(Amounts.parse(form.refund)!, totalRefunded).amount
+ ),
+ reason:
+ form.description === undefined
+ ? form.mainReason || ""
+ : `${form.mainReason}: ${form.description}`,
+ });
+ } catch (err) {
+ console.log(err);
+ }
+ };
+
//FIXME: parameters in the translation
return (
<ConfirmModal
description="refund"
danger
active
+ disabled={!isRefundable || hasErrors}
onCancel={onCancel}
onConfirm={validateAndConfirm}
>
{refunds.length > 0 && (
<div class="columns">
- <div class="column is-2" />
- <div class="column is-8">
+ <div class="column is-12">
<InputGroup
name="asd"
- label={`${totalRefunded} was already refunded`}
+ label={`${Amounts.stringify(totalRefunded)} was already refunded`}
>
<table class="table is-fullwidth">
<thead>
@@ -358,7 +370,6 @@ export function RefundModal({
</table>
</InputGroup>
</div>
- <div class="column is-2" />
</div>
)}
@@ -380,19 +391,20 @@ export function RefundModal({
name="mainReason"
label={i18n`Reason`}
values={[
- i18n`duplicated`,
+ i18n`Choose one...`,
+ duplicatedText,
i18n`requested by the customer`,
i18n`other`,
]}
tooltip={i18n`why this order is being refunded`}
/>
- {form.mainReason && (
+ {form.mainReason && form.mainReason !== duplicatedText ? (
<Input<State>
label={i18n`Description`}
name="description"
tooltip={i18n`more information to give context`}
/>
- )}
+ ) : undefined}
</FormProvider>
)}
</ConfirmModal>
diff --git a/packages/merchant-backoffice/src/schemas/index.ts b/packages/merchant-backoffice/src/schemas/index.ts
index a1cd597..6901293 100644
--- a/packages/merchant-backoffice/src/schemas/index.ts
+++ b/packages/merchant-backoffice/src/schemas/index.ts
@@ -113,15 +113,6 @@ export const InstanceSchema = yup.object().shape({
export const InstanceUpdateSchema = InstanceSchema.clone().omit(['id']);
export const InstanceCreateSchema = InstanceSchema.clone();
-export const RefundSchema = yup.object().shape({
- mainReason: yup.string().required(),
- description: yup.string().required(),
- refund: yup.string()
- .required()
- .test('amount', 'the amount is not valid', currencyWithAmountIsValid)
- .test('amount_positive', 'the amount is not valid', currencyGreaterThan0),
-})
-
export const AuthorizeTipSchema = yup.object().shape({
justification: yup.string().required(),
amount: yup.string()