@final-commerce/command-frame 0.5.0-preprod.1 → 0.5.0-preprod.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/calculate-refund-total/action.js +2 -2
- package/dist/actions/can-transition/types.d.ts +1 -1
- package/dist/actions/cash-payment/types.d.ts +6 -3
- package/dist/actions/get-refund-plan/mock.d.ts +5 -0
- package/dist/actions/get-refund-plan/mock.js +24 -0
- package/dist/actions/get-refund-plan/types.d.ts +92 -0
- package/dist/actions/get-refund-plan/types.js +6 -0
- package/dist/actions/get-refunds/types.d.ts +1 -1
- package/dist/actions/get-remaining-refundable-quantities/action.js +2 -2
- package/dist/actions/get-remaining-refundable-quantities/mock.js +2 -0
- package/dist/actions/get-remaining-refundable-quantities/types.d.ts +13 -0
- package/dist/actions/initiate-refund/types.d.ts +6 -0
- package/dist/actions/process-partial-refund/mock.d.ts +1 -1
- package/dist/actions/process-partial-refund/mock.js +14 -5
- package/dist/actions/process-partial-refund/types.d.ts +65 -5
- package/dist/actions/remove-product-fee/types.d.ts +10 -1
- package/dist/actions/select-all-refund-items/action.js +2 -2
- package/dist/actions/set-active-refund/types.d.ts +1 -1
- package/dist/actions/set-refund-stock-action/types.d.ts +1 -1
- package/dist/actions/tap-to-pay-payment/types.d.ts +6 -3
- package/dist/actions/void-order/types.d.ts +4 -3
- package/dist/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* Calls the calculateRefundTotal action on the parent window
|
|
4
4
|
*/
|
|
5
5
|
import { commandFrameClient } from "../../client";
|
|
6
|
-
export const calculateRefundTotal = async () => {
|
|
7
|
-
return await commandFrameClient.call("calculateRefundTotal");
|
|
6
|
+
export const calculateRefundTotal = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("calculateRefundTotal", params);
|
|
8
8
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CFStatePair, CFTransitionResult } from "../../common-types/order-state";
|
|
2
2
|
export interface CanTransitionParams {
|
|
3
|
-
/** Order to evaluate.
|
|
3
|
+
/** Order to evaluate. Defaults to the active order; if there is no active order (or none matches), evaluates as a brand-new order (from = null). */
|
|
4
4
|
orderId?: string;
|
|
5
5
|
/** Target state pair to transition to. */
|
|
6
6
|
to: CFStatePair;
|
|
@@ -3,14 +3,17 @@ export interface CashPaymentParams {
|
|
|
3
3
|
/**
|
|
4
4
|
* The amount to pay with this tender, in integer MINOR currency units
|
|
5
5
|
* (e.g. 1575 = $15.75 — see `getContext().minorUnits` for the currency's
|
|
6
|
-
* exponent). Required
|
|
7
|
-
*
|
|
6
|
+
* exponent). Required whenever the balance due is greater than $0; may be
|
|
7
|
+
* omitted only on a cart that already nets to a $0 balance due (e.g. fully
|
|
8
|
+
* discounted), where it defaults to 0. Semantics against the cart's
|
|
9
|
+
* balance due:
|
|
10
|
+
* - missing → error, unless the balance due is $0 (→ 0)
|
|
8
11
|
* - less than balance → partial payment (the POS enters a fixed
|
|
9
12
|
* split-payment leg for this amount)
|
|
10
13
|
* - equal to balance → full payment
|
|
11
14
|
* - more than balance → error (overpayment is `tenderedAmount`'s job)
|
|
12
15
|
*/
|
|
13
|
-
amount
|
|
16
|
+
amount?: number;
|
|
14
17
|
/**
|
|
15
18
|
* Cash physically handed over by the customer, in integer MINOR currency
|
|
16
19
|
* units. When provided, the POS computes the change itself (after applying
|
|
@@ -10,5 +10,10 @@ import { GetRefundPlan } from './types';
|
|
|
10
10
|
* `maxRefundable` as the full captured amount. Against real kaching those
|
|
11
11
|
* numbers come from `order.refund[]` and the capture's `emv` JSON. Use this
|
|
12
12
|
* only to shape UI in local/standalone mode — never to assert real capacity.
|
|
13
|
+
*
|
|
14
|
+
* `allocation` is likewise shape-only: the demo has no refund SELECTION state
|
|
15
|
+
* and no company cash-rounding setting, so it always describes a FULL refund
|
|
16
|
+
* with `rounding: 0` and no cash `payout`. Against real kaching the allocation
|
|
17
|
+
* tracks the live selection and carries the drawer snap.
|
|
13
18
|
*/
|
|
14
19
|
export declare const mockGetRefundPlan: GetRefundPlan;
|
|
@@ -10,6 +10,11 @@ import { MOCK_ORDERS } from '../../demo/database';
|
|
|
10
10
|
* `maxRefundable` as the full captured amount. Against real kaching those
|
|
11
11
|
* numbers come from `order.refund[]` and the capture's `emv` JSON. Use this
|
|
12
12
|
* only to shape UI in local/standalone mode — never to assert real capacity.
|
|
13
|
+
*
|
|
14
|
+
* `allocation` is likewise shape-only: the demo has no refund SELECTION state
|
|
15
|
+
* and no company cash-rounding setting, so it always describes a FULL refund
|
|
16
|
+
* with `rounding: 0` and no cash `payout`. Against real kaching the allocation
|
|
17
|
+
* tracks the live selection and carries the drawer snap.
|
|
13
18
|
*/
|
|
14
19
|
export const mockGetRefundPlan = async (params) => {
|
|
15
20
|
console.log('[Mock] getRefundPlan called', params);
|
|
@@ -45,10 +50,29 @@ export const mockGetRefundPlan = async (params) => {
|
|
|
45
50
|
});
|
|
46
51
|
const totalCaptured = sources.reduce((sum, s) => sum + s.capturedAmount, 0);
|
|
47
52
|
const nonRefundableLiability = order.summary?.nonRevenueTotal ?? 0;
|
|
53
|
+
// Full-refund legs: every source returns its whole capture (the demo's
|
|
54
|
+
// `maxRefundable`), which is exactly the shape a full selection produces.
|
|
55
|
+
const legs = sources
|
|
56
|
+
.filter((s) => s.maxRefundable > 0)
|
|
57
|
+
.map((s) => ({
|
|
58
|
+
transactionId: s.transactionId,
|
|
59
|
+
amount: s.maxRefundable,
|
|
60
|
+
paymentType: s.paymentType,
|
|
61
|
+
requiresDestination: s.paymentType === 'redeem',
|
|
62
|
+
requiresGiftCardDestination: s.paymentType === 'redeem',
|
|
63
|
+
}));
|
|
64
|
+
const budget = legs.reduce((sum, l) => sum + l.amount, 0);
|
|
48
65
|
return {
|
|
49
66
|
success: true,
|
|
50
67
|
orderId: order._id,
|
|
51
68
|
sources,
|
|
69
|
+
allocation: {
|
|
70
|
+
budget,
|
|
71
|
+
// No cash rounding in the demo, so the goods value and the budget agree.
|
|
72
|
+
itemTotal: budget,
|
|
73
|
+
rounding: 0,
|
|
74
|
+
legs,
|
|
75
|
+
},
|
|
52
76
|
// Demo: no prior refunds, so remaining = captured minus the non-revenue load.
|
|
53
77
|
remainingRefundable: Math.max(0, totalCaptured - nonRefundableLiability),
|
|
54
78
|
nonRefundableLiability,
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
export interface GetRefundPlanParams {
|
|
2
2
|
/** Order to inspect; defaults to the active order. */
|
|
3
3
|
orderId?: string;
|
|
4
|
+
/**
|
|
5
|
+
* The selection to allocate — the SAME array you will pass to
|
|
6
|
+
* `processPartialRefund({ items })`, so the plan you render and the refund
|
|
7
|
+
* you submit are computed from one input.
|
|
8
|
+
*
|
|
9
|
+
* A flow that owns its own refund UI holds the selection in its own state and
|
|
10
|
+
* never stages it on the POS, so without this there is nothing for the engine
|
|
11
|
+
* to allocate. Pass it here on every selection change to get the matching
|
|
12
|
+
* {@link RefundPlanAllocation} back. **Purely a read** — unlike
|
|
13
|
+
* `processPartialRefund`, this never stages the selection or touches POS
|
|
14
|
+
* state, so it is safe to call as the cashier ticks rows.
|
|
15
|
+
*
|
|
16
|
+
* Omit it to fall back to the selection already staged on the POS (what
|
|
17
|
+
* `selectAllRefundItems` sets) — the in-POS modal's path. Omitted with
|
|
18
|
+
* nothing staged, no `allocation` comes back.
|
|
19
|
+
*/
|
|
20
|
+
items?: {
|
|
21
|
+
/** `internalId` / `variantId` for a product, `customSaleId`, cart-fee id, or tip `transactionId`. */
|
|
22
|
+
itemKey: string;
|
|
23
|
+
quantity: number;
|
|
24
|
+
/** Optional hint; inferred from the order when omitted. */
|
|
25
|
+
type?: 'product' | 'customSale' | 'fee' | 'tip';
|
|
26
|
+
}[];
|
|
4
27
|
}
|
|
5
28
|
export interface RefundPlanSource {
|
|
6
29
|
transactionId: string;
|
|
@@ -17,10 +40,79 @@ export interface RefundPlanSource {
|
|
|
17
40
|
/** For redeem sources: the card number from the payment entry's emv, when present. */
|
|
18
41
|
cardNumber?: string;
|
|
19
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* One ready-to-submit refund leg. Pass these straight to
|
|
45
|
+
* `processPartialRefund({ openUI: false, legs })` — the amounts are the
|
|
46
|
+
* engine's own allocation and already satisfy its Σ-contract.
|
|
47
|
+
*/
|
|
48
|
+
export interface RefundPlanLeg {
|
|
49
|
+
/** `transactionId` of the source payment this leg draws from — join key to `sources`. */
|
|
50
|
+
transactionId: string;
|
|
51
|
+
/** Amount to return to this source (minor units). Submit VERBATIM; do not re-derive. */
|
|
52
|
+
amount: number;
|
|
53
|
+
/** `cash` / `card` / `redeem` / etc., copied from the source. */
|
|
54
|
+
paymentType: string;
|
|
55
|
+
/**
|
|
56
|
+
* True when the leg must carry a destination tender (a `redeem` source
|
|
57
|
+
* cannot be refunded to itself — the money needs somewhere to land, credited
|
|
58
|
+
* by the flow FIRST). The destination is usually a gift card but redeem is
|
|
59
|
+
* the general rail: loyalty and store-credit extensions ride it too.
|
|
60
|
+
*/
|
|
61
|
+
requiresDestination: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* @deprecated Same value as {@link RefundPlanLeg.requiresDestination} — the
|
|
64
|
+
* old name baked one extension (gift card) into a general redeem concept.
|
|
65
|
+
* Kept populated for existing callers; prefer `requiresDestination`.
|
|
66
|
+
*/
|
|
67
|
+
requiresGiftCardDestination: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Cash legs only: what the drawer actually pays after the company's
|
|
70
|
+
* cash-rounding snap, and the signed delta from `amount`. Display it
|
|
71
|
+
* ("drawer pays 6.50 (+0.01 rounding)") — never apply the snap yourself,
|
|
72
|
+
* and never stage `payout.amount` as the leg (`amount` is the leg).
|
|
73
|
+
*/
|
|
74
|
+
payout?: {
|
|
75
|
+
amount: number;
|
|
76
|
+
rounding: number;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The engine's own allocation of the CURRENT refund selection across the
|
|
81
|
+
* order's captures — what a flow renders and submits instead of computing a
|
|
82
|
+
* split of its own.
|
|
83
|
+
*
|
|
84
|
+
* Present when the call carries a selection: either `params.items` (a flow
|
|
85
|
+
* holding its own selection — the usual case) or a selection already staged on
|
|
86
|
+
* the POS for the active order (`selectAllRefundItems`). Omitted for a bare
|
|
87
|
+
* capacity read with neither.
|
|
88
|
+
*/
|
|
89
|
+
export interface RefundPlanAllocation {
|
|
90
|
+
/**
|
|
91
|
+
* What Σ `legs.amount` MUST equal — `min(itemTotal, Σ maxRefundable)`, which
|
|
92
|
+
* on a FULL selection is the captured total, not the goods value. Staging the
|
|
93
|
+
* goods value instead is rejected with `refund.legSumMismatch`.
|
|
94
|
+
*/
|
|
95
|
+
budget: number;
|
|
96
|
+
/** Goods value of the selection (minor units). DISPLAY ONLY — never allocate against it. */
|
|
97
|
+
itemTotal: number;
|
|
98
|
+
/**
|
|
99
|
+
* `budget − itemTotal` — the sale's cash rounding, returned to the tender that
|
|
100
|
+
* took it. Non-zero only on a cash-rounded capture; the engine stamps it as
|
|
101
|
+
* refund residue at commit.
|
|
102
|
+
*/
|
|
103
|
+
rounding: number;
|
|
104
|
+
/** One leg per source that receives money. Submit as `legs`, unchanged. */
|
|
105
|
+
legs: RefundPlanLeg[];
|
|
106
|
+
}
|
|
20
107
|
export interface GetRefundPlanResponse {
|
|
21
108
|
success: boolean;
|
|
22
109
|
orderId: string;
|
|
23
110
|
sources: RefundPlanSource[];
|
|
111
|
+
/**
|
|
112
|
+
* Ready-to-submit allocation of the current selection. Present only when a
|
|
113
|
+
* refund selection exists on the active order. See {@link RefundPlanAllocation}.
|
|
114
|
+
*/
|
|
115
|
+
allocation?: RefundPlanAllocation;
|
|
24
116
|
/** Order-level remaining refundable (minor units) — non-revenue liability already excluded. */
|
|
25
117
|
remainingRefundable: number;
|
|
26
118
|
/** Non-refundable liability (gift-card loads etc., minor units). */
|
|
@@ -4,4 +4,10 @@
|
|
|
4
4
|
// order-level math so flows can PRESENT accurate refund options without
|
|
5
5
|
// re-deriving the numbers client-side (the mutating commands —
|
|
6
6
|
// `processPartialRefund` / `redeemRefund` — re-validate at submit time).
|
|
7
|
+
//
|
|
8
|
+
// `allocation` closes the last gap: capacities alone still left a flow to work
|
|
9
|
+
// out WHICH tender gets WHAT, and a flow that split the goods value across the
|
|
10
|
+
// tenders shaved the sale's cash rounding off gift-card legs and was rejected
|
|
11
|
+
// at submit. The engine now returns the legs it would accept — render them,
|
|
12
|
+
// submit them unchanged, compute nothing.
|
|
7
13
|
export {};
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* Calls the getRemainingRefundableQuantities action on the parent window
|
|
4
4
|
*/
|
|
5
5
|
import { commandFrameClient } from "../../client";
|
|
6
|
-
export const getRemainingRefundableQuantities = async () => {
|
|
7
|
-
return await commandFrameClient.call("getRemainingRefundableQuantities");
|
|
6
|
+
export const getRemainingRefundableQuantities = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("getRemainingRefundableQuantities", params);
|
|
8
8
|
};
|
|
@@ -5,6 +5,19 @@ export interface GetRemainingRefundableQuantitiesResponse {
|
|
|
5
5
|
success: boolean;
|
|
6
6
|
lineItems: Record<string, number>;
|
|
7
7
|
customSales: Record<string, number>;
|
|
8
|
+
/**
|
|
9
|
+
* Remaining refundable cart fees, keyed by `order.cartFees[].id` —
|
|
10
|
+
* the same key `processPartialRefund` takes for `type: 'fee'` items.
|
|
11
|
+
* 0/1 semantics: `1` = still refundable, `0` = already refunded.
|
|
12
|
+
*/
|
|
13
|
+
cartFees: Record<string, number>;
|
|
14
|
+
/**
|
|
15
|
+
* Remaining refundable tips, keyed by the paying method's
|
|
16
|
+
* `transactionId` — the same key `processPartialRefund` takes for
|
|
17
|
+
* `type: 'tip'` items. Only payment methods that carry a tip appear.
|
|
18
|
+
* 0/1 semantics: `1` = still refundable, `0` = already refunded.
|
|
19
|
+
*/
|
|
20
|
+
tips: Record<string, number>;
|
|
8
21
|
timestamp: string;
|
|
9
22
|
}
|
|
10
23
|
export type GetRemainingRefundableQuantities = (params?: GetRemainingRefundableQuantitiesParams) => Promise<GetRemainingRefundableQuantitiesResponse>;
|
|
@@ -7,4 +7,10 @@ export interface InitiateRefundResponse {
|
|
|
7
7
|
orderId: string;
|
|
8
8
|
timestamp: string;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated The host-side refund popup is disabled — no UI opens. Stages the
|
|
12
|
+
* active order (and arms barcode refund-scan routing when no `orderId` is
|
|
13
|
+
* given). Build refund UI in the flow: `getRefundPlan`,
|
|
14
|
+
* `getRemainingRefundableQuantities`, `processPartialRefund`, `redeemRefund`.
|
|
15
|
+
*/
|
|
10
16
|
export type InitiateRefund = (params?: InitiateRefundParams) => Promise<InitiateRefundResponse>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ProcessPartialRefund } from
|
|
1
|
+
import { ProcessPartialRefund } from './types';
|
|
2
2
|
export declare const mockProcessPartialRefund: ProcessPartialRefund;
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
export const mockProcessPartialRefund = async (params) => {
|
|
2
2
|
// The mock has no split-payment modal or order engine, so `openUI` (default
|
|
3
|
-
// true on the real command), `legs` (the headless per-tender allocation)
|
|
4
|
-
//
|
|
5
|
-
// shape is accepted and echoed, nothing
|
|
6
|
-
|
|
3
|
+
// true on the real command), `legs` (the headless per-tender allocation), a
|
|
4
|
+
// per-leg `giftCard` destination (mixed returns) and the top-level `giftCard`
|
|
5
|
+
// routing are all inert here — the shape is accepted and echoed, nothing
|
|
6
|
+
// else. No gift card is credited.
|
|
7
|
+
//
|
|
8
|
+
// The one rule worth mirroring is the mutual exclusion, so a flow built
|
|
9
|
+
// against the mock fails the same way it will against the runtime.
|
|
10
|
+
if (params?.legs && params?.giftCard) {
|
|
11
|
+
throw new Error('refund.giftCardAndLegs: pass either `legs` (you allocate) or `giftCard` (the engine allocates), not both');
|
|
12
|
+
}
|
|
13
|
+
console.log('[Mock] processPartialRefund called', {
|
|
7
14
|
...params,
|
|
8
15
|
openUI: params?.openUI ?? true,
|
|
9
16
|
legs: params?.legs ?? null,
|
|
17
|
+
giftCard: params?.giftCard ?? null,
|
|
10
18
|
});
|
|
11
19
|
return {
|
|
12
20
|
success: true,
|
|
13
21
|
refundId: 'mock_refund_' + Date.now(),
|
|
14
|
-
|
|
22
|
+
modalRaised: false,
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
15
24
|
};
|
|
16
25
|
};
|
|
@@ -2,10 +2,11 @@ export interface ProcessPartialRefundParams {
|
|
|
2
2
|
/**
|
|
3
3
|
* Optional refund reason.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* state-event audit row
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Recorded verbatim on the persisted `Refund` doc's `reason` field and on
|
|
6
|
+
* the state-event audit row — same as `redeemRefund`. When omitted, the
|
|
7
|
+
* refund doc's `reason` stays unset and only the audit row carries the
|
|
8
|
+
* 'partial-refund' fallback label. See the README's "`reason` persistence"
|
|
9
|
+
* section.
|
|
9
10
|
*/
|
|
10
11
|
reason?: string;
|
|
11
12
|
/** Optional: specify which order to refund (sets it as active). */
|
|
@@ -87,6 +88,47 @@ export interface ProcessPartialRefundParams {
|
|
|
87
88
|
label?: string;
|
|
88
89
|
};
|
|
89
90
|
}[];
|
|
91
|
+
/**
|
|
92
|
+
* Route part (or all) of the refund onto ONE gift-card / store-credit tender
|
|
93
|
+
* and let the engine send whatever is left back to the original payments.
|
|
94
|
+
*
|
|
95
|
+
* This is the declarative alternative to hand-building `legs`: state the card
|
|
96
|
+
* and how much lands on it, and the engine does the allocation — it already
|
|
97
|
+
* owns that math for every other refund path. Prefer it over `legs` for a
|
|
98
|
+
* gift-card destination; a flow that computes its own split is duplicating
|
|
99
|
+
* engine arithmetic that will drift (see "Query, never recompute").
|
|
100
|
+
*
|
|
101
|
+
* - `amount` omitted → the WHOLE refund lands on the card (what an
|
|
102
|
+
* all-`giftCard` `legs` staging does today).
|
|
103
|
+
* - `amount` set → that much lands on the card, in minor units; the
|
|
104
|
+
* remainder returns to the original payments, allocated by the engine.
|
|
105
|
+
*
|
|
106
|
+
* DRAWING ORDER — the card is filled from the tenders that cannot be
|
|
107
|
+
* refunded to source first (a redeem tender has nowhere to return to), then
|
|
108
|
+
* proportionally from the rest. So `amount` can never be lower than what
|
|
109
|
+
* those tenders must contribute: below that the call throws
|
|
110
|
+
* `REFUND_GIFT_AMOUNT_BELOW_MINIMUM`, naming the minimum, and nothing is
|
|
111
|
+
* committed. Surface that message — it is the number to clamp the field to,
|
|
112
|
+
* so the flow never has to derive it.
|
|
113
|
+
*
|
|
114
|
+
* Exactly one destination card, therefore exactly ONE credit for the caller
|
|
115
|
+
* to place and one to reverse. **Credit-first:** credit `referenceId` for
|
|
116
|
+
* `amount` (or the full refund total when omitted) BEFORE calling; on any
|
|
117
|
+
* throw nothing was recorded — reverse it.
|
|
118
|
+
*
|
|
119
|
+
* Requires `openUI: false`. Mutually exclusive with `legs` — passing both
|
|
120
|
+
* throws, since they are two answers to the same question.
|
|
121
|
+
*/
|
|
122
|
+
giftCard?: {
|
|
123
|
+
/** Card/account id the flow already credited (stored raw). */
|
|
124
|
+
referenceId: string;
|
|
125
|
+
/** Minor units landing on the card. Omit for the whole refund. */
|
|
126
|
+
amount?: number;
|
|
127
|
+
/** Provider/program name. Defaults to `giftCard`. */
|
|
128
|
+
processor?: string;
|
|
129
|
+
/** Human label for the destination tender. */
|
|
130
|
+
label?: string;
|
|
131
|
+
};
|
|
90
132
|
/** Optional items to refund. */
|
|
91
133
|
items?: {
|
|
92
134
|
/** internalId or variantId or customSaleId. */
|
|
@@ -111,7 +153,25 @@ export interface ProcessPartialRefundParams {
|
|
|
111
153
|
}
|
|
112
154
|
export interface ProcessPartialRefundResponse {
|
|
113
155
|
success: boolean;
|
|
114
|
-
|
|
156
|
+
/**
|
|
157
|
+
* The persisted Refund document's id — the REAL one, usable to look the
|
|
158
|
+
* refund up. `null` means nothing has committed: the split-payment modal
|
|
159
|
+
* was raised (`modalRaised: true`) and owns the commit from there.
|
|
160
|
+
*
|
|
161
|
+
* Before kaching 1.9.5-preprod.17 this was the hardcoded string
|
|
162
|
+
* `'processed'` regardless of outcome, so a truthiness check could not
|
|
163
|
+
* detect a refund that silently didn't happen. Guard on it now:
|
|
164
|
+
* `if (!res.refundId && !res.modalRaised) …` is unreachable (such paths
|
|
165
|
+
* throw instead), so `res.refundId` alone answers "did money move".
|
|
166
|
+
*/
|
|
167
|
+
refundId: string | null;
|
|
168
|
+
/**
|
|
169
|
+
* True when a multi-tender order raised the split-payment refund modal
|
|
170
|
+
* (`openUI` omitted or `true`): the cashier allocates there and the modal
|
|
171
|
+
* drives the commit — this call wrote nothing. Headless calls
|
|
172
|
+
* (`openUI: false`) never raise it.
|
|
173
|
+
*/
|
|
174
|
+
modalRaised: boolean;
|
|
115
175
|
timestamp: string;
|
|
116
176
|
}
|
|
117
177
|
export type ProcessPartialRefund = (params?: ProcessPartialRefundParams) => Promise<ProcessPartialRefundResponse>;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
export interface RemoveProductFeeParams {
|
|
2
|
-
/** If provided, removes fee from specific cart item. Otherwise uses active product. */
|
|
2
|
+
/** If provided, removes fee(s) from a specific cart item. Otherwise uses active product. */
|
|
3
3
|
internalId?: string;
|
|
4
|
+
/**
|
|
5
|
+
* 0-based index of the single fee to remove, in the order the line's fees
|
|
6
|
+
* were added (fees STACK — `addProductFee` appends). Omit to clear ALL
|
|
7
|
+
* fees on the line (the legacy behavior). Out-of-range indexes are a
|
|
8
|
+
* no-op.
|
|
9
|
+
*/
|
|
10
|
+
index?: number;
|
|
4
11
|
}
|
|
5
12
|
export interface RemoveProductFeeResponse {
|
|
6
13
|
success: boolean;
|
|
7
14
|
internalId?: string;
|
|
15
|
+
/** Echoed when a single fee was targeted. */
|
|
16
|
+
index?: number;
|
|
8
17
|
timestamp: string;
|
|
9
18
|
}
|
|
10
19
|
export type RemoveProductFee = (params?: RemoveProductFeeParams) => Promise<RemoveProductFeeResponse>;
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* Calls the selectAllRefundItems action on the parent window
|
|
4
4
|
*/
|
|
5
5
|
import { commandFrameClient } from "../../client";
|
|
6
|
-
export const selectAllRefundItems = async () => {
|
|
7
|
-
return await commandFrameClient.call("selectAllRefundItems");
|
|
6
|
+
export const selectAllRefundItems = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("selectAllRefundItems", params);
|
|
8
8
|
};
|
|
@@ -7,4 +7,4 @@ export interface SetActiveRefundResponse {
|
|
|
7
7
|
refund: CFActiveRefundDetails;
|
|
8
8
|
timestamp: string;
|
|
9
9
|
}
|
|
10
|
-
export type SetActiveRefund = (params
|
|
10
|
+
export type SetActiveRefund = (params: SetActiveRefundParams) => Promise<SetActiveRefundResponse>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface SetRefundStockActionParams {
|
|
2
2
|
orderId?: string;
|
|
3
|
-
/** The 'key' field from getLineItemsByOrder response (internalId
|
|
3
|
+
/** The 'key' field from getLineItemsByOrder response (internalId, falling back to variantId). */
|
|
4
4
|
itemKey: string;
|
|
5
5
|
action: 'RESTOCK' | 'REFUND_DAMAGE';
|
|
6
6
|
}
|
|
@@ -2,14 +2,17 @@ import { CFOrder } from "../../CommonTypes";
|
|
|
2
2
|
export interface TapToPayPaymentParams {
|
|
3
3
|
/**
|
|
4
4
|
* The amount to pay with this tender, in integer MINOR currency units
|
|
5
|
-
* (e.g. 1575 = $15.75). Required
|
|
6
|
-
*
|
|
5
|
+
* (e.g. 1575 = $15.75). Required whenever the balance due is greater than
|
|
6
|
+
* $0; may be omitted only on a cart that already nets to a $0 balance due
|
|
7
|
+
* (e.g. fully discounted), where it defaults to 0. Semantics against the
|
|
8
|
+
* cart's balance due:
|
|
9
|
+
* - missing → error, unless the balance due is $0 (→ 0)
|
|
7
10
|
* - less than balance → partial payment (the POS enters a fixed
|
|
8
11
|
* split-payment leg for this amount)
|
|
9
12
|
* - equal to balance → full payment
|
|
10
13
|
* - more than balance → error
|
|
11
14
|
*/
|
|
12
|
-
amount
|
|
15
|
+
amount?: number;
|
|
13
16
|
/** Override the fulfillment state after full payment. kaching resolves the cascade. */
|
|
14
17
|
checkoutFulfillmentTarget?: string;
|
|
15
18
|
}
|
|
@@ -3,9 +3,10 @@ export interface VoidOrderParams {
|
|
|
3
3
|
/** Order to void; defaults to the active order. */
|
|
4
4
|
orderId?: string;
|
|
5
5
|
/**
|
|
6
|
-
* Optional cashier-facing reason.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Optional cashier-facing reason. Recorded on both branches — the void audit
|
|
7
|
+
* trail on a pure void, and (verbatim) on the persisted refund plus its own
|
|
8
|
+
* audit trail on the refund branch — and always carried on the
|
|
9
|
+
* `order-voided` event either way.
|
|
9
10
|
*/
|
|
10
11
|
reason?: string;
|
|
11
12
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -141,8 +141,8 @@ export type { CalculateRefundTotal, CalculateRefundTotalParams, CalculateRefundT
|
|
|
141
141
|
export type { GetRemainingRefundableQuantities, GetRemainingRefundableQuantitiesParams, GetRemainingRefundableQuantitiesResponse, } from './actions/get-remaining-refundable-quantities/types';
|
|
142
142
|
export type { ProcessPartialRefund, ProcessPartialRefundParams, ProcessPartialRefundResponse, } from './actions/process-partial-refund/types';
|
|
143
143
|
export type { RedeemRefund, RedeemRefundParams, RedeemRefundResponse } from './actions/redeem-refund/types';
|
|
144
|
-
export type { GetRefundPlan, GetRefundPlanParams, GetRefundPlanResponse, RefundPlanSource, } from './actions/get-refund-plan/types';
|
|
145
|
-
export type { CheckPermission, CheckPermissionParams, CheckPermissionResponse
|
|
144
|
+
export type { GetRefundPlan, GetRefundPlanParams, GetRefundPlanResponse, RefundPlanSource, RefundPlanAllocation, RefundPlanLeg, } from './actions/get-refund-plan/types';
|
|
145
|
+
export type { CheckPermission, CheckPermissionParams, CheckPermissionResponse } from './actions/check-permission/types';
|
|
146
146
|
export type { InitiateRefund, InitiateRefundParams, InitiateRefundResponse } from './actions/initiate-refund/types';
|
|
147
147
|
export type { GetCurrentCart, GetCurrentCartResponse } from './actions/get-current-cart/types';
|
|
148
148
|
export type { AddProductDiscount, AddProductDiscountParams, AddProductDiscountResponse, } from './actions/add-product-discount/types';
|