gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant-backoffice] branch master updated: new show template and


From: gnunet
Subject: [taler-merchant-backoffice] branch master updated: new show template and mustache example
Date: Thu, 30 Sep 2021 23:39:42 +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 b783e72  new show template and mustache example
b783e72 is described below

commit b783e7219cc6ee4ae60301f560e2edf6cc44a489
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Sep 30 18:39:32 2021 -0300

    new show template and mustache example
---
 packages/backend/package.json                      |   5 +-
 packages/backend/render-examples.ts                |  83 ++++++
 packages/backend/render-mustache.js                |  18 --
 packages/backend/src/hooks/transfer.ts             |   4 +-
 .../backend/src/pages/ShowOrderDetails.examples.ts | 219 +++++++++++++++
 .../backend/src/pages/ShowOrderDetails.stories.tsx | 111 +-------
 packages/backend/src/pages/ShowOrderDetails.tsx    | 302 +++++++++++++++++----
 .../backend/tests/__mocks__/fileTransformer.js     |   2 +-
 pnpm-lock.yaml                                     |   6 +
 9 files changed, 565 insertions(+), 185 deletions(-)

diff --git a/packages/backend/package.json b/packages/backend/package.json
index f84c238..2593b1c 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -5,14 +5,14 @@
   "license": "MIT",
   "scripts": {
     "build": "rollup -c",
-    "compile": "tsc",
     "dev": "rollup -c -w",
+    "render-examples": "ts-node -O '{\"module\": \"commonjs\"}' -T 
render-examples.ts dist/pages dist/examples",
     "lint-check": "eslint '{src,tests}/**/*.{js,jsx,ts,tsx}'",
     "lint-fix": "eslint --fix '{src,tests}/**/*.{js,jsx,ts,tsx}'",
     "test": "jest ./tests",
     "dev-test": "jest ./tests --watch",
     "typedoc": "typedoc src",
-    "clean": "rimraf build storybook-static docs single",
+    "clean": "rimraf build storybook-static docs single dist",
     "serve-dist": "sirv --port ${PORT:=8080} --cors --single dist",
     "build-storybook": "build-storybook",
     "storybook": "start-storybook -p 6006"
@@ -83,6 +83,7 @@
     "@types/history": "^4.7.8",
     "@types/jest": "^26.0.23",
     "@types/mocha": "^8.2.2",
+    "@types/mustache": "^4.1.2",
     "@typescript-eslint/eslint-plugin": "^4.22.0",
     "@typescript-eslint/parser": "^4.22.0",
     "babel-loader": "^8.2.2",
diff --git a/packages/backend/render-examples.ts 
b/packages/backend/render-examples.ts
new file mode 100644
index 0000000..c1da3ce
--- /dev/null
+++ b/packages/backend/render-examples.ts
@@ -0,0 +1,83 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import mustache from "mustache";
+import fs from "fs";
+import { format, formatDuration, intervalToDuration } from "date-fns";
+
+/**
+ * This script will emulate what the merchant backend will do when being 
requested
+ * 
+*/
+
+const sourceDirectory = process.argv[2]
+const destDirectory = process.argv[3]
+
+if (!sourceDirectory || !destDirectory) {
+       console.log('usage: render-mustache <source-directory> 
<dest-directory>')
+       process.exit(1);
+}
+
+if (!fs.existsSync(destDirectory)) {
+       fs.mkdirSync(destDirectory);
+}
+
+/**
+ * Load all the html files
+ */
+const files = fs.readdirSync(sourceDirectory).filter(f => /.html/.test(f))
+
+files.forEach(file => {
+       const html = fs.readFileSync(`${sourceDirectory}/${file}`, 'utf8')
+
+       const testName = file.replace('.html', '')
+       if (testName !== 'ShowOrderDetails') return;
+       // eslint-disable-next-line @typescript-eslint/no-var-requires
+       const { exampleData } = require(`./src/pages/${testName}.examples`)
+
+       Object.keys(exampleData).forEach(exampleName => {
+               const example = exampleData[exampleName]
+
+               //enhance the example with more information
+               example.contract_terms_json = () => 
JSON.stringify(example.contract_terms);
+               example.contract_terms.timestamp_str = () => 
example.contract_terms.timestamp && 
format(example.contract_terms.timestamp.t_ms, 'dd MMM yyyy HH:mm:ss');
+
+               example.contract_terms.hasProducts = () => 
example.contract_terms.products?.length > 0;
+               example.contract_terms.hasAuditors = () => 
example.contract_terms.auditors?.length > 0;
+               example.contract_terms.hasExchanges = () => 
example.contract_terms.exchanges?.length > 0;
+
+               example.contract_terms.products.forEach(p => {
+                       p.delivery_date_str = () => p.delivery_date && 
format(p.delivery_date.t_ms, 'dd MM yyyy HH:mm:ss')
+                       p.hasTaxes = () => p.taxes?.length > 0
+               })
+               example.contract_terms.has_delivery_info = () => 
example.contract_terms.delivery_date || example.contract_terms.delivery_location
+
+               example.contract_terms.delivery_date_str = () => 
example.contract_terms.delivery_date && 
format(example.contract_terms.delivery_date.t_ms, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.pay_deadline_str = () => 
example.contract_terms.pay_deadline && 
format(example.contract_terms.pay_deadline.t_ms, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.wire_transfer_deadline_str = () => 
example.contract_terms.wire_transfer_deadline && 
format(example.contract_terms.wire_transfer_deadline.t_ms, 'dd MM yyyy 
HH:mm:ss')
+               example.contract_terms.refund_deadline_str = () => 
example.contract_terms.refund_deadline && 
format(example.contract_terms.refund_deadline.t_ms, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.auto_refund_str = () => 
example.contract_terms.auto_refund && formatDuration(intervalToDuration({ 
start: 0, end: example.contract_terms.auto_refund.d_ms }))
+
+               const output = mustache.render(html, example);
+
+               
fs.writeFileSync(`${destDirectory}/${testName}.${exampleName}.html`, output)
+       })
+})
diff --git a/packages/backend/render-mustache.js 
b/packages/backend/render-mustache.js
deleted file mode 100644
index 74b68dd..0000000
--- a/packages/backend/render-mustache.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const mustache = require('mustache')
-const fs = require('fs')
-
-const htmlFile = process.argv[2]
-const exampleJson = process.argv[3]
-
-if (!htmlFile || !exampleJson) {
-       console.log('usage: render-mustache <htmlFile> <exampleJson>')
-       return 1
-}
-
-const html = fs.readFileSync(htmlFile, 'utf8')
-const json = fs.readFileSync(exampleJson, 'utf8')
-const example = JSON.parse(json)
-
-const output = mustache.render(html, example);
-
-console.log(output)
diff --git a/packages/backend/src/hooks/transfer.ts 
b/packages/backend/src/hooks/transfer.ts
index 02e041a..482f00d 100644
--- a/packages/backend/src/hooks/transfer.ts
+++ b/packages/backend/src/hooks/transfer.ts
@@ -124,7 +124,7 @@ export function useInstanceTransfers(args?: 
InstanceTransferFilter, updatePositi
       if (afterData.data.transfers.length < MAX_RESULT_SIZE) {
         setPageAfter(pageAfter + 1)
       } else {
-        const from = 
""+afterData.data.transfers[afterData.data.transfers.length - 
1].transfer_serial_id
+        const from = 
`${afterData.data.transfers[afterData.data.transfers.length - 
1].transfer_serial_id}`
         if (from && updatePosition) updatePosition(from)
       }
     },
@@ -133,7 +133,7 @@ export function useInstanceTransfers(args?: 
InstanceTransferFilter, updatePositi
       if (beforeData.data.transfers.length < MAX_RESULT_SIZE) {
         setPageBefore(pageBefore + 1)
       } else if (beforeData) {
-        const from = 
""+beforeData.data.transfers[beforeData.data.transfers.length - 
1].transfer_serial_id
+        const from = 
`${beforeData.data.transfers[beforeData.data.transfers.length - 
1].transfer_serial_id}`
         if (from && updatePosition) updatePosition(from)
       }
     },
diff --git a/packages/backend/src/pages/ShowOrderDetails.examples.ts 
b/packages/backend/src/pages/ShowOrderDetails.examples.ts
new file mode 100644
index 0000000..8d76900
--- /dev/null
+++ b/packages/backend/src/pages/ShowOrderDetails.examples.ts
@@ -0,0 +1,219 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { MerchantBackend } from '../declaration';
+import { Props } from './ShowOrderDetails';
+
+
+const defaultContractTerms: MerchantBackend.ContractTerms = {
+  order_id: 'XRS8876388373',
+  amount: 'USD:10',
+  summary: 'this is a short summary',
+  pay_deadline: {
+    t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+  },
+  merchant: {
+    name: 'the merchant (inc)',
+    address: {
+      country_subdivision: 'Buenos Aires',
+      town: 'CABA',
+      country: 'Argentina'
+    },
+    jurisdiction: {
+      country_subdivision: 'Cordoba',
+      town: 'Capital',
+      country: 'Argentina'
+    },
+  },
+  max_fee: 'USD:0.1',
+  max_wire_fee: 'USD:0.2',
+  wire_fee_amortization: 1,
+  products: [],
+  timestamp: {
+    t_ms: new Date().getTime()
+  },
+  auditors: [],
+  exchanges: [],
+  h_wire: '',
+  merchant_base_url: 'http://merchant.base.url/',
+  merchant_pub: 'QWEASDQWEASD',
+  nonce: 'NONCE',
+  refund_deadline: {
+    t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+  },
+  wire_method: 'x-taler-bank',
+  wire_transfer_deadline: {
+    t_ms: new Date().getTime() + 3 * 24 * 60 * 60 * 1000
+  },
+};
+
+const inSixDays = new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+const in10Minutes = new Date().getTime() + 10 * 60 * 1000
+const in15Minutes = new Date().getTime() + 15 * 60 * 1000
+const in20Minutes = new Date().getTime() + 20 * 60 * 1000
+
+export const exampleData: { [name: string]: Props } = {
+  Simplest: {
+    order_summary: 'here goes the order summary',
+    contract_terms: defaultContractTerms,
+  },
+  WithRefundAmount: {
+    order_summary: 'here goes the order summary',
+    refund_amount: 'USD:10',
+    contract_terms: defaultContractTerms,
+  },
+  WithDeliveryDate: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_date: {
+        t_ms: inSixDays
+      },
+    },
+  },
+  WithDeliveryLocation: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_location: {
+        address_lines: ['addr line 1', 'addr line 2', 'addr line 3', 'addr 
line 4', 'addr line 5', 'addr line 6', 'addr line 7'],
+        building_name: 'building-name',
+        building_number: 'building-number',
+        country: 'country',
+        country_subdivision: 'country sub',
+        district: 'district',
+        post_code: 'post-code',
+        street: 'street',
+        town: 'town',
+        town_location: 'town loc',
+      },
+    },
+  },
+  WithDeliveryLocationAndDate: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_location: {
+        address_lines: ['addr1', 'addr2', 'addr3', 'addr4', 'addr5', 'addr6', 
'addr7'],
+        building_name: 'building-name',
+        building_number: 'building-number',
+        country: 'country',
+        country_subdivision: 'country sub',
+        district: 'district',
+        post_code: 'post-code',
+        street: 'street',
+        town: 'town',
+        town_location: 'town loc',
+      },
+      delivery_date: {
+        t_ms: inSixDays
+      },
+    },
+  },
+  WithThreeProducts: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      products: [{
+        description: 'description of the first product',
+        price: '5:USD',
+        quantity: 1,
+        delivery_date: { t_ms: in10Minutes },
+        product_id: '12333',
+      }, {
+        description: 'another description',
+        price: '10:USD',
+        quantity: 5,
+        unit: 't-shirt',
+      }, {
+        description: 'one last description',
+        price: '10:USD',
+        quantity: 5
+      }]
+    } as MerchantBackend.ContractTerms
+  },
+  WithProductWithTaxes: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      products: [{
+        description: 'description of the first product',
+        price: '5:USD',
+        quantity: 1,
+        unit: 'beer',
+        delivery_date: { t_ms: in10Minutes },
+        product_id: '456',
+        taxes: [{
+          name: 'VAT', tax: 'USD:1'
+        }],
+      }, {
+        description: 'one last description',
+        price: '10:USD',
+        quantity: 5,
+        product_id: '123',
+        unit: 'beer',
+        taxes: [{
+          name: 'VAT', tax: 'USD:1'
+        }],
+      }]
+    } as MerchantBackend.ContractTerms
+  },
+  WithExchangeList: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      exchanges: [{
+        master_pub: 'ABCDEFGHIJKLMNO',
+        url: 'http://exchange0.taler.net'
+      }, {
+        master_pub: 'AAAAAAAAAAAAAAA',
+        url: 'http://exchange1.taler.net'
+      }, {
+        master_pub: 'BBBBBBBBBBBBBBB',
+        url: 'http://exchange2.taler.net'
+      }]
+    },
+  },
+  WithAuditorList: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      auditors: [{
+        auditor_pub: 'ABCDEFGHIJKLMNO',
+        name: 'the USD auditor',
+        url: 'http://auditor-usd.taler.net'
+      }, {
+        auditor_pub: 'OPQRSTUVWXYZABCD',
+        name: 'the EUR auditor',
+        url: 'http://auditor-eur.taler.net'
+      }]
+    },
+  },
+  WithAutoRefund: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      auto_refund: {
+        d_ms: 1000 * 60 * 60 * 26 + 1000 * 60 * 30
+      }
+    },
+  },
+}
diff --git a/packages/backend/src/pages/ShowOrderDetails.stories.tsx 
b/packages/backend/src/pages/ShowOrderDetails.stories.tsx
index 616af7f..6a902cc 100644
--- a/packages/backend/src/pages/ShowOrderDetails.stories.tsx
+++ b/packages/backend/src/pages/ShowOrderDetails.stories.tsx
@@ -20,8 +20,8 @@
 */
 
 import { FunctionalComponent, h } from 'preact';
-import { MerchantBackend } from '../declaration';
-import { Props, ShowOrderDetails as TestedComponent } from 
'./ShowOrderDetails';
+import { ShowOrderDetails as TestedComponent } from './ShowOrderDetails';
+import { exampleData } from './ShowOrderDetails.examples';
 
 export default {
   title: 'ShowOrderDetails',
@@ -37,110 +37,13 @@ function createExample<Props>(Component: 
FunctionalComponent<Props>, props: Part
   return r
 }
 
-const defaultContractTerms: MerchantBackend.ContractTerms = {
-  order_id: 'XRS8876388373',
-  amount: 'USD:10',
-  summary: 'this is a short summary',
-  pay_deadline: {
-    t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
-  },
-  merchant: {
-    name: 'the merchant (inc)',
-    address: {},
-    jurisdiction: {},
-  },
-  max_fee: '',
-  max_wire_fee: '',
-  wire_fee_amortization: 1,
-  products: [],
-  timestamp: {
-    t_ms: new Date().getTime()
-  },
-  auditors: [],
-  exchanges: [],
-  h_wire: '',
-  merchant_base_url : '://merchant.base.url/',
-  merchant_pub: 'QWEASDQWEASD',
-  nonce: 'NONCE',
-  refund_deadline: {
-    t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
-  },
-  wire_method: 'x-taler-bank',
-  wire_transfer_deadline: {
-    t_ms: new Date().getTime() + 3 * 24 * 60 * 60 * 1000
-  }
-};
-
-
-export const exampleData: { [name: string]: Props } = {
-  Simplest: {
-    order_summary: 'here goes the order summary',
-    contract_terms: defaultContractTerms,
-  },
-  WithRefundAmount: {
-    order_summary: 'here goes the order summary',
-    refund_amount: 'USD:10',
-    contract_terms: defaultContractTerms,
-  },
-  WithDeliveryDate: {
-    order_summary: 'here goes the order summary',
-    contract_terms: {
-      ...defaultContractTerms,
-      delivery_date: {
-        t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
-      }
-    },
-  },
-  WithDeliveryLocation: {
-    order_summary: 'here goes the order summary',
-    contract_terms: {
-      ...defaultContractTerms,
-      delivery_location: {
-        address_lines: ['addr1', 'addr2', 'addr3', 'addr4', 'addr5', 'addr6', 
'addr7'],
-        building_name: 'building-name',
-        building_number: 'building-number',
-        country: 'country',
-        country_subdivision: 'country sub',
-        district: 'district',
-        post_code: 'post-code',
-        street: 'street',
-        town: 'town',
-        town_location: 'town loc',
-      },
-    },
-  },
-  WithThreeProducts: {
-    order_summary: 'here goes the order summary',
-    contract_terms: {
-      order_id: 'XRS8876388373',
-      amount: 'USD:10',
-      summary: 'this is a short summary',
-      pay_deadline: {
-        t_ms: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
-      },
-      merchant: {
-        name: 'the merchant (inc)'
-      },
-      products: [{
-        description: 'description of the first product',
-        price: '5:USD',
-        quantity: 1,
-        delivery_date: { t_ms: new Date().getTime() }
-      }, {
-        description: 'another description',
-        price: '10:USD',
-        quantity: 5,
-      }, {
-        description: 'one last description',
-        price: '10:USD',
-        quantity: 5
-      }]
-    } as MerchantBackend.ContractTerms
-  },
-}
-
 export const Simplest = createExample(TestedComponent, exampleData.Simplest);
 export const WithRefundAmount = createExample(TestedComponent, 
exampleData.WithRefundAmount);
 export const WithDeliveryDate = createExample(TestedComponent, 
exampleData.WithDeliveryDate);
 export const WithDeliveryLocation = createExample(TestedComponent, 
exampleData.WithDeliveryLocation);
+export const WithDeliveryLocationAndDate = createExample(TestedComponent, 
exampleData.WithDeliveryLocationAndDate);
 export const WithThreeProducts = createExample(TestedComponent, 
exampleData.WithThreeProducts);
+export const WithAuditorList = createExample(TestedComponent, 
exampleData.WithAuditorList);
+export const WithExchangeList = createExample(TestedComponent, 
exampleData.WithExchangeList);
+export const WithAutoRefund = createExample(TestedComponent, 
exampleData.WithAutoRefund);
+export const WithProductWithTaxes = createExample(TestedComponent, 
exampleData.WithProductWithTaxes);
diff --git a/packages/backend/src/pages/ShowOrderDetails.tsx 
b/packages/backend/src/pages/ShowOrderDetails.tsx
index b791c91..43b730c 100644
--- a/packages/backend/src/pages/ShowOrderDetails.tsx
+++ b/packages/backend/src/pages/ShowOrderDetails.tsx
@@ -18,8 +18,8 @@
 *
 * @author Sebastian Javier Marchano (sebasjm)
 */
-import { Product } from '@gnu-taler/taler-util';
-import { format } from 'date-fns';
+import { format, formatDuration } from 'date-fns';
+import { intervalToDuration } from 'date-fns/esm';
 import { Fragment, h, render, VNode } from 'preact';
 import { render as renderToString } from 'preact-render-to-string';
 import { Footer } from '../components/Footer';
@@ -59,11 +59,54 @@ function Head({ order_summary }: { order_summary?: string 
}): VNode {
       <meta http-equiv="refresh" content="1" />
     </noscript>
     <title>Status of your order for {order_summary ? order_summary : `{{ 
order_summary }}`}</title>
+    <script>{`
+      var contractTermsStr = '{{{contract_terms_json}}}';
+    `}</script>
+  </Fragment>
+}
+
+function Location({ templateName, location, btr }: { templateName: string, 
location: MerchantBackend.Location | undefined, btr?: boolean }) {
+  //FIXME: mustache strings show be constructed in a way that ends in the 
final output of the html but is not present in the 
+  // javascript code, otherwise when mustache render engine run over the html 
it will also replace string in the javascript code
+  // that is made to run when the browser has javascript enable leading into 
undefined behavior.
+  // that's why in the next fields we are using concatenations to build the 
mustache placeholder.
+  return <Fragment>
+    {btr && `{{`+`#${templateName}.building_name}}`}
+    <dd>{location?.building_name || (btr && `{{ ${templateName}.building_name 
}}`)} {location?.building_number || (btr && `{{ ${templateName}.building_number 
}}`)}</dd>
+    {btr && `{{`+`/${templateName}.building_name}}`}
+
+    {btr && `{{`+`#${templateName}.country}}`}
+    <dd>{location?.country || (btr && `{{ ${templateName}.country }}`)} 
{location?.country_subdivision || (btr && `{{ 
${templateName}.country_subdivision }}`)}</dd>
+    {btr && `{{`+`/${templateName}.country}}`}
+
+    {btr && `{{`+`#${templateName}.district}}`}
+    <dd>{location?.district || (btr && `{{ ${templateName}.district }}`)}</dd>
+    {btr && `{{`+`/${templateName}.district}}`}
+
+    {btr && `{{`+`#${templateName}.post_code}}`}
+    <dd>{location?.post_code || (btr && `{{ ${templateName}.post_code 
}}`)}</dd>
+    {btr && `{{`+`/${templateName}.post_code}}`}
+
+    {btr && `{{`+`#${templateName}.street}}`}
+    <dd>{location?.street || (btr && `{{ ${templateName}.street }}`)}</dd>
+    {btr && `{{`+`/${templateName}.street}}`}
+
+    {btr && `{{`+`#${templateName}.town}}`}
+    <dd>{location?.town || (btr && `{{ ${templateName}.town }}`)}</dd>
+    {btr && `{{`+`/${templateName}.town}}`}
+
+    {btr && `{{`+`#${templateName}.town_location}}`}
+    <dd>{location?.town_location || (btr && `{{ ${templateName}.town_location 
}}`)}</dd>
+    {btr && `{{`+`/${templateName}.town_location}}`}
   </Fragment>
 }
 
 export function ShowOrderDetails({ order_summary, refund_amount, 
contract_terms, btr }: Props): VNode {
-  const productList = (btr ? [{} as Product] : (contract_terms?.products || 
[]))
+  const productList = (btr ? [{} as MerchantBackend.Product] : 
(contract_terms?.products || []))
+  const auditorsList = (btr ? [{} as MerchantBackend.Auditor] : 
(contract_terms?.auditors || []))
+  const exchangesList = (btr ? [{} as MerchantBackend.Exchange] : 
(contract_terms?.exchanges || []))
+  const hasDeliveryInfo = btr || !!contract_terms?.delivery_date || 
!!contract_terms?.delivery_location
+
   return <Page>
     <header>
       <h1>Details of order {contract_terms?.order_id || `{{ 
contract_terms.order_id }}`}</h1>
@@ -84,72 +127,46 @@ export function ShowOrderDetails({ order_summary, 
refund_amount, contract_terms,
           <dd>{contract_terms?.summary || `{{ contract_terms.summary }}`}</dd>
           <dt>Amount paid:</dt>
           <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd>
+          <dt>Order date:</dt>
+          <dd>{contract_terms?.timestamp ?
+            (contract_terms?.timestamp.t_ms != 'never' ?
+              format(contract_terms?.timestamp.t_ms, 'dd MMM yyyy HH:mm:ss') :
+              'never')
+            : `{{ contract_terms.timestamp_str }}`} </dd>
           <dt>Merchant name:</dt>
           <dd>{contract_terms?.merchant.name || `{{ 
contract_terms.merchant.name }}`}</dd>
-
-          {btr && `{{#contract_terms.delivery_location}}`}
-          {(btr || contract_terms?.delivery_location) && <Fragment>
-            <dt>Delivery address:</dt>
-
-            {btr && `{{#contract_terms.delivery_location.building_name}}`}
-              <dd>{contract_terms?.delivery_location?.building_name || `{{ 
contract_terms.delivery_location.building_name }}`} 
{contract_terms?.delivery_location?.building_number || `{{ 
contract_terms.delivery_location.building_number }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.building_name}}`}
-
-            {btr && `{{#contract_terms.delivery_location.country}}`}
-              <dd>{contract_terms?.delivery_location?.country || `{{ 
contract_terms.delivery_location.country }}`} 
{contract_terms?.delivery_location?.country_subdivision || `{{ 
contract_terms.delivery_location.country_subdivision }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.country}}`}
-
-            {btr && `{{#contract_terms.delivery_location.district}}`}
-              <dd>{contract_terms?.delivery_location?.district || `{{ 
contract_terms.delivery_location.district }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.district}}`}
-
-            {btr && `{{#contract_terms.delivery_location.post_code}}`}
-              <dd>{contract_terms?.delivery_location?.post_code || `{{ 
contract_terms.delivery_location.post_code }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.post_code}}`}
-
-            {btr && `{{#contract_terms.delivery_location.street}}`}
-              <dd>{contract_terms?.delivery_location?.street || `{{ 
contract_terms.delivery_location.street }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.street}}`}
-
-            {btr && `{{#contract_terms.delivery_location.town}}`}
-              <dd>{contract_terms?.delivery_location?.town || `{{ 
contract_terms.delivery_location.town }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.town}}`}
-
-            {btr && `{{#contract_terms.delivery_location.town_location}}`}
-              <dd>{contract_terms?.delivery_location?.town_location || `{{ 
contract_terms.delivery_location.town_location }}`}</dd>
-            {btr && `{{/contract_terms.delivery_location.town_location}}`}
-          </Fragment>}
-          {btr && `{{/contract_terms.delivery_location}}`}
-
-          {btr && `{{#contract_terms.delivery_date}}`}
-          {(btr || contract_terms?.delivery_date) && <Fragment>
-            <dt>Delivery date:</dt>
-            <dd>{contract_terms?.delivery_date ?
-              (contract_terms?.delivery_date.t_ms != 'never' ?
-                format(contract_terms?.delivery_date.t_ms, 'dd MMM yyyy 
HH:mm:ss') :
-                'never')
-              : `{{ contract_terms.delivery_date }}`} </dd>
-
-          </Fragment>}
-          {btr && `{{/contract_terms.delivery_date}}`}
         </TableExpanded>
       </section>
 
-      {btr && `{{#contract_terms.products.0}}`}
+      {btr && `{{#contract_terms.hasProducts}}`}
       {!productList.length ? null : <section>
         <h2>Products purchased</h2>
         <TableSimple>
-          {btr && `{{#contract_terms.products}}`}
+          {btr && '{{' + '#contract_terms.products' + '}}'}
           {productList.map((p, i) => {
+            const taxList = (btr ? [{} as MerchantBackend.Tax] : (p.taxes || 
[]))
+
             return <Fragment key={i}>
               <p>{p.description || `{{description}}`}</p>
               <dl>
-
-                <dt>Amount:</dt>
-                <dd>{p.quantity || `{{description}}`}</dd>
+                <dt>Quantity:</dt>
+                <dd>{p.quantity || `{{quantity}}`}</dd>
 
                 <dt>Price:</dt>
-                <dd>{p.price || `{{quantity}}`}</dd>
+                <dd>{p.price || `{{price}}`}</dd>
+
+                {btr && `{{#hasTaxes}}`}
+                {!taxList.length ? null : <Fragment>
+                  {btr && '{{' + '#taxes' + '}}'}
+                  {taxList.map((t, i) => {
+                    return <Fragment key={i}>
+                      <dt>{t.name || `{{name}}`}</dt>
+                      <dd>{t.tax || `{{tax}}`}</dd>
+                    </Fragment>
+                  })}
+                  {btr && '{{' + '/taxes' + '}}'}
+                </Fragment>}
+                {btr && `{{/hasTaxes}}`}
 
                 {btr && `{{#delivery_date}}`}
                 {(btr || p.delivery_date) && <Fragment>
@@ -158,18 +175,181 @@ export function ShowOrderDetails({ order_summary, 
refund_amount, contract_terms,
                     (p.delivery_date.t_ms != 'never' ?
                       format(p.delivery_date.t_ms, 'dd MMM yyyy HH:mm:ss') :
                       'never')
-                    : `{{ delivery_date }}`} </dd>
+                    : `{{ delivery_date_str }}`} </dd>
                 </Fragment>}
                 {btr && `{{/delivery_date}}`}
 
+                {btr && `{{#unit}}`}
+                {(btr || p.unit) && <Fragment>
+                  <dt>Product unit:</dt>
+                  <dd>{p.unit || `{{.}}`}</dd>
+                </Fragment>}
+                {btr && `{{/unit}}`}
+
+                {btr && `{{#product_id}}`}
+                {(btr || p.product_id) && <Fragment>
+                  <dt>Product ID:</dt>
+                  <dd>{p.product_id || `{{.}}`}</dd>
+                </Fragment>}
+                {btr && `{{/product_id}}`}
+
               </dl>
             </Fragment>
           })}
-          {btr && `{{/contract_terms.products}}`}
+          {btr && '{{' + '/contract_terms.products' + '}}'}
         </TableSimple>
 
       </section>}
-      {btr && `{{/contract_terms.products.0}}`}
+      {btr && `{{/contract_terms.hasProducts}}`}
+
+
+      {btr && `{{#contract_terms.has_delivery_info}}`}
+      {!hasDeliveryInfo ? null : <section>
+        <h2>Delivery information</h2>
+        <TableExpanded>
+          {btr && `{{#contract_terms.delivery_date}}`}
+          {(btr || contract_terms?.delivery_date) && <Fragment>
+            <dt>Delivery date:</dt>
+            <dd>{contract_terms?.delivery_date ?
+              (contract_terms?.delivery_date.t_ms != 'never' ?
+                format(contract_terms?.delivery_date.t_ms, 'dd MMM yyyy 
HH:mm:ss') :
+                'never')
+              : `{{ contract_terms.delivery_date_str }}`} </dd>
+
+          </Fragment>}
+          {btr && `{{/contract_terms.delivery_date}}`}
+
+          {btr && `{{#contract_terms.delivery_location}}`}
+          {(btr || contract_terms?.delivery_location) && <Fragment>
+            <dt>Delivery address:</dt>
+            <Location btr={btr} location={contract_terms?.delivery_location} 
templateName="contract_terms.delivery_location" />
+          </Fragment>}
+          {btr && `{{/contract_terms.delivery_location}}`}
+        </TableExpanded>
+      </section>}
+      {btr && `{{/contract_terms.has_delivery_info}}`}
+
+      <section>
+        <h2>Full payment information</h2>
+        <TableExpanded>
+          <dt>Amount paid:</dt>
+          <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd>
+          <dt>Wire transfer method:</dt>
+          <dd>{contract_terms?.wire_method || `{{ contract_terms.wire_method 
}}`}</dd>
+          <dt>Payment deadline:</dt>
+          <dd>{contract_terms?.pay_deadline ?
+            (contract_terms?.pay_deadline.t_ms != 'never' ?
+              format(contract_terms?.pay_deadline.t_ms, 'dd MMM yyyy 
HH:mm:ss') :
+              'never')
+            : `{{ contract_terms.pay_deadline_str }}`} </dd>
+          <dt>Exchange transfer deadline:</dt>
+          <dd>{contract_terms?.wire_transfer_deadline ?
+            (contract_terms?.wire_transfer_deadline.t_ms != 'never' ?
+              format(contract_terms?.wire_transfer_deadline.t_ms, 'dd MMM yyyy 
HH:mm:ss') :
+              'never')
+            : `{{ contract_terms.wire_transfer_deadline_str }}`} </dd>
+          <dt>Maximum deposit fee:</dt>
+          <dd>{contract_terms?.max_fee || `{{ contract_terms.max_fee }}`}</dd>
+          <dt>Maximum wire fee:</dt>
+          <dd>{contract_terms?.max_wire_fee || `{{ contract_terms.max_wire_fee 
}}`}</dd>
+          <dt>Wire fee amortization:</dt>
+          <dd>{contract_terms?.wire_fee_amortization || `{{ 
contract_terms.wire_fee_amortization }}`} transactions</dd>
+        </TableExpanded>
+      </section>
+
+      <section>
+        <h2>Refund information</h2>
+        <TableExpanded>
+          <dt>Refund deadline:</dt>
+          <dd>{contract_terms?.refund_deadline ?
+            (contract_terms?.refund_deadline.t_ms != 'never' ?
+              format(contract_terms?.refund_deadline.t_ms, 'dd MMM yyyy 
HH:mm:ss') :
+              'never')
+            : `{{ contract_terms.refund_deadline_str }}`} </dd>
+
+          {btr && `{{#contract_terms.auto_refund}}`}
+          {(btr || contract_terms?.auto_refund) && <Fragment>
+            <dt>Attempt autorefund for:</dt>
+            <dd>{contract_terms?.auto_refund ?
+              (contract_terms?.auto_refund.d_ms != 'forever' ?
+                formatDuration(intervalToDuration({ start: 0, end: 
contract_terms?.auto_refund.d_ms })) :
+                'forever')
+              : `{{ contract_terms.auto_refund_str }}`} </dd>
+          </Fragment>}
+          {btr && `{{/contract_terms.auto_refund}}`}
+        </TableExpanded>
+      </section>
+
+      <section>
+        <h2>Additional order details</h2>
+        <TableExpanded>
+          <dt>Public reorder URL:</dt>
+          <dd> -- not defined yet -- </dd>
+          {btr && `{{#contract_terms.fulfillment_url}}`}
+          {(btr || contract_terms?.fulfillment_url) && <Fragment>
+            <dt>Fulfillment URL:</dt>
+            <dd>{contract_terms?.fulfillment_url || (btr && `{{ 
contract_terms.fulfillment_url }}`)}</dd>
+          </Fragment>}
+          {btr && `{{/contract_terms.fulfillment_url}}`}
+          {/* <dt>Fulfillment message:</dt>
+          <dd> -- not defined yet -- </dd> */}
+        </TableExpanded>
+      </section>
+
+      <section>
+        <h2>Full merchant information</h2>
+        <TableExpanded>
+          <dt>Merchant name:</dt>
+          <dd>{contract_terms?.merchant.name || `{{ 
contract_terms.merchant.name }}`}</dd>
+          <dt>Merchant address:</dt>
+          <Location btr={btr} location={contract_terms?.merchant.address} 
templateName="contract_terms.merchant.address" />
+          <dt>Merchant's jurisdiction:</dt>
+          <Location btr={btr} location={contract_terms?.merchant.jurisdiction} 
templateName="contract_terms.merchant.jurisdiction" />
+          <dt>Merchant URI:</dt>
+          <dd>{contract_terms?.merchant_base_url || `{{ 
contract_terms.merchant_base_url }}`}</dd>
+          <dt>Merchant's public key:</dt>
+          <dd>{contract_terms?.merchant_pub || `{{ contract_terms.merchant_pub 
}}`}</dd>
+          {/* <dt>Merchant's hash:</dt>
+          <dd> -- not defined yet -- </dd> */}
+        </TableExpanded>
+      </section>
+
+      {btr && `{{#contract_terms.hasAuditors}}`}
+      {!auditorsList.length ? null : <section>
+        <h2>Auditors accepted by the merchant</h2>
+        <TableExpanded>
+          {btr && '{{' + '#contract_terms.auditors' + '}}'}
+          {auditorsList.map((p, i) => {
+            return <Fragment key={i}>
+              <p>{p.name || `{{name}}`}</p>
+              <dt>Auditor's public key:</dt>
+              <dd>{p.auditor_pub || `{{auditor_pub}}`}</dd>
+              <dt>Auditor's URL:</dt>
+              <dd>{p.url || `{{url}}`}</dd>
+            </Fragment>
+          })}
+          {btr && '{{' + '/contract_terms.auditors' + '}}'}
+        </TableExpanded>
+      </section>}
+      {btr && `{{/contract_terms.hasAuditors}}`}
+
+      {btr && `{{#contract_terms.hasExchanges}}`}
+      {!exchangesList.length ? null : <section>
+        <h2>Exchanges accepted by the merchant</h2>
+        <TableExpanded>
+          {btr && '{{' + '#contract_terms.exchanges' + '}}'}
+          {exchangesList.map((p, i) => {
+            return <Fragment key={i}>
+              <dt>Exchange's URL:</dt>
+              <dd>{p.url || `{{url}}`}</dd>
+              <dt>Public key:</dt>
+              <dd>{p.master_pub || `{{master_pub}}`}</dd>
+            </Fragment>
+          })}
+          {btr && '{{' + '/contract_terms.exchanges' + '}}'}
+        </TableExpanded>
+      </section>}
+      {btr && `{{/contract_terms.hasExchanges}}`}
     </section>
 
     <Footer />
@@ -188,7 +368,13 @@ export function mount(): void {
     const ra = fromLocation.get('refund_amount') || undefined;
     const ct = fromLocation.get('contract_terms') || undefined;
 
+    let contractTerms: MerchantBackend.ContractTerms | undefined;
+    try {
+      contractTerms = JSON.parse((window as any).contractTermsStr)
+    } catch { }
+
     render(<ShowOrderDetails
+      contract_terms={contractTerms}
       order_summary={os} refund_amount={ra}
     />, document.body);
 
diff --git a/packages/backend/tests/__mocks__/fileTransformer.js 
b/packages/backend/tests/__mocks__/fileTransformer.js
index e6193f8..51ebbfa 100644
--- a/packages/backend/tests/__mocks__/fileTransformer.js
+++ b/packages/backend/tests/__mocks__/fileTransformer.js
@@ -25,7 +25,7 @@ const path = require('path');
 
 module.exports = {
     process(src, filename, config, options) {
-        return 'module.exports = ' + JSON.stringify(path.basename(filename)) + 
';';
+        return `module.exports = ${  JSON.stringify(path.basename(filename))  
};`;
     },
 };
 
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e92d486..8ae4ae2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -38,6 +38,7 @@ importers:
       '@types/history': ^4.7.8
       '@types/jest': ^26.0.23
       '@types/mocha': ^8.2.2
+      '@types/mustache': ^4.1.2
       '@typescript-eslint/eslint-plugin': ^4.22.0
       '@typescript-eslint/parser': ^4.22.0
       axios: ^0.21.1
@@ -128,6 +129,7 @@ importers:
       '@types/history': 4.7.8
       '@types/jest': 26.0.23
       '@types/mocha': 8.2.2
+      '@types/mustache': 4.1.2
       '@typescript-eslint/eslint-plugin': 
4.22.0_e3b52a83531895e7febd6ecd5ba813eb
       '@typescript-eslint/parser': 4.22.0_eslint@7.25.0+typescript@4.2.4
       babel-loader: 8.2.2_@babel+core@7.13.16
@@ -4178,6 +4180,10 @@ packages:
     resolution: {integrity: 
sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==}
     dev: true
 
+  /@types/mustache/4.1.2:
+    resolution: {integrity: 
sha512-c4OVMMcyodKQ9dpwBwh3ofK9P6U9ZktKU9S+p33UqwMNN1vlv2P0zJZUScTshnx7OEoIIRcCFNQ904sYxZz8kg==}
+    dev: true
+
   /@types/node-fetch/2.5.10:
     resolution: {integrity: 
sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==}
     dependencies:

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