gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-backoffice] branch master updated: show refund uri


From: gnunet
Subject: [taler-merchant-backoffice] branch master updated: show refund uri
Date: Tue, 10 May 2022 16:24:01 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository merchant-backoffice.

The following commit(s) were added to refs/heads/master by this push:
     new db548d9  show refund uri
db548d9 is described below

commit db548d9a8a69f085561d029a3782bb0dcee64d09
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue May 10 11:23:16 2022 -0300

    show refund uri
---
 .../paths/instance/orders/details/DetailPage.tsx   | 26 +++++--
 .../src/paths/instance/orders/list/Table.tsx       | 84 ++++++++++++----------
 packages/merchant-backoffice/src/schemas/index.ts  |  9 ---
 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()

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]