/* 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 */ /** * * @author Sebastian Javier Marchano (sebasjm) */ 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"; import "../css/pure-min.css"; import "../css/style.css"; import { MerchantBackend } from "../declaration"; import { Page, InfoBox, TableExpanded, TableSimple } from "../styled"; import { TIME_DATE_FORMAT } from "../utils"; /** * This page creates a payment request QR code * * It will build into a mustache html template for server side rendering * * server side rendering params: * - order_summary * - contract_terms * - refund_amount * * request params: * - refund_amount * - contract_terms * - order_summary */ export interface Props { btr?: boolean; // build time rendering flag order_summary?: string; refund_amount?: string; contract_terms?: MerchantBackend.ContractTerms; } function Head({ order_summary }: { order_summary?: string }): VNode { return ( Status of your order for{" "} {order_summary ? order_summary : `{{ order_summary }}`} ); } function Location({ templateName, location, btr, }: { templateName: string; location: MerchantBackend.Location | undefined; btr?: boolean; }) { //FIXME: mustache strings will 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 ( {btr && `{{` + `#${templateName}.building_name}}`}
{location?.building_name || (btr && `{{ ${templateName}.building_name }}`)}{" "} {location?.building_number || (btr && `{{ ${templateName}.building_number }}`)}
{btr && `{{` + `/${templateName}.building_name}}`} {btr && `{{` + `#${templateName}.country}}`}
{location?.country || (btr && `{{ ${templateName}.country }}`)}{" "} {location?.country_subdivision || (btr && `{{ ${templateName}.country_subdivision }}`)}
{btr && `{{` + `/${templateName}.country}}`} {btr && `{{` + `#${templateName}.district}}`}
{location?.district || (btr && `{{ ${templateName}.district }}`)}
{btr && `{{` + `/${templateName}.district}}`} {btr && `{{` + `#${templateName}.post_code}}`}
{location?.post_code || (btr && `{{ ${templateName}.post_code }}`)}
{btr && `{{` + `/${templateName}.post_code}}`} {btr && `{{` + `#${templateName}.street}}`}
{location?.street || (btr && `{{ ${templateName}.street }}`)}
{btr && `{{` + `/${templateName}.street}}`} {btr && `{{` + `#${templateName}.town}}`}
{location?.town || (btr && `{{ ${templateName}.town }}`)}
{btr && `{{` + `/${templateName}.town}}`} {btr && `{{` + `#${templateName}.town_location}}`}
{location?.town_location || (btr && `{{ ${templateName}.town_location }}`)}
{btr && `{{` + `/${templateName}.town_location}}`}
); } export function ShowOrderDetails({ order_summary, refund_amount, contract_terms, btr, }: Props): VNode { 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 (

Details of order{" "} {contract_terms?.order_id || `{{ contract_terms.order_id }}`}

{btr && `{{#refund_amount}}`} {(btr || refund_amount) && (
Refunded: The merchant refunded you{" "} {refund_amount || `{{ refund_amount }}`}.
)} {btr && `{{/refund_amount}}`} {btr && `{{#contract_terms.fulfillment_message}}`} {(btr || contract_terms?.fulfillment_message) && (
{contract_terms?.fulfillment_message || `{{ contract_terms.fulfillment_message }}`}.
)} {btr && `{{/contract_terms.fulfillment_message}}`}
Order summary:
{contract_terms?.summary || `{{ contract_terms.summary }}`}
{btr && `{{#contract_terms.fulfillment_url}}`}
Fulfillment URL:
{contract_terms?.fulfillment_url || `{{ contract_terms.fulfillment_url }}`}
{btr && `{{/contract_terms.fulfillment_url}}`}
Amount paid:
{contract_terms?.amount || `{{ contract_terms.amount }}`}
Order date:
{contract_terms?.timestamp ? contract_terms?.timestamp.t_s != "never" ? format( contract_terms?.timestamp.t_s * 1000, TIME_DATE_FORMAT, ) : "never" : `{{ contract_terms.timestamp_str }}`}{" "}
Merchant name:
{contract_terms?.merchant.name || `{{ contract_terms.merchant.name }}`}
{btr && `{{#contract_terms.hasProducts}}`} {!productList.length ? null : (

Products purchased

{btr && "{{" + "#contract_terms.products" + "}}"} {productList.map((p, i) => { const taxList = btr ? [{} as MerchantBackend.Tax] : p.taxes || []; return (

{p.description || `{{description}}`}

Quantity:
{p.quantity || `{{quantity}}`}
Price:
{p.price || `{{price}}`}
{btr && `{{#hasTaxes}}`} {!taxList.length ? null : ( {btr && "{{" + "#taxes" + "}}"} {taxList.map((t, i) => { return (
{t.name || `{{name}}`}
{t.tax || `{{tax}}`}
); })} {btr && "{{" + "/taxes" + "}}"}
)} {btr && `{{/hasTaxes}}`} {btr && `{{#delivery_date}}`} {(btr || p.delivery_date) && (
Delivered on:
{p.delivery_date ? p.delivery_date.t_s != "never" ? format( p.delivery_date.t_s, TIME_DATE_FORMAT, ) : "never" : `{{ delivery_date_str }}`}{" "}
)} {btr && `{{/delivery_date}}`} {btr && `{{#unit}}`} {(btr || p.unit) && (
Product unit:
{p.unit || `{{.}}`}
)} {btr && `{{/unit}}`} {btr && `{{#product_id}}`} {(btr || p.product_id) && (
Product ID:
{p.product_id || `{{.}}`}
)} {btr && `{{/product_id}}`}
); })} {btr && "{{" + "/contract_terms.products" + "}}"}
)} {btr && `{{/contract_terms.hasProducts}}`} {btr && `{{#contract_terms.has_delivery_info}}`} {!hasDeliveryInfo ? null : (

Delivery information

{btr && `{{#contract_terms.delivery_date}}`} {(btr || contract_terms?.delivery_date) && (
Delivery date:
{contract_terms?.delivery_date ? contract_terms?.delivery_date.t_s != "never" ? format( contract_terms?.delivery_date.t_s, TIME_DATE_FORMAT, ) : "never" : `{{ contract_terms.delivery_date_str }}`}{" "}
)} {btr && `{{/contract_terms.delivery_date}}`} {btr && `{{#contract_terms.delivery_location}}`} {(btr || contract_terms?.delivery_location) && (
Delivery address:
)} {btr && `{{/contract_terms.delivery_location}}`}
)} {btr && `{{/contract_terms.has_delivery_info}}`}

Full payment information

Exchange transfer deadline:
{btr && `{{` + `#contract_terms.wire_transfer_deadline_str}}`}
{contract_terms?.wire_transfer_deadline ? contract_terms?.wire_transfer_deadline.t_s != "never" ? format( contract_terms?.wire_transfer_deadline.t_s * 1000, TIME_DATE_FORMAT, ) : "never" : `{{ contract_terms.wire_transfer_deadline_str }}`}{" "}
{btr && `{{` + `/contract_terms.wire_transfer_deadline_str}}`} {btr && `{{` + `^contract_terms.wire_transfer_deadline_str}}`}
Wire transfer settled.
{btr && `{{` + `/contract_terms.wire_transfer_deadline_str}}`} {btr && `{{` + `#contract_terms.max_fee}}`}
Maximum deposit fee:
{contract_terms?.max_fee || `{{ contract_terms.max_fee }}`}
{btr && `{{` + `/contract_terms.max_fee}}`} {btr && `{{` + `#contract_terms.max_wire_fee}}`}
Maximum wire fee:
{contract_terms?.max_wire_fee || `{{ contract_terms.max_wire_fee }}`}
{btr && `{{` + `/contract_terms.max_wire_fee}}`} {btr && `{{` + `#contract_terms.wire_fee_amortization}}`}
Wire fee amortization:
{contract_terms?.wire_fee_amortization || `{{ contract_terms.wire_fee_amortization }}`}{" "} transactions
{btr && `{{` + `/contract_terms.wire_fee_amortization}}`}

Refund information

Refund deadline:
{contract_terms?.refund_deadline ? contract_terms?.refund_deadline.t_s != "never" ? format( contract_terms?.refund_deadline.t_s * 1000, TIME_DATE_FORMAT, ) : "never" : `{{ contract_terms.refund_deadline_str }}`}{" "}
{btr && `{{#contract_terms.auto_refund}}`} {(btr || contract_terms?.auto_refund) && (
Attempt autorefund for:
{contract_terms?.auto_refund ? contract_terms?.auto_refund.d_us != "forever" ? formatDuration( intervalToDuration({ start: 0, end: contract_terms?.auto_refund.d_us, }), ) : "forever" : `{{ contract_terms.auto_refund_str }}`}{" "}
)} {btr && `{{/contract_terms.auto_refund}}`}

Additional order details

Public reorder URL:
-- not defined yet --
{btr && `{{#contract_terms.fulfillment_url}}`} {(btr || contract_terms?.fulfillment_url) && (
Fulfillment URL:
{contract_terms?.fulfillment_url || (btr && `{{ contract_terms.fulfillment_url }}`)}
)} {btr && `{{/contract_terms.fulfillment_url}}`} {/*
Fulfillment message:
-- not defined yet --
*/}

Full merchant information

Merchant name:
{contract_terms?.merchant.name || `{{ contract_terms.merchant.name }}`}
Merchant address:
Merchant's jurisdiction:
Merchant URI:
{contract_terms?.merchant_base_url || `{{ contract_terms.merchant_base_url }}`}
Merchant's public key:
{contract_terms?.merchant_pub || `{{ contract_terms.merchant_pub }}`}
{/*
Merchant's hash:
-- not defined yet --
*/}
{btr && `{{#contract_terms.hasAuditors}}`} {!auditorsList.length ? null : (

Auditors accepted by the merchant

{btr && "{{" + "#contract_terms.auditors" + "}}"} {auditorsList.map((p, i) => { return (

{p.name || `{{name}}`}

Auditor's public key:
{p.auditor_pub || `{{auditor_pub}}`}
Auditor's URL:
{p.url || `{{url}}`}
); })} {btr && "{{" + "/contract_terms.auditors" + "}}"}
)} {btr && `{{/contract_terms.hasAuditors}}`} {btr && `{{#contract_terms.hasExchanges}}`} {!exchangesList.length ? null : (

Exchanges accepted by the merchant

{btr && "{{" + "#contract_terms.exchanges" + "}}"} {exchangesList.map((p, i) => { return (
Exchange's URL:
{p.url || `{{url}}`}
Public key:
{p.master_pub || `{{master_pub}}`}
); })} {btr && "{{" + "/contract_terms.exchanges" + "}}"}
)} {btr && `{{/contract_terms.hasExchanges}}`}