diff options
author | Sebastian <sebasjm@gmail.com> | 2022-05-11 17:02:21 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-05-11 17:02:21 -0300 |
commit | 3c0355ff41c77b780ac34c39e9c2c7556b7db6f7 (patch) | |
tree | 8a57f3087b90c9c3ea40da1651e8b24e96421ad3 /packages | |
parent | db548d9a8a69f085561d029a3782bb0dcee64d09 (diff) | |
download | merchant-backoffice-3c0355ff41c77b780ac34c39e9c2c7556b7db6f7.tar.gz merchant-backoffice-3c0355ff41c77b780ac34c39e9c2c7556b7db6f7.tar.bz2 merchant-backoffice-3c0355ff41c77b780ac34c39e9c2c7556b7db6f7.zip |
show refund taken in order details
Diffstat (limited to 'packages')
4 files changed, 114 insertions, 42 deletions
diff --git a/packages/merchant-backoffice/src/declaration.d.ts b/packages/merchant-backoffice/src/declaration.d.ts index 6699601..9b06f8f 100644 --- a/packages/merchant-backoffice/src/declaration.d.ts +++ b/packages/merchant-backoffice/src/declaration.d.ts @@ -766,6 +766,9 @@ export namespace MerchantBackend { // When was the refund approved. timestamp: Timestamp; + // Set to true if a refund is still available for the wallet for this payment. + pending: boolean; + // Total amount that was refunded (minus a refund fee). amount: Amount; } 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 9671bfd..4bb7051 100644 --- a/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx +++ b/packages/merchant-backoffice/src/paths/instance/orders/details/DetailPage.tsx @@ -49,7 +49,9 @@ interface Props { onRefund: (id: string, value: MerchantBackend.Orders.RefundRequest) => void; } -type Paid = MerchantBackend.Orders.CheckPaymentPaidResponse; +type Paid = MerchantBackend.Orders.CheckPaymentPaidResponse & { + refund_taken: string; +}; type Unpaid = MerchantBackend.Orders.CheckPaymentUnpaidResponse; type Claimed = MerchantBackend.Orders.CheckPaymentClaimedResponse; @@ -366,7 +368,7 @@ function PaidPage({ events.push({ when: new Date(e.timestamp.t_s * 1000), description: `refund: ${e.amount}: ${e.reason}`, - type: "refund", + type: e.pending ? "refund" : "refund-taken", }); } }); @@ -426,6 +428,13 @@ function PaidPage({ new Date().getTime() < order.contract_terms.refund_deadline.t_s * 1000; const i18n = useTranslator(); + const amount = Amounts.parseOrThrow(order.contract_terms.amount); + const refund_taken = order.refund_details.reduce((prev, cur) => { + if (cur.pending) return prev; + return Amounts.add(prev, Amounts.parseOrThrow(cur.amount)).amount; + }, Amounts.getZero(amount.currency)); + value.refund_taken = Amounts.stringify(refund_taken); + return ( <div> <section class="section"> @@ -544,6 +553,13 @@ function PaidPage({ label={i18n`Refunded amount`} /> )} + {order.refunded && ( + <InputCurrency<Paid> + name="refund_taken" + readonly + label={i18n`Refund taken`} + /> + )} <Input<Paid> name="order_status" readonly diff --git a/packages/merchant-backoffice/src/paths/instance/orders/details/Timeline.tsx b/packages/merchant-backoffice/src/paths/instance/orders/details/Timeline.tsx index 34271a4..bea6560 100644 --- a/packages/merchant-backoffice/src/paths/instance/orders/details/Timeline.tsx +++ b/packages/merchant-backoffice/src/paths/instance/orders/details/Timeline.tsx @@ -18,59 +18,111 @@ import { h } from "preact"; import { useEffect, useState } from "preact/hooks"; interface Props { - events: Event[] + events: Event[]; } -export function Timeline({ events:e }: Props) { - const events = [...e] +export function Timeline({ events: e }: Props) { + const events = [...e]; events.push({ when: new Date(), - description: 'now', - type: 'now' - }) + description: "now", + type: "now", + }); - events.sort((a, b) => a.when.getTime() - b.when.getTime()) + events.sort((a, b) => a.when.getTime() - b.when.getTime()); - const [state, setState] = useState(events) + const [state, setState] = useState(events); useEffect(() => { const handle = setTimeout(() => { - const eventsWithoutNow = state.filter(e => e.type !== 'now') + const eventsWithoutNow = state.filter((e) => e.type !== "now"); eventsWithoutNow.push({ when: new Date(), - description: 'now', - type: 'now' - }) - setState(eventsWithoutNow) - },1000) + description: "now", + type: "now", + }); + setState(eventsWithoutNow); + }, 1000); return () => { - clearTimeout(handle) - } - }) - return <div class="timeline"> - {events.map((e,i) => { - return <div key={i} class="timeline-item"> - {(() => { - switch (e.type) { - case "deadline": return <div class="timeline-marker is-icon "><i class="mdi mdi-flag" /></div> - case "delivery": return <div class="timeline-marker is-icon "><i class="mdi mdi-delivery" /></div> - case "start": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-flag " /></div> - case "wired": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-cash" /></div> - case "wired-range": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-cash" /></div> - case "refund": return <div class="timeline-marker is-icon is-danger"><i class="mdi mdi-cash" /></div> - case "now": return <div class="timeline-marker is-icon is-info"><i class="mdi mdi-clock" /></div> - } - })()} - <div class="timeline-content"> - <p class="heading">{format(e.when, 'yyyy/MM/dd HH:mm:ss')}</p> - <p>{e.description}</p> - </div> - </div> - })} - </div >; - + clearTimeout(handle); + }; + }); + return ( + <div class="timeline"> + {events.map((e, i) => { + return ( + <div key={i} class="timeline-item"> + {(() => { + switch (e.type) { + case "deadline": + return ( + <div class="timeline-marker is-icon "> + <i class="mdi mdi-flag" /> + </div> + ); + case "delivery": + return ( + <div class="timeline-marker is-icon "> + <i class="mdi mdi-delivery" /> + </div> + ); + case "start": + return ( + <div class="timeline-marker is-icon is-success"> + <i class="mdi mdi-flag " /> + </div> + ); + case "wired": + return ( + <div class="timeline-marker is-icon is-success"> + <i class="mdi mdi-cash" /> + </div> + ); + case "wired-range": + return ( + <div class="timeline-marker is-icon is-success"> + <i class="mdi mdi-cash" /> + </div> + ); + case "refund": + return ( + <div class="timeline-marker is-icon is-danger"> + <i class="mdi mdi-cash" /> + </div> + ); + case "refund-taken": + return ( + <div class="timeline-marker is-icon is-success"> + <i class="mdi mdi-cash" /> + </div> + ); + case "now": + return ( + <div class="timeline-marker is-icon is-info"> + <i class="mdi mdi-clock" /> + </div> + ); + } + })()} + <div class="timeline-content"> + <p class="heading">{format(e.when, "yyyy/MM/dd HH:mm:ss")}</p> + <p>{e.description}</p> + </div> + </div> + ); + })} + </div> + ); } export interface Event { when: Date; description: string; - type: 'start' | 'refund' | 'wired' | 'wired-range' |'deadline' | 'delivery' | 'now' + type: + | "start" + | "refund" + | "refund-taken" + | "wired" + | "wired-range" + | "deadline" + | "delivery" + | "now"; } diff --git a/packages/merchant-backoffice/src/utils/amount.ts b/packages/merchant-backoffice/src/utils/amount.ts index 85f2304..61e3312 100644 --- a/packages/merchant-backoffice/src/utils/amount.ts +++ b/packages/merchant-backoffice/src/utils/amount.ts @@ -41,6 +41,7 @@ export function mergeRefunds(prev: MerchantBackend.Orders.RefundDetails[], cur: cur.timestamp.t_s === 'never' || //current doesnt have timestamp (tail = prev[prev.length - 1]).timestamp.t_s === 'never' || // last doesnt have timestamp cur.reason !== tail.reason || //different reason + cur.pending !== tail.pending || //different pending state Math.abs(cur.timestamp.t_s - tail.timestamp.t_s) > 1000 * 60) {//more than 1 minute difference prev.push(cur) |