gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: order config using relative t


From: gnunet
Subject: [taler-wallet-core] branch master updated: order config using relative time
Date: Mon, 08 Jan 2024 18:34:51 +0100

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

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new b0610d245 order config using relative time
b0610d245 is described below

commit b0610d24571593909cd6683b340fa266de046e31
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Jan 8 14:24:07 2024 -0300

    order config using relative time
---
 .../src/components/form/InputDuration.tsx          | 126 ++++++++-------
 .../src/components/picker/DurationPicker.tsx       |   2 +-
 .../merchant-backoffice-ui/src/declaration.d.ts    |   7 +-
 .../src/paths/admin/create/CreatePage.tsx          | 116 +++++++-------
 .../paths/instance/orders/create/CreatePage.tsx    | 178 ++++++++++-----------
 .../src/paths/instance/update/UpdatePage.tsx       |  73 +++------
 6 files changed, 240 insertions(+), 262 deletions(-)

diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
index ef4df1df4..8b6b5636d 100644
--- a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
+++ b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
@@ -20,16 +20,19 @@
  */
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { formatDuration, intervalToDuration } from "date-fns";
-import { h, VNode } from "preact";
+import { ComponentChildren, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { SimpleModal } from "../modal/index.js";
 import { DurationPicker } from "../picker/DurationPicker.js";
 import { InputProps, useField } from "./useField.js";
+import { Duration } from "@gnu-taler/taler-util";
 
 export interface Props<T> extends InputProps<T> {
   expand?: boolean;
   readonly?: boolean;
   withForever?: boolean;
+  side?: ComponentChildren;
+  withoutClear?: boolean;
 }
 
 export function InputDuration<T>({
@@ -41,19 +44,22 @@ export function InputDuration<T>({
   help,
   readonly,
   withForever,
+  withoutClear,
+  side,
 }: Props<keyof T>): VNode {
   const [opened, setOpened] = useState(false);
   const { i18n } = useTranslationContext();
 
-  const { error, required, value, onChange } = useField<T>(name);
+  const { error, required, value: anyValue, onChange } = useField<T>(name);
   let strValue = "";
+  const value: Duration = anyValue
   if (!value) {
     strValue = "";
-  } else if (value.d_us === "forever") {
+  } else if (value.d_ms === "forever") {
     strValue = i18n.str`forever`;
   } else {
     strValue = formatDuration(
-      intervalToDuration({ start: 0, end: value.d_us / 1000 }),
+      intervalToDuration({ start: 0, end: value.d_ms }),
       {
         locale: {
           formatDistance: (name, value) => {
@@ -97,72 +103,80 @@ export function InputDuration<T>({
           )}
         </label>
       </div>
-      <div class="field-body is-flex-grow-3">
-        <div class="field">
-          <div class="field has-addons">
-            <p class={expand ? "control is-expanded " : "control "}>
-              <input
-                class="input"
-                type="text"
-                readonly
-                value={strValue}
-                placeholder={placeholder}
+
+      <div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <div class="field has-addons">
+              <p class={expand ? "control is-expanded " : "control "}>
+                <input
+                  class="input"
+                  type="text"
+                  readonly
+                  value={strValue}
+                  placeholder={placeholder}
+                  onClick={() => {
+                    if (!readonly) setOpened(true);
+                  }}
+                />
+                {required && (
+                  <span class="icon has-text-danger is-right">
+                    <i class="mdi mdi-alert" />
+                  </span>
+                )}
+              </p>
+              <div
+                class="control"
                 onClick={() => {
                   if (!readonly) setOpened(true);
                 }}
-              />
-              {required && (
-                <span class="icon has-text-danger is-right">
-                  <i class="mdi mdi-alert" />
-                </span>
-              )}
-              {help}
-            </p>
-            <div
-              class="control"
-              onClick={() => {
-                if (!readonly) setOpened(true);
-              }}
-            >
-              <a class="button is-static">
-                <span class="icon">
-                  <i class="mdi mdi-clock" />
-                </span>
-              </a>
+              >
+                <a class="button is-static">
+                  <span class="icon">
+                    <i class="mdi mdi-clock" />
+                  </span>
+                </a>
+              </div>
             </div>
+            {error && <p class="help is-danger">{error}</p>}
           </div>
-          {error && <p class="help is-danger">{error}</p>}
+          {withForever && (
+            <span data-tooltip={i18n.str`change value to never`}>
+              <button
+                class="button is-info mr-3"
+                onClick={() => onChange({ d_ms: "forever" } as any)}
+              >
+                <i18n.Translate>forever</i18n.Translate>
+              </button>
+            </span>
+          )}
+          {!readonly && !withoutClear && (
+            <span data-tooltip={i18n.str`change value to empty`}>
+              <button
+                class="button is-info "
+                onClick={() => onChange(undefined as any)}
+              >
+                <i18n.Translate>clear</i18n.Translate>
+              </button>
+            </span>
+          )}
+          {side}
         </div>
-        {withForever && (
-          <span data-tooltip={i18n.str`change value to never`}>
-            <button
-              class="button is-info mr-3"
-              onClick={() => onChange({ d_us: "forever" } as any)}
-            >
-              <i18n.Translate>forever</i18n.Translate>
-            </button>
-          </span>
-        )}
-        {!readonly && (
-          <span data-tooltip={i18n.str`change value to empty`}>
-            <button
-              class="button is-info "
-              onClick={() => onChange(undefined as any)}
-            >
-              <i18n.Translate>clear</i18n.Translate>
-            </button>
-          </span>
-        )}
+        <span>
+          {help}
+        </span>
       </div>
+
+
       {opened && (
         <SimpleModal onCancel={() => setOpened(false)}>
           <DurationPicker
             days
             hours
             minutes
-            value={!value || value.d_us === "forever" ? 0 : value.d_us}
+            value={!value || value.d_ms === "forever" ? 0 : value.d_ms}
             onChange={(v) => {
-              onChange({ d_us: v } as any);
+              onChange({ d_ms: v } as any);
             }}
           />
         </SimpleModal>
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
index 0968b0a17..ba003cce5 100644
--- a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
+++ b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
@@ -42,7 +42,7 @@ export function DurationPicker({
   onChange,
   value,
 }: Props): VNode {
-  const ss = 1000 * 1000;
+  const ss = 1000;
   const ms = ss * 60;
   const hs = ms * 60;
   const ds = hs * 24;
diff --git a/packages/merchant-backoffice-ui/src/declaration.d.ts 
b/packages/merchant-backoffice-ui/src/declaration.d.ts
index dc53e3e83..f99dd1867 100644
--- a/packages/merchant-backoffice-ui/src/declaration.d.ts
+++ b/packages/merchant-backoffice-ui/src/declaration.d.ts
@@ -23,7 +23,7 @@ type HashCode = string;
 type EddsaPublicKey = string;
 type EddsaSignature = string;
 type WireTransferIdentifierRawP = string;
-type RelativeTime = Duration;
+type RelativeTime = TalerProtocolDuration;
 type ImageDataUrl = string;
 type MerchantUserType = "business" | "individual";
 
@@ -38,9 +38,12 @@ interface Timestamp {
   // never happen.
   t_s: number | "never";
 }
-interface Duration {
+interface TalerProtocolDuration {
   d_us: number | "forever";
 }
+interface Duration {
+  d_ms: number | "forever";
+}
 
 interface WithId {
   id: string;
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
index 093c24c3d..d13b7e929 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
@@ -32,13 +32,16 @@ import { MerchantBackend } from "../../../declaration.js";
 import { INSTANCE_ID_REGEX } from "../../../utils/constants.js";
 import { undefinedIfEmpty } from "../../../utils/table.js";
 import { SetTokenNewInstanceModal } from "../../../components/modal/index.js";
+import { Duration } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage & {
+export type Entity = 
Omit<Omit<MerchantBackend.Instances.InstanceConfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
   auth_token?: string;
+  default_pay_delay: Duration,
+  default_wire_transfer_delay: Duration,
 };
 
 interface Props {
-  onCreate: (d: Entity) => Promise<void>;
+  onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => 
Promise<void>;
   onBack?: () => void;
   forceId?: string;
 }
@@ -49,8 +52,8 @@ function with_defaults(id?: string): Partial<Entity> {
     // accounts: [],
     user_type: "business",
     use_stefan: true,
-    default_pay_delay: { d_us: 2 * 1000 * 60 * 60 * 1000 }, // two hours
-    default_wire_transfer_delay: { d_us: 1000 * 2 * 60 * 60 * 24 * 1000 }, // 
two days
+    default_pay_delay: { d_ms: 2 * 60 * 60 * 1000 }, // two hours
+    default_wire_transfer_delay: { d_ms: 2 * 60 * 60 * 24 * 1000 }, // two days
   };
 }
 
@@ -88,9 +91,9 @@ export function CreatePage({ onCreate, onBack, forceId }: 
Props): VNode {
     default_pay_delay: !value.default_pay_delay
       ? i18n.str`required`
       : !!value.default_wire_transfer_delay &&
-        value.default_wire_transfer_delay.d_us !== "forever" &&
-        value.default_pay_delay.d_us !== "forever" &&
-        value.default_pay_delay.d_us > value.default_wire_transfer_delay.d_us ?
+        value.default_wire_transfer_delay.d_ms !== "forever" &&
+        value.default_pay_delay.d_ms !== "forever" &&
+        value.default_pay_delay.d_ms > value.default_wire_transfer_delay.d_ms ?
         i18n.str`pay delay can't be greater than wire transfer delay` : 
undefined,
     default_wire_transfer_delay: !value.default_wire_transfer_delay
       ? i18n.str`required`
@@ -124,7 +127,12 @@ export function CreatePage({ onCreate, onBack, forceId }: 
Props): VNode {
     if (!value.jurisdiction) value.jurisdiction = {};
     // remove above use conversion
     // schema.validateSync(value, { abortEarly: false })
-    return onCreate(value as Entity);
+    value.default_pay_delay = 
Duration.toTalerProtocolDuration(value.default_pay_delay!) as any
+    value.default_wire_transfer_delay = 
Duration.toTalerProtocolDuration(value.default_wire_transfer_delay!) as any
+    // delete value.default_pay_delay;
+    // delete value.default_wire_transfer_delay;
+
+    return onCreate(value as any as 
MerchantBackend.Instances.InstanceConfigurationMessage);
   };
 
   function updateToken(token: string | null) {
@@ -174,54 +182,54 @@ export function CreatePage({ onCreate, onBack, forceId }: 
Props): VNode {
             </FormProvider>
 
             <div class="level">
-            <div class="level-item has-text-centered">
-              <h1 class="title">
-                <button
-                  class={
-                    !isTokenSet
-                      ? "button is-danger has-tooltip-bottom"
-                      : !value.auth_token
-                        ? "button has-tooltip-bottom"
-                        : "button is-info has-tooltip-bottom"
-                  }
-                  data-tooltip={i18n.str`change authorization configuration`}
-                  onClick={() => updateIsTokenDialogActive(true)}
-                >
-                  <div class="icon is-centered">
-                    <i class="mdi mdi-lock-reset" />
-                  </div>
-                  <span>
-                    <i18n.Translate>Set access token</i18n.Translate>
-                  </span>
-                </button>
-              </h1>
+              <div class="level-item has-text-centered">
+                <h1 class="title">
+                  <button
+                    class={
+                      !isTokenSet
+                        ? "button is-danger has-tooltip-bottom"
+                        : !value.auth_token
+                          ? "button has-tooltip-bottom"
+                          : "button is-info has-tooltip-bottom"
+                    }
+                    data-tooltip={i18n.str`change authorization configuration`}
+                    onClick={() => updateIsTokenDialogActive(true)}
+                  >
+                    <div class="icon is-centered">
+                      <i class="mdi mdi-lock-reset" />
+                    </div>
+                    <span>
+                      <i18n.Translate>Set access token</i18n.Translate>
+                    </span>
+                  </button>
+                </h1>
+              </div>
             </div>
-          </div>
-          <div class="level">
-            <div class="level-item has-text-centered">
-              {!isTokenSet ? (
-                <p class="is-size-6">
-                  <i18n.Translate>
-                    Access token is not yet configured. This instance can't be
-                    created.
-                  </i18n.Translate>
-                </p>
-              ) : value.auth_token === undefined ? (
-                <p class="is-size-6">
-                  <i18n.Translate>
-                    No access token. Authorization must be handled externally.
-                  </i18n.Translate>
-                </p>
-              ) : (
-                <p class="is-size-6">
-                  <i18n.Translate>
-                    Access token is set. Authorization is handled by the
-                    merchant backend.
-                  </i18n.Translate>
-                </p>
-              )}
+            <div class="level">
+              <div class="level-item has-text-centered">
+                {!isTokenSet ? (
+                  <p class="is-size-6">
+                    <i18n.Translate>
+                      Access token is not yet configured. This instance can't 
be
+                      created.
+                    </i18n.Translate>
+                  </p>
+                ) : value.auth_token === undefined ? (
+                  <p class="is-size-6">
+                    <i18n.Translate>
+                      No access token. Authorization must be handled 
externally.
+                    </i18n.Translate>
+                  </p>
+                ) : (
+                  <p class="is-size-6">
+                    <i18n.Translate>
+                      Access token is set. Authorization is handled by the
+                      merchant backend.
+                    </i18n.Translate>
+                  </p>
+                )}
+              </div>
             </div>
-          </div>
             <div class="buttons is-right mt-5">
               {onBack && (
                 <button class="button" onClick={onBack}>
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
index 2b1741276..a30f79169 100644
--- 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
@@ -19,32 +19,32 @@
  * @author Sebastian Javier Marchano (sebasjm)
  */
 
-import { Amounts } from "@gnu-taler/taler-util";
+import { AbsoluteTime, Amounts, Duration, TalerProtocolDuration } from 
"@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { add, isAfter, isBefore, isFuture } from "date-fns";
-import { Fragment, h, VNode } from "preact";
+import { format, isFuture } from "date-fns";
+import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import {
   FormErrors,
   FormProvider,
 } from "../../../../components/form/FormProvider.js";
 import { Input } from "../../../../components/form/Input.js";
-import { InputBoolean } from "../../../../components/form/InputBoolean.js";
 import { InputCurrency } from "../../../../components/form/InputCurrency.js";
 import { InputDate } from "../../../../components/form/InputDate.js";
+import { InputDuration } from "../../../../components/form/InputDuration.js";
 import { InputGroup } from "../../../../components/form/InputGroup.js";
 import { InputLocation } from "../../../../components/form/InputLocation.js";
 import { InputNumber } from "../../../../components/form/InputNumber.js";
+import { InputToggle } from "../../../../components/form/InputToggle.js";
 import { InventoryProductForm } from 
"../../../../components/product/InventoryProductForm.js";
 import { NonInventoryProductFrom } from 
"../../../../components/product/NonInventoryProductForm.js";
 import { ProductList } from "../../../../components/product/ProductList.js";
 import { useConfigContext } from "../../../../context/config.js";
-import { Duration, MerchantBackend, WithId } from "../../../../declaration.js";
+import { MerchantBackend, WithId } from "../../../../declaration.js";
+import { useSettings } from "../../../../hooks/useSettings.js";
 import { OrderCreateSchema as schema } from "../../../../schemas/index.js";
 import { rate } from "../../../../utils/amount.js";
 import { undefinedIfEmpty } from "../../../../utils/table.js";
-import { useSettings } from "../../../../hooks/useSettings.js";
-import { InputToggle } from "../../../../components/form/InputToggle.js";
 
 interface Props {
   onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
@@ -54,23 +54,13 @@ interface Props {
 }
 interface InstanceConfig {
   use_stefan: boolean;
-  default_pay_delay: Duration;
-  default_wire_transfer_delay: Duration;
+  default_pay_delay: TalerProtocolDuration;
+  default_wire_transfer_delay: TalerProtocolDuration;
 }
 
 function with_defaults(config: InstanceConfig, currency: string): 
Partial<Entity> {
-  const defaultPayDeadline =
-    !config.default_pay_delay || config.default_pay_delay.d_us === "forever"
-      ? undefined
-      : add(new Date(), {
-        seconds: config.default_pay_delay.d_us / (1000 * 1000),
-      });
-  const defaultWireDeadline =
-    !config.default_wire_transfer_delay || 
config.default_wire_transfer_delay.d_us === "forever"
-      ? undefined
-      : add(new Date(), {
-        seconds: config.default_wire_transfer_delay.d_us / (1000 * 1000),
-      });
+  const defaultPayDeadline = 
Duration.fromTalerProtocolDuration(config.default_pay_delay);
+  const defaultWireDeadline = 
Duration.fromTalerProtocolDuration(config.default_wire_transfer_delay);
 
   return {
     inventoryProducts: {},
@@ -78,10 +68,10 @@ function with_defaults(config: InstanceConfig, currency: 
string): Partial<Entity
     pricing: {},
     payments: {
       max_fee: undefined,
-      pay_deadline: defaultPayDeadline,
-      refund_deadline: defaultPayDeadline,
       createToken: true,
-      wire_transfer_deadline: defaultWireDeadline,
+      pay_deadline: (defaultPayDeadline),
+      refund_deadline: (defaultPayDeadline),
+      wire_transfer_deadline: (defaultWireDeadline),
     },
     shipping: {},
     extra: {},
@@ -107,10 +97,10 @@ interface Shipping {
   fullfilment_url?: string;
 }
 interface Payments {
-  refund_deadline?: Date;
-  pay_deadline?: Date;
-  wire_transfer_deadline?: Date;
-  auto_refund_deadline?: Date;
+  refund_deadline: Duration;
+  pay_deadline: Duration;
+  wire_transfer_deadline: Duration;
+  auto_refund_deadline: Duration;
   max_fee?: string;
   createToken: boolean;
   minimum_age?: number;
@@ -164,53 +154,41 @@ export function CreatePage({
             ? i18n.str`must be greater than 0`
             : undefined,
     }),
-    // extra:
-    //   value.extra && !stringIsValidJSON(value.extra)
-    //     ? i18n.str`not a valid json`
-    //     : undefined,
     payments: undefinedIfEmpty({
       refund_deadline: !value.payments?.refund_deadline
         ? undefined
-        : !isFuture(value.payments.refund_deadline)
-          ? i18n.str`should be in the future`
-          : value.payments.pay_deadline &&
-            isBefore(value.payments.refund_deadline, 
value.payments.pay_deadline)
-            ? i18n.str`refund deadline cannot be before pay deadline`
-            : value.payments.wire_transfer_deadline &&
-              isBefore(
-                value.payments.wire_transfer_deadline,
-                value.payments.refund_deadline,
-              )
-              ? i18n.str`wire transfer deadline cannot be before refund 
deadline`
-              : undefined,
-      pay_deadline: !value.payments?.pay_deadline
-        ? i18n.str`required`
-        : !isFuture(value.payments.pay_deadline)
-          ? i18n.str`should be in the future`
+        : value.payments.pay_deadline &&
+          Duration.cmp(value.payments.refund_deadline, 
value.payments.pay_deadline) === -1
+          ? i18n.str`refund deadline cannot be before pay deadline`
           : value.payments.wire_transfer_deadline &&
-            isBefore(
+            Duration.cmp(
               value.payments.wire_transfer_deadline,
-              value.payments.pay_deadline,
-            )
-            ? i18n.str`wire transfer deadline cannot be before pay deadline`
+              value.payments.refund_deadline,
+            ) === -1
+            ? i18n.str`wire transfer deadline cannot be before refund deadline`
             : undefined,
-      wire_transfer_deadline: !value.payments?.wire_transfer_deadline
+      pay_deadline: !value.payments?.pay_deadline
         ? i18n.str`required`
-        : !isFuture(value.payments.wire_transfer_deadline)
-          ? i18n.str`should be in the future`
+        : value.payments.wire_transfer_deadline &&
+          Duration.cmp(
+            value.payments.wire_transfer_deadline,
+            value.payments.pay_deadline,
+          ) === -1
+          ? i18n.str`wire transfer deadline cannot be before pay deadline`
           : undefined,
+      wire_transfer_deadline: !value.payments?.wire_transfer_deadline
+        ? i18n.str`required`
+        : undefined,
       auto_refund_deadline: !value.payments?.auto_refund_deadline
         ? undefined
-        : !isFuture(value.payments.auto_refund_deadline)
-          ? i18n.str`should be in the future`
-          : !value.payments?.refund_deadline
-            ? i18n.str`should have a refund deadline`
-            : !isAfter(
-              value.payments.refund_deadline,
-              value.payments.auto_refund_deadline,
-            )
-              ? i18n.str`auto refund cannot be after refund deadline`
-              : undefined,
+        : !value.payments?.refund_deadline
+          ? i18n.str`should have a refund deadline`
+          : Duration.cmp(
+            value.payments.refund_deadline,
+            value.payments.auto_refund_deadline,
+          ) == -1
+            ? i18n.str`auto refund cannot be after refund deadline`
+            : undefined,
 
     }),
     shipping: undefinedIfEmpty({
@@ -226,7 +204,7 @@ export function CreatePage({
   );
 
   const submit = (): void => {
-    const order = schema.cast(value);
+    const order = value as any; //schema.cast(value);
     if (!value.payments) return;
     if (!value.shipping) return;
 
@@ -236,29 +214,18 @@ export function CreatePage({
         summary: order.pricing.summary,
         products: productList,
         extra: undefinedIfEmpty(value.extra),
-        pay_deadline: value.payments.pay_deadline
-          ? {
-            t_s: Math.floor(value.payments.pay_deadline.getTime() / 1000),
-          }
-          : undefined,
+        pay_deadline: !value.payments.pay_deadline ?
+          i18n.str`required` :
+          
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.pay_deadline))
+        ,// : undefined,
         wire_transfer_deadline: value.payments.wire_transfer_deadline
-          ? {
-            t_s: Math.floor(
-              value.payments.wire_transfer_deadline.getTime() / 1000,
-            ),
-          }
+          ? 
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.wire_transfer_deadline))
           : undefined,
         refund_deadline: value.payments.refund_deadline
-          ? {
-            t_s: Math.floor(value.payments.refund_deadline.getTime() / 1000),
-          }
+          ? 
AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.refund_deadline))
           : undefined,
         auto_refund: value.payments.auto_refund_deadline
-          ? {
-            d_us: Math.floor(
-              value.payments.auto_refund_deadline.getTime() * 1000,
-            ),
-          }
+          ? 
Duration.toTalerProtocolDuration(value.payments.auto_refund_deadline)
           : undefined,
         max_fee: value.payments.max_fee as string,
 
@@ -360,10 +327,18 @@ export function CreatePage({
     0,
   );
 
+  // if there is no default pay deadline
   const noDefault_payDeadline = !instance_default.payments || 
!instance_default.payments.pay_deadline
+  // and there is no defailt wire deadline
   const noDefault_wireDeadline = !instance_default.payments || 
!instance_default.payments.wire_transfer_deadline
+  // user required to set the taler options
   const requiresSomeTalerOptions = noDefault_payDeadline || 
noDefault_wireDeadline
 
+  const whenPay = !value.payments?.pay_deadline ? undefined : 
AbsoluteTime.addDuration(AbsoluteTime.now(), value.payments.pay_deadline)
+  const whenRefund = !value.payments?.refund_deadline ? undefined : 
AbsoluteTime.addDuration(AbsoluteTime.now(), value.payments.refund_deadline)
+  const whenWire = !value.payments?.wire_transfer_deadline ? undefined : 
AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.wire_transfer_deadline)
+  const whenAutoRefund = !value.payments?.auto_refund_deadline ? undefined : 
AbsoluteTime.addDuration(AbsoluteTime.now(), 
value.payments.auto_refund_deadline)
+
   return (
     <div>
 
@@ -522,10 +497,13 @@ export function CreatePage({
                   label={i18n.str`Taler payment options`}
                   tooltip={i18n.str`Override default Taler payment settings 
for this order`}
                 >
-                  {(settings.advanceOrderMode || noDefault_payDeadline) && 
<InputDate
+                  {(settings.advanceOrderMode || noDefault_payDeadline) && 
<InputDuration
                     name="payments.pay_deadline"
-                    label={i18n.str`Payment deadline`}
-                    tooltip={i18n.str`Deadline for the customer to pay for the 
offer before it expires. Inventory products will be reserved until this 
deadline.`}
+                    label={i18n.str`Payment time`}
+                    help={whenPay && whenPay.t_ms !== "never" ? 
i18n.str`Deadline at ${format(whenPay.t_ms, "dd/MM/yy HH:mm")}` : 
i18n.str`Without deadline`}
+                    withForever
+                    withoutClear
+                    tooltip={i18n.str`Time for the customer to pay for the 
offer before it expires. Inventory products will be reserved until this 
deadline. Time start to run after the order is created.`}
                     side={
                       <span>
                         <button class="button" onClick={() => {
@@ -543,10 +521,13 @@ export function CreatePage({
                       </span>
                     }
                   />}
-                  {settings.advanceOrderMode && <InputDate
+                  {settings.advanceOrderMode && <InputDuration
                     name="payments.refund_deadline"
-                    label={i18n.str`Refund deadline`}
-                    tooltip={i18n.str`Time until which the order can be 
refunded by the merchant.`}
+                    label={i18n.str`Refund time`}
+                    help={whenRefund && whenRefund.t_ms !== "never" ? 
i18n.str`Deadline at ${format(whenRefund.t_ms, "dd/MM/yy HH:mm")}` : 
i18n.str`Without deadline`}
+                    withForever
+                    withoutClear
+                    tooltip={i18n.str`Time while the order can be refunded by 
the merchant. Time starts after the order is created.`}
                     side={
                       <span>
                         <button class="button" onClick={() => {
@@ -563,10 +544,13 @@ export function CreatePage({
                       </span>
                     }
                   />}
-                  {(settings.advanceOrderMode || noDefault_wireDeadline) && 
<InputDate
+                  {(settings.advanceOrderMode || noDefault_wireDeadline) && 
<InputDuration
                     name="payments.wire_transfer_deadline"
-                    label={i18n.str`Wire transfer deadline`}
-                    tooltip={i18n.str`Deadline for the exchange to make the 
wire transfer.`}
+                    label={i18n.str`Wire transfer time`}
+                    help={whenWire && whenWire.t_ms !== "never" ? 
i18n.str`Deadline at ${format(whenWire.t_ms, "dd/MM/yy HH:mm")}` : 
i18n.str`Without deadline`}
+                    withoutClear
+                    withForever
+                    tooltip={i18n.str`Time for the exchange to make the wire 
transfer. Time starts after the order is created.`}
                     side={
                       <span>
                         <button class="button" onClick={() => {
@@ -583,10 +567,12 @@ export function CreatePage({
                       </span>
                     }
                   />}
-                  {settings.advanceOrderMode && <InputDate
+                  {settings.advanceOrderMode && <InputDuration
                     name="payments.auto_refund_deadline"
-                    label={i18n.str`Auto-refund deadline`}
+                    label={i18n.str`Auto-refund interval`}
+                    help={whenAutoRefund && whenAutoRefund.t_ms !== "never" ? 
i18n.str`Deadline at ${format(whenAutoRefund.t_ms, "dd/MM/yy HH:mm")}` : 
i18n.str`Without deadline`}
                     tooltip={i18n.str`Time until which the wallet will 
automatically check for refunds without user interaction.`}
+                    withForever
                   />}
 
                   {settings.advanceOrderMode && <InputCurrency
@@ -703,3 +689,5 @@ function asProduct(p: ProductAndQuantity): 
MerchantBackend.Product {
     minimum_age: p.product.minimum_age,
   };
 }
+
+
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
index 5b88b550f..a27a0cb06 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
@@ -31,14 +31,16 @@ import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultI
 import { useInstanceContext } from "../../../context/instance.js";
 import { MerchantBackend } from "../../../declaration.js";
 import { undefinedIfEmpty } from "../../../utils/table.js";
+import { Duration } from "@gnu-taler/taler-util";
 
-type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & {
-  auth_token?: string;
+export type Entity = 
Omit<Omit<MerchantBackend.Instances.InstanceReconfigurationMessage, 
"default_pay_delay">, "default_wire_transfer_delay"> & {
+  default_pay_delay: Duration,
+  default_wire_transfer_delay: Duration,
 };
 
 //MerchantBackend.Instances.InstanceAuthConfigurationMessage
 interface Props {
-  onUpdate: (d: Entity) => void;
+  onUpdate: (d: MerchantBackend.Instances.InstanceReconfigurationMessage) => 
void;
   selected: MerchantBackend.Instances.QueryInstancesResponse;
   isLoading: boolean;
   onBack: () => void;
@@ -47,21 +49,12 @@ interface Props {
 function convert(
   from: MerchantBackend.Instances.QueryInstancesResponse,
 ): Entity {
-  const { ...rest } = from;
-  // const accounts = qAccounts
-  //   .filter((a) => a.active)
-  //   .map(
-  //     (a) =>
-  //     ({
-  //       payto_uri: a.payto_uri,
-  //       credit_facade_url: a.credit_facade_url,
-  //       credit_facade_credentials: a.credit_facade_credentials,
-  //     } as MerchantBackend.Instances.MerchantBankAccount),
-  //   );
+  const { default_pay_delay, default_wire_transfer_delay, ...rest } = from;
+
   const defaults = {
     use_stefan: false,
-    default_pay_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 }, //two hours
-    default_wire_transfer_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 * 2 }, 
//two hours
+    default_pay_delay: Duration.fromTalerProtocolDuration(default_pay_delay),
+    default_wire_transfer_delay: 
Duration.fromTalerProtocolDuration(default_wire_transfer_delay),
   };
   return { ...defaults, ...rest };
 }
@@ -72,20 +65,6 @@ export function UpdatePage({
   onBack,
 }: Props): VNode {
   const { id } = useInstanceContext();
-  // const currentTokenValue = getTokenValuePart(token);
-
-  // function updateToken(token: string | undefined | null) {
-  //   const value =
-  //     token && token.startsWith("secret-token:")
-  //       ? token.substring("secret-token:".length)
-  //       : token;
-
-  //   if (!token) {
-  //     onChangeAuth({ method: "external" });
-  //   } else {
-  //     onChangeAuth({ method: "token", token: `secret-token:${value}` });
-  //   }
-  // }
 
   const [value, valueHandler] = useState<Partial<Entity>>(convert(selected));
 
@@ -101,9 +80,9 @@ export function UpdatePage({
     default_pay_delay: !value.default_pay_delay
       ? i18n.str`required`
       : !!value.default_wire_transfer_delay &&
-        value.default_wire_transfer_delay.d_us !== "forever" &&
-        value.default_pay_delay.d_us !== "forever" &&
-        value.default_pay_delay.d_us > value.default_wire_transfer_delay.d_us ?
+        value.default_wire_transfer_delay.d_ms !== "forever" &&
+        value.default_pay_delay.d_ms !== "forever" &&
+        value.default_pay_delay.d_ms > value.default_wire_transfer_delay.d_ms ?
         i18n.str`pay delay can't be greater than wire transfer delay` : 
undefined,
     default_wire_transfer_delay: !value.default_wire_transfer_delay
       ? i18n.str`required`
@@ -127,7 +106,13 @@ export function UpdatePage({
   );
 
   const submit = async (): Promise<void> => {
-    await onUpdate(value as Entity);
+    const { default_pay_delay, default_wire_transfer_delay, ...rest } = value 
as Required<Entity>;
+    const result: MerchantBackend.Instances.InstanceReconfigurationMessage = {
+      default_pay_delay: Duration.toTalerProtocolDuration(default_pay_delay),
+      default_wire_transfer_delay: 
Duration.toTalerProtocolDuration(default_wire_transfer_delay),
+      ...rest,
+    }
+    await onUpdate(result);
   };
   // const [active, setActive] = useState(false);
 
@@ -144,26 +129,6 @@ export function UpdatePage({
                   </span>
                 </div>
               </div>
-              {/* <div class="level-right">
-                <div class="level-item">
-                  <h1 class="title">
-                    <button
-                      class="button is-danger"
-                      data-tooltip={i18n.str`Change the authorization method 
use for this instance.`}
-                      onClick={(): void => {
-                        setActive(!active);
-                      }}
-                    >
-                      <div class="icon is-left">
-                        <i class="mdi mdi-lock-reset" />
-                      </div>
-                      <span>
-                        <i18n.Translate>Manage access token</i18n.Translate>
-                      </span>
-                    </button>
-                  </h1>
-                </div>
-              </div> */}
             </div>
           </div>
         </section>

-- 
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]