diff options
author | Sebastian <sebasjm@gmail.com> | 2022-05-10 11:23:16 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-05-10 11:23:53 -0300 |
commit | db548d9a8a69f085561d029a3782bb0dcee64d09 (patch) | |
tree | 07cbfd9bb6bfd9142125ffb5b2f62596e45bd391 /packages | |
parent | 9aabcf8e9c9ab1ca01f477dade290f7d304b5e82 (diff) | |
download | merchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.tar.gz merchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.tar.bz2 merchant-backoffice-db548d9a8a69f085561d029a3782bb0dcee64d09.zip |
show refund uri
Diffstat (limited to 'packages')
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() |