@final-commerce/command-frame 0.6.0-staging.5 → 0.6.0-staging3.1
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/README.md +2 -0
- package/dist/CommonTypes.d.ts +10 -1
- package/dist/actions/add-product-to-cart/mock.js +6 -0
- package/dist/actions/add-product-to-cart/types.d.ts +12 -2
- package/dist/actions/get-available-transitions/mock.d.ts +7 -2
- package/dist/actions/get-available-transitions/mock.js +9 -9
- package/dist/actions/get-product-modifier-selections/action.d.ts +6 -0
- package/dist/actions/get-product-modifier-selections/action.js +8 -0
- package/dist/actions/get-product-modifier-selections/mock.d.ts +2 -0
- package/dist/actions/get-product-modifier-selections/mock.js +23 -0
- package/dist/actions/get-product-modifier-selections/types.d.ts +30 -0
- package/dist/actions/get-product-modifier-selections/types.js +2 -0
- package/dist/actions/set-product-modifier-selections/action.d.ts +6 -0
- package/dist/actions/set-product-modifier-selections/action.js +8 -0
- package/dist/actions/set-product-modifier-selections/mock.d.ts +2 -0
- package/dist/actions/set-product-modifier-selections/mock.js +34 -0
- package/dist/actions/set-product-modifier-selections/types.d.ts +22 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.js +4 -8
- package/dist/projects/render/mocks.js +4 -6
- package/dist/projects/render/types.d.ts +3 -4
- package/dist/pubsub/topics/cart/product-modifiers-updated/types.d.ts +16 -0
- package/dist/pubsub/topics/cart/product-modifiers-updated/types.js +1 -0
- package/dist/pubsub/topics/cart/types.d.ts +4 -2
- package/dist/pubsub/topics/cart/types.js +1 -0
- package/package.json +2 -2
- package/dist/actions/charge-moto/action.d.ts +0 -6
- package/dist/actions/charge-moto/action.js +0 -8
- package/dist/actions/charge-moto/mock.d.ts +0 -2
- package/dist/actions/charge-moto/mock.js +0 -47
- package/dist/actions/charge-moto/types.d.ts +0 -53
- package/dist/actions/create-payment-link/action.d.ts +0 -6
- package/dist/actions/create-payment-link/action.js +0 -8
- package/dist/actions/create-payment-link/mock.d.ts +0 -2
- package/dist/actions/create-payment-link/mock.js +0 -35
- package/dist/actions/create-payment-link/types.d.ts +0 -27
- package/dist/actions/create-payment-link/types.js +0 -12
- package/dist/actions/get-time-clock-status/action.d.ts +0 -6
- package/dist/actions/get-time-clock-status/action.js +0 -8
- package/dist/actions/get-time-clock-status/mock.d.ts +0 -2
- package/dist/actions/get-time-clock-status/mock.js +0 -17
- package/dist/actions/get-time-clock-status/types.d.ts +0 -18
- package/dist/actions/get-time-clock-status/types.js +0 -7
- /package/dist/actions/{charge-moto → set-product-modifier-selections}/types.js +0 -0
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ The library provides three main capabilities:
|
|
|
18
18
|
|
|
19
19
|
Domain models (orders, cart, customers, products, and related types) are documented in **[Types reference](./src/types/README.md)**.
|
|
20
20
|
|
|
21
|
+
The order lifecycle — payment × fulfillment state pairs, display labels, the transition guard chain, and the financial invariants — is documented in **[Order state machine reference](./docs/order-state-machine.md)**. Read it before building anything that reads or moves order state (`canTransition`, `getAvailableTransitions`, `applyTransition`, park/void/resume, payments, refunds).
|
|
22
|
+
|
|
21
23
|
## Installation
|
|
22
24
|
|
|
23
25
|
### From npm (public registry)
|
package/dist/CommonTypes.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from './common-types';
|
|
2
|
-
import type { Tax, Tip, Address, MetadataItem, PosDataItem, CartFeeTaxEntry, CartFeeItem, CartDiscountItem, OrderNote, NonRevenueItem, DiscountDetail, FeeDetail, DiscountLineItem, FeeLineItem, LineItem, TipPayment, RefundedTipPayment, PaymentMethod, Discount, CustomFee, Summary, CustomSale, RefundedCustomSale, RefundItem, RefundedLineItem, ActiveStation, ActiveSession, ActiveOutlet, ActiveUser, ActiveUserRole, ActiveOrder, ActiveCart, ActivePark, ActiveCompany, ActiveCustomSales, ActiveProduct, ActiveCustomer, FullProduct, ProductVariant, Inventory, CustomerNote, Attribute, AttributeOption, Category, Transaction, ActiveSplitPayment } from '@final-commerce/common/pos-types';
|
|
2
|
+
import type { Tax, Tip, Address, MetadataItem, PosDataItem, CartFeeTaxEntry, CartFeeItem, CartDiscountItem, OrderNote, NonRevenueItem, DiscountDetail, FeeDetail, DiscountLineItem, FeeLineItem, LineItem, TipPayment, RefundedTipPayment, PaymentMethod, Discount, CustomFee, Summary, CustomSale, RefundedCustomSale, RefundItem, RefundedLineItem, ActiveStation, ActiveSession, ActiveOutlet, ActiveUser, ActiveUserRole, ActiveOrder, ActiveCart, ActivePark, ActiveCompany, ActiveCustomSales, ActiveProduct, ActiveCustomer, FullProduct, ProductVariant, Inventory, ResolvedModifier, ResolvedModifierChoice, ModifierSelectionType, ModifierSelection, ModifierChoiceSelection, OrderLineItemModifier, CustomerNote, Attribute, AttributeOption, Category, Transaction, ActiveSplitPayment } from '@final-commerce/common/pos-types';
|
|
3
3
|
export { CurrencyCode, ProductType as CFProductType, UserTypes as CFUserTypes } from '@final-commerce/common';
|
|
4
4
|
/** Open record used as a base for active entities. */
|
|
5
5
|
export type CFActiveEntity = Record<string, unknown>;
|
|
@@ -18,6 +18,15 @@ export type CFTransaction = Transaction;
|
|
|
18
18
|
export type CFCategory = Category;
|
|
19
19
|
export type CFProductVariant = ProductVariant;
|
|
20
20
|
export type CFProduct = FullProduct;
|
|
21
|
+
/** Modifier (the till question) resolved onto a product — `CFProduct.modifiers`. */
|
|
22
|
+
export type CFResolvedModifier = ResolvedModifier;
|
|
23
|
+
export type CFResolvedModifierChoice = ResolvedModifierChoice;
|
|
24
|
+
export type CFModifierSelectionType = ModifierSelectionType;
|
|
25
|
+
/** One selected modifier choice on an order line item (wire shape). */
|
|
26
|
+
export type CFOrderLineItemModifier = OrderLineItemModifier;
|
|
27
|
+
/** Cart-line modifier answer (pre-pricing) — `CFActiveProduct.modifierSelections`. */
|
|
28
|
+
export type CFModifierSelection = ModifierSelection;
|
|
29
|
+
export type CFModifierChoiceSelection = ModifierChoiceSelection;
|
|
21
30
|
export type CFActiveProduct = ActiveProduct;
|
|
22
31
|
export type CFCustomer = ActiveCustomer;
|
|
23
32
|
export type CFActiveCustomer = ActiveCustomer;
|
|
@@ -53,6 +53,12 @@ export const mockAddProductToCart = async (params) => {
|
|
|
53
53
|
note: note,
|
|
54
54
|
// discount/fee could be added here to mock object if CFActiveProduct supports it
|
|
55
55
|
};
|
|
56
|
+
// Mock modifier handling: echo selections onto the line; a real host resolves the
|
|
57
|
+
// product's modifiers, validates required/min/max in units, and prices each choice
|
|
58
|
+
// (fee-level money: not in grossSales, not reduced by the product discount).
|
|
59
|
+
if (params?.modifiers?.length) {
|
|
60
|
+
activeProduct.modifierSelections = params.modifiers;
|
|
61
|
+
}
|
|
56
62
|
MOCK_CART.products.push(activeProduct);
|
|
57
63
|
// Recalculate totals. extendPrice, not a raw multiply: a fractional quantity times an
|
|
58
64
|
// integer-minor price leaves fractional cents, which no order may carry.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import type { AddProductDiscountParams } from
|
|
2
|
-
import type { AddProductFeeParams } from
|
|
1
|
+
import type { AddProductDiscountParams } from '../add-product-discount/types';
|
|
2
|
+
import type { AddProductFeeParams } from '../add-product-fee/types';
|
|
3
|
+
import type { ModifierSelection } from '../get-product-modifier-selections/types';
|
|
4
|
+
/**
|
|
5
|
+
* One modifier answer passed at ring-time. Same shape as the
|
|
6
|
+
* get-product-modifier-selections `ModifierSelection` (single source of truth).
|
|
7
|
+
*/
|
|
8
|
+
export type AddProductToCartModifierParams = ModifierSelection;
|
|
3
9
|
export interface AddProductToCartParams {
|
|
4
10
|
/** ID of the variant to add. */
|
|
5
11
|
variantId: string;
|
|
@@ -21,11 +27,15 @@ export interface AddProductToCartParams {
|
|
|
21
27
|
discounts?: AddProductDiscountParams[];
|
|
22
28
|
/** Array of fees to apply immediately. */
|
|
23
29
|
fees?: AddProductFeeParams[];
|
|
30
|
+
/** Modifier selections to apply immediately. */
|
|
31
|
+
modifiers?: AddProductToCartModifierParams[];
|
|
24
32
|
/** Note or array of notes to add immediately. */
|
|
25
33
|
notes?: string | string[];
|
|
26
34
|
}
|
|
27
35
|
export interface AddProductToCartResponse {
|
|
28
36
|
success: boolean;
|
|
37
|
+
/** Set when the add was rejected (e.g. a required modifier is unanswered). */
|
|
38
|
+
reason?: string;
|
|
29
39
|
productId: string;
|
|
30
40
|
variantId: string;
|
|
31
41
|
/** The unique identifier for the specific item instance added to the cart. */
|
|
@@ -2,7 +2,12 @@ import type { GetAvailableTransitions } from './types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Mock implementation: returns a fixed set of plausible transitions
|
|
4
4
|
* so the demo app has data to render. Mirrors an UNPAID order under the
|
|
5
|
-
* default (empty cross-axis rules) config
|
|
6
|
-
*
|
|
5
|
+
* default (empty cross-axis rules) config.
|
|
6
|
+
*
|
|
7
|
+
* FULFILLMENT-AXIS ONLY (common 2.1.4 contract): the payment axis never
|
|
8
|
+
* appears as an available transition — it moves exclusively through the
|
|
9
|
+
* money operations (pay / refund / void), which derive their own landing
|
|
10
|
+
* pairs. Every row keeps `to.payment` equal to the order's current payment
|
|
11
|
+
* state, exactly like the host's `getAvailableTransitions`.
|
|
7
12
|
*/
|
|
8
13
|
export declare const getAvailableTransitionsMock: GetAvailableTransitions;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Mock implementation: returns a fixed set of plausible transitions
|
|
3
3
|
* so the demo app has data to render. Mirrors an UNPAID order under the
|
|
4
|
-
* default (empty cross-axis rules) config
|
|
5
|
-
*
|
|
4
|
+
* default (empty cross-axis rules) config.
|
|
5
|
+
*
|
|
6
|
+
* FULFILLMENT-AXIS ONLY (common 2.1.4 contract): the payment axis never
|
|
7
|
+
* appears as an available transition — it moves exclusively through the
|
|
8
|
+
* money operations (pay / refund / void), which derive their own landing
|
|
9
|
+
* pairs. Every row keeps `to.payment` equal to the order's current payment
|
|
10
|
+
* state, exactly like the host's `getAvailableTransitions`.
|
|
6
11
|
*/
|
|
7
12
|
export const getAvailableTransitionsMock = () => Promise.resolve({
|
|
8
13
|
transitions: [
|
|
@@ -22,13 +27,8 @@ export const getAvailableTransitionsMock = () => Promise.resolve({
|
|
|
22
27
|
conditions: [{ met: true, description: 'Order is open' }],
|
|
23
28
|
},
|
|
24
29
|
{
|
|
25
|
-
to: { payment: '
|
|
26
|
-
displayLabel: '
|
|
27
|
-
conditions: [{ met: true, description: 'Balance due > 0' }],
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
to: { payment: 'voided', fulfillment: 'cancelled' },
|
|
31
|
-
displayLabel: 'Void Order',
|
|
30
|
+
to: { payment: 'unpaid', fulfillment: 'cancelled' },
|
|
31
|
+
displayLabel: 'Cancel Order',
|
|
32
32
|
conditions: [
|
|
33
33
|
{ met: true, description: 'Order exists' },
|
|
34
34
|
{ met: false, description: 'No payments captured (mock: skipped)' },
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get product modifier selections action (read-only)
|
|
3
|
+
* Calls the getProductModifierSelections action on the parent window
|
|
4
|
+
*/
|
|
5
|
+
import type { GetProductModifierSelections } from "./types";
|
|
6
|
+
export declare const getProductModifierSelections: GetProductModifierSelections;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get product modifier selections action (read-only)
|
|
3
|
+
* Calls the getProductModifierSelections action on the parent window
|
|
4
|
+
*/
|
|
5
|
+
import { commandFrameClient } from "../../client";
|
|
6
|
+
export const getProductModifierSelections = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("getProductModifierSelections", params);
|
|
8
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MOCK_CART } from "../../demo/database";
|
|
2
|
+
export const mockGetProductModifierSelections = async (params) => {
|
|
3
|
+
console.log("[Mock] getProductModifierSelections called", params);
|
|
4
|
+
// Read the line's stored selections from the mock cart (last line when no internalId).
|
|
5
|
+
const line = params?.internalId
|
|
6
|
+
? MOCK_CART.products.find((p) => p.internalId === params.internalId)
|
|
7
|
+
: MOCK_CART.products[MOCK_CART.products.length - 1];
|
|
8
|
+
if (!line) {
|
|
9
|
+
return {
|
|
10
|
+
success: false,
|
|
11
|
+
reason: "No matching cart line",
|
|
12
|
+
internalId: params?.internalId,
|
|
13
|
+
selections: [],
|
|
14
|
+
timestamp: new Date().toISOString()
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
internalId: line.internalId,
|
|
20
|
+
selections: line.modifierSelections ?? [],
|
|
21
|
+
timestamp: new Date().toISOString()
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** One chosen choice: `quantity` is units PER LINE-ITEM UNIT (1 unless the control is a stepper). */
|
|
2
|
+
export interface ModifierChoiceSelection {
|
|
3
|
+
choiceId: string;
|
|
4
|
+
quantity: number;
|
|
5
|
+
}
|
|
6
|
+
/** The cashier's answer to one modifier. */
|
|
7
|
+
export interface ModifierSelection {
|
|
8
|
+
modifierId: string;
|
|
9
|
+
choices: ModifierChoiceSelection[];
|
|
10
|
+
}
|
|
11
|
+
export interface GetProductModifierSelectionsParams {
|
|
12
|
+
/** The cart line to read. Defaults to the active product's line. */
|
|
13
|
+
internalId?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface GetProductModifierSelectionsResponse {
|
|
16
|
+
success: boolean;
|
|
17
|
+
/** Set when the read failed (e.g. no such line, no active product). */
|
|
18
|
+
reason?: string;
|
|
19
|
+
internalId?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The line's current modifier selections. Supplied at creation via
|
|
22
|
+
* `addProductToCart({ modifiers })`; edit them with
|
|
23
|
+
* `setProductModifierSelections` (full replacement, re-validated).
|
|
24
|
+
* Modifier DEFINITIONS remain read-only — they flow one-way from
|
|
25
|
+
* station-sync into the till.
|
|
26
|
+
*/
|
|
27
|
+
selections: ModifierSelection[];
|
|
28
|
+
timestamp: string;
|
|
29
|
+
}
|
|
30
|
+
export type GetProductModifierSelections = (params?: GetProductModifierSelectionsParams) => Promise<GetProductModifierSelectionsResponse>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set product modifier selections action
|
|
3
|
+
* Calls the setProductModifierSelections action on the parent window
|
|
4
|
+
*/
|
|
5
|
+
import { commandFrameClient } from "../../client";
|
|
6
|
+
export const setProductModifierSelections = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("setProductModifierSelections", params);
|
|
8
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { MOCK_CART } from "../../demo/database";
|
|
2
|
+
export const mockSetProductModifierSelections = async (params) => {
|
|
3
|
+
console.log("[Mock] setProductModifierSelections called", params);
|
|
4
|
+
if (!params?.selections) {
|
|
5
|
+
return {
|
|
6
|
+
success: false,
|
|
7
|
+
reason: "selections is required (pass [] to clear)",
|
|
8
|
+
internalId: params?.internalId,
|
|
9
|
+
selections: [],
|
|
10
|
+
timestamp: new Date().toISOString()
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
// Write the selections onto the mock cart line (last line when no internalId).
|
|
14
|
+
// The mock does not re-run rule validation or repricing — the real host does.
|
|
15
|
+
const line = params.internalId
|
|
16
|
+
? MOCK_CART.products.find((p) => p.internalId === params.internalId)
|
|
17
|
+
: MOCK_CART.products[MOCK_CART.products.length - 1];
|
|
18
|
+
if (!line) {
|
|
19
|
+
return {
|
|
20
|
+
success: false,
|
|
21
|
+
reason: "No matching cart line",
|
|
22
|
+
internalId: params.internalId,
|
|
23
|
+
selections: [],
|
|
24
|
+
timestamp: new Date().toISOString()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
line.modifierSelections = params.selections;
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
internalId: line.internalId,
|
|
31
|
+
selections: params.selections,
|
|
32
|
+
timestamp: new Date().toISOString()
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ModifierSelection } from "../get-product-modifier-selections/types";
|
|
2
|
+
export interface SetProductModifierSelectionsParams {
|
|
3
|
+
/** The cart line to edit. Defaults to the active product's line. */
|
|
4
|
+
internalId?: string;
|
|
5
|
+
/**
|
|
6
|
+
* The line's COMPLETE new answers — replaces every existing selection on the
|
|
7
|
+
* line (send [] to clear all optional modifiers). Validated against the
|
|
8
|
+
* product's category-modifier rules exactly like addProductToCart({ modifiers }):
|
|
9
|
+
* a selection that breaks a rule rejects the edit and the line is unchanged.
|
|
10
|
+
*/
|
|
11
|
+
selections: ModifierSelection[];
|
|
12
|
+
}
|
|
13
|
+
export interface SetProductModifierSelectionsResponse {
|
|
14
|
+
success: boolean;
|
|
15
|
+
/** Set when the edit was rejected (rule violation) — the line is unchanged. */
|
|
16
|
+
reason?: string;
|
|
17
|
+
internalId?: string;
|
|
18
|
+
/** The selections now on the line (the new ones on success, the old ones on rejection). */
|
|
19
|
+
selections: ModifierSelection[];
|
|
20
|
+
timestamp: string;
|
|
21
|
+
}
|
|
22
|
+
export type SetProductModifierSelections = (params?: SetProductModifierSelectionsParams) => Promise<SetProductModifierSelectionsResponse>;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export declare const command: {
|
|
|
21
21
|
readonly getFinalContext: import(".").GetFinalContext;
|
|
22
22
|
readonly addProductNote: import(".").AddProductNote;
|
|
23
23
|
readonly addProductFee: import(".").AddProductFee;
|
|
24
|
+
readonly getProductModifierSelections: import(".").GetProductModifierSelections;
|
|
25
|
+
readonly setProductModifierSelections: import(".").SetProductModifierSelections;
|
|
24
26
|
readonly setActiveProductFee: import(".").SetActiveProductFee;
|
|
25
27
|
readonly setActiveProductDiscount: import(".").SetActiveProductDiscount;
|
|
26
28
|
readonly getActiveProduct: import(".").GetActiveProduct;
|
|
@@ -41,8 +43,6 @@ export declare const command: {
|
|
|
41
43
|
readonly extensionPayment: import(".").ExtensionPayment;
|
|
42
44
|
readonly redeemPayment: import(".").RedeemPayment;
|
|
43
45
|
readonly integrationPayment: import(".").IntegrationPayment;
|
|
44
|
-
readonly createPaymentLink: import(".").CreatePaymentLink;
|
|
45
|
-
readonly chargeMoto: import(".").ChargeMoto;
|
|
46
46
|
readonly addCustomerNote: import(".").AddCustomerNote;
|
|
47
47
|
readonly removeCustomerNote: import(".").RemoveCustomerNote;
|
|
48
48
|
readonly removeCustomerFromCart: import(".").RemoveCustomerFromCart;
|
|
@@ -111,7 +111,6 @@ export declare const command: {
|
|
|
111
111
|
readonly uploadMedia: import(".").UploadMedia;
|
|
112
112
|
readonly getTaxTables: import(".").GetTaxTables;
|
|
113
113
|
readonly getBranding: import(".").GetBranding;
|
|
114
|
-
readonly getTimeClockStatus: import(".").GetTimeClockStatus;
|
|
115
114
|
readonly canTransition: import(".").CanTransition;
|
|
116
115
|
readonly getAvailableTransitions: import(".").GetAvailableTransitions;
|
|
117
116
|
readonly applyTransition: import(".").ApplyTransition;
|
|
@@ -149,7 +148,7 @@ export type { CheckPermission, CheckPermissionParams, CheckPermissionResponse }
|
|
|
149
148
|
export type { InitiateRefund, InitiateRefundParams, InitiateRefundResponse } from './actions/initiate-refund/types';
|
|
150
149
|
export type { GetCurrentCart, GetCurrentCartResponse } from './actions/get-current-cart/types';
|
|
151
150
|
export type { AddProductDiscount, AddProductDiscountParams, AddProductDiscountResponse, } from './actions/add-product-discount/types';
|
|
152
|
-
export type { AddProductToCart, AddProductToCartParams, AddProductToCartResponse, } from './actions/add-product-to-cart/types';
|
|
151
|
+
export type { AddProductToCart, AddProductToCartParams, AddProductToCartModifierParams, AddProductToCartResponse, } from './actions/add-product-to-cart/types';
|
|
153
152
|
export type { RemoveProductFromCart, RemoveProductFromCartParams, RemoveProductFromCartResponse, } from './actions/remove-product-from-cart/types';
|
|
154
153
|
export type { UpdateCartItemQuantity, UpdateCartItemQuantityParams, UpdateCartItemQuantityResponse, } from './actions/update-cart-item-quantity/types';
|
|
155
154
|
export type { AddCartDiscount, AddCartDiscountParams, AddCartDiscountResponse, } from './actions/add-cart-discount/types';
|
|
@@ -157,6 +156,8 @@ export type { GetContext, GetContextResponse, GetContextResponseManage, GetConte
|
|
|
157
156
|
export type { GetFinalContext, GetFinalContextResponse } from './actions/get-final-context/types';
|
|
158
157
|
export type { AddProductNote, AddProductNoteParams, AddProductNoteResponse } from './actions/add-product-note/types';
|
|
159
158
|
export type { AddProductFee, AddProductFeeParams, AddProductFeeResponse } from './actions/add-product-fee/types';
|
|
159
|
+
export type { GetProductModifierSelections, GetProductModifierSelectionsParams, GetProductModifierSelectionsResponse, ModifierSelection, ModifierChoiceSelection, } from './actions/get-product-modifier-selections/types';
|
|
160
|
+
export type { SetProductModifierSelections, SetProductModifierSelectionsParams, SetProductModifierSelectionsResponse, } from './actions/set-product-modifier-selections/types';
|
|
160
161
|
export type { SetActiveProductFee, SetActiveProductFeeParams, SetActiveProductFeeResponse, } from './actions/set-active-product-fee/types';
|
|
161
162
|
export type { SetActiveProductDiscount, SetActiveProductDiscountParams, SetActiveProductDiscountResponse, } from './actions/set-active-product-discount/types';
|
|
162
163
|
export type { GetActiveProduct, GetActiveProductResponse } from './actions/get-active-product/types';
|
|
@@ -176,8 +177,6 @@ export type { TerminalPayment, TerminalPaymentParams, TerminalPaymentResponse }
|
|
|
176
177
|
export type { ExtensionPayment, ExtensionPaymentParams, ExtensionPaymentResponse, } from './actions/extension-payment/types';
|
|
177
178
|
export type { RedeemPayment, RedeemPaymentParams, RedeemPaymentResponse } from './actions/redeem-payment/types';
|
|
178
179
|
export type { IntegrationPayment, IntegrationPaymentParams, IntegrationPaymentResponse, IntegrationEmvData, } from './actions/integration-payment/types';
|
|
179
|
-
export type { CreatePaymentLink, CreatePaymentLinkParams, CreatePaymentLinkResponse, } from './actions/create-payment-link/types';
|
|
180
|
-
export type { ChargeMoto, ChargeMotoParams, ChargeMotoResponse, ChargeMotoCardFields, } from './actions/charge-moto/types';
|
|
181
180
|
export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse, } from './actions/add-customer-note/types';
|
|
182
181
|
export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse, } from './actions/remove-customer-note/types';
|
|
183
182
|
export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from './actions/remove-customer-from-cart/types';
|
|
@@ -191,7 +190,6 @@ export type { GetMedia, GetMediaParams, GetMediaResponse, MediaItemPayload } fro
|
|
|
191
190
|
export type { UploadMedia, UploadMediaParams, UploadMediaResponse } from './actions/upload-media/types';
|
|
192
191
|
export type { GetTaxTables, GetTaxTablesResponse, TaxRatePayload, TaxTablePayload, } from './actions/get-tax-tables/types';
|
|
193
192
|
export type { BorderRadiusPreset, GetBranding, GetBrandingResponse } from './actions/get-branding/types';
|
|
194
|
-
export type { GetTimeClockStatus, GetTimeClockStatusResponse, TimeClockEntry, } from './actions/get-time-clock-status/types';
|
|
195
193
|
export type { ShowConfirmation, ShowConfirmationParams, ShowConfirmationResponse, } from './actions/show-confirmation/types';
|
|
196
194
|
export type { AuthenticateUser, AuthenticateUserParams, AuthenticateUserResponse, } from './actions/authenticate-user/types';
|
|
197
195
|
export type { PartialPayment, PartialPaymentParams, PartialPaymentResponse } from './actions/partial-payment/types';
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ import { updateCartItemQuantity } from './actions/update-cart-item-quantity/acti
|
|
|
20
20
|
// Product Actions
|
|
21
21
|
import { addProductNote } from './actions/add-product-note/action';
|
|
22
22
|
import { addProductFee } from './actions/add-product-fee/action';
|
|
23
|
+
import { getProductModifierSelections } from './actions/get-product-modifier-selections/action';
|
|
24
|
+
import { setProductModifierSelections } from './actions/set-product-modifier-selections/action';
|
|
23
25
|
import { setActiveProductFee } from './actions/set-active-product-fee/action';
|
|
24
26
|
import { setActiveProductDiscount } from './actions/set-active-product-discount/action';
|
|
25
27
|
import { getActiveProduct } from './actions/get-active-product/action';
|
|
@@ -41,8 +43,6 @@ import { terminalPayment } from './actions/terminal-payment/action';
|
|
|
41
43
|
import { extensionPayment } from './actions/extension-payment/action';
|
|
42
44
|
import { redeemPayment } from './actions/redeem-payment/action';
|
|
43
45
|
import { integrationPayment } from './actions/integration-payment/action';
|
|
44
|
-
import { createPaymentLink } from './actions/create-payment-link/action';
|
|
45
|
-
import { chargeMoto } from './actions/charge-moto/action';
|
|
46
46
|
// Customer Actions
|
|
47
47
|
import { addCustomerNote } from './actions/add-customer-note/action';
|
|
48
48
|
import { removeCustomerNote } from './actions/remove-customer-note/action';
|
|
@@ -130,8 +130,6 @@ import { getMedia } from './actions/get-media/action';
|
|
|
130
130
|
import { uploadMedia } from './actions/upload-media/action';
|
|
131
131
|
import { getTaxTables } from './actions/get-tax-tables/action';
|
|
132
132
|
import { getBranding } from './actions/get-branding/action';
|
|
133
|
-
// Time Clock Actions
|
|
134
|
-
import { getTimeClockStatus } from './actions/get-time-clock-status/action';
|
|
135
133
|
// Export actions as command object
|
|
136
134
|
export const command = {
|
|
137
135
|
exampleFunction,
|
|
@@ -157,6 +155,8 @@ export const command = {
|
|
|
157
155
|
// Product Actions
|
|
158
156
|
addProductNote,
|
|
159
157
|
addProductFee,
|
|
158
|
+
getProductModifierSelections,
|
|
159
|
+
setProductModifierSelections,
|
|
160
160
|
setActiveProductFee,
|
|
161
161
|
setActiveProductDiscount,
|
|
162
162
|
getActiveProduct,
|
|
@@ -178,8 +178,6 @@ export const command = {
|
|
|
178
178
|
extensionPayment,
|
|
179
179
|
redeemPayment,
|
|
180
180
|
integrationPayment,
|
|
181
|
-
createPaymentLink,
|
|
182
|
-
chargeMoto,
|
|
183
181
|
// Customer Actions
|
|
184
182
|
addCustomerNote,
|
|
185
183
|
removeCustomerNote,
|
|
@@ -262,8 +260,6 @@ export const command = {
|
|
|
262
260
|
uploadMedia,
|
|
263
261
|
getTaxTables,
|
|
264
262
|
getBranding,
|
|
265
|
-
// Time Clock Actions
|
|
266
|
-
getTimeClockStatus,
|
|
267
263
|
// State Machine Queries
|
|
268
264
|
canTransition,
|
|
269
265
|
getAvailableTransitions,
|
|
@@ -12,6 +12,8 @@ import { mockAddOrderNote } from '../../actions/add-order-note/mock';
|
|
|
12
12
|
import { mockRemoveOrderNote } from '../../actions/remove-order-note/mock';
|
|
13
13
|
import { mockAddProductDiscount } from '../../actions/add-product-discount/mock';
|
|
14
14
|
import { mockAddProductFee } from '../../actions/add-product-fee/mock';
|
|
15
|
+
import { mockGetProductModifierSelections } from '../../actions/get-product-modifier-selections/mock';
|
|
16
|
+
import { mockSetProductModifierSelections } from '../../actions/set-product-modifier-selections/mock';
|
|
15
17
|
import { mockRemoveProductDiscount } from '../../actions/remove-product-discount/mock';
|
|
16
18
|
import { mockRemoveProductFee } from '../../actions/remove-product-fee/mock';
|
|
17
19
|
import { mockSetActiveProductFee } from '../../actions/set-active-product-fee/mock';
|
|
@@ -29,9 +31,6 @@ import { mockAuthenticateUser } from '../../actions/authenticate-user/mock';
|
|
|
29
31
|
import { mockCalculateRefundTotal } from '../../actions/calculate-refund-total/mock';
|
|
30
32
|
import { mockCashPayment } from '../../actions/cash-payment/mock';
|
|
31
33
|
import { mockGetCashRoundingAmount } from '../../actions/get-cash-rounding-amount/mock';
|
|
32
|
-
import { mockCreatePaymentLink } from '../../actions/create-payment-link/mock';
|
|
33
|
-
import { mockChargeMoto } from '../../actions/charge-moto/mock';
|
|
34
|
-
import { mockGetTimeClockStatus } from '../../actions/get-time-clock-status/mock';
|
|
35
34
|
import { mockClearCart } from '../../actions/clear-cart/mock';
|
|
36
35
|
import { mockDeleteParkedOrder } from '../../actions/delete-parked-order/mock';
|
|
37
36
|
import { mockVoidOrder } from '../../actions/void-order/mock';
|
|
@@ -112,6 +111,8 @@ export const RENDER_MOCKS = {
|
|
|
112
111
|
addOrderNote: mockAddOrderNote,
|
|
113
112
|
addProductDiscount: mockAddProductDiscount,
|
|
114
113
|
addProductFee: mockAddProductFee,
|
|
114
|
+
getProductModifierSelections: mockGetProductModifierSelections,
|
|
115
|
+
setProductModifierSelections: mockSetProductModifierSelections,
|
|
115
116
|
setActiveProductFee: mockSetActiveProductFee,
|
|
116
117
|
setActiveProductDiscount: mockSetActiveProductDiscount,
|
|
117
118
|
getActiveProduct: mockGetActiveProduct,
|
|
@@ -126,8 +127,6 @@ export const RENDER_MOCKS = {
|
|
|
126
127
|
calculateRefundTotal: mockCalculateRefundTotal,
|
|
127
128
|
cashPayment: mockCashPayment,
|
|
128
129
|
getCashRoundingAmount: mockGetCashRoundingAmount,
|
|
129
|
-
createPaymentLink: mockCreatePaymentLink,
|
|
130
|
-
chargeMoto: mockChargeMoto,
|
|
131
130
|
clearCart: mockClearCart,
|
|
132
131
|
deleteParkedOrder: mockDeleteParkedOrder,
|
|
133
132
|
voidOrder: mockVoidOrder,
|
|
@@ -204,5 +203,4 @@ export const RENDER_MOCKS = {
|
|
|
204
203
|
saveSmartGridLayout: mockSaveSmartGridLayout,
|
|
205
204
|
sendEmail: mockSendEmail,
|
|
206
205
|
sendSms: mockSendSms,
|
|
207
|
-
getTimeClockStatus: mockGetTimeClockStatus,
|
|
208
206
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, VoidOrder, InitiateRefund, CashPayment, GetCashRoundingAmount, TapToPayPayment, TerminalPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, RedeemRefund, GetRefundPlan, CheckPermission, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles, RemoveCartDiscount, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, GetActiveStation, GetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem, CanTransition, GetAvailableTransitions, ApplyTransition, IntegrationPayment, GetSmartGridLayout, SaveSmartGridLayout, SendEmail, SendSms
|
|
1
|
+
import type { ExampleFunction, GetProducts, AddCustomSale, EditCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, GetProductModifierSelections, SetProductModifierSelections, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, VoidOrder, InitiateRefund, CashPayment, GetCashRoundingAmount, TapToPayPayment, TerminalPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, RedeemRefund, GetRefundPlan, CheckPermission, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles, RemoveCartDiscount, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, GetActiveStation, GetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem, CanTransition, GetAvailableTransitions, ApplyTransition, IntegrationPayment, GetSmartGridLayout, SaveSmartGridLayout, SendEmail, SendSms } from '../../index';
|
|
2
2
|
export interface RenderProviderActions {
|
|
3
3
|
exampleFunction: ExampleFunction;
|
|
4
4
|
getProducts: GetProducts;
|
|
@@ -21,6 +21,8 @@ export interface RenderProviderActions {
|
|
|
21
21
|
getFinalContext: GetFinalContext;
|
|
22
22
|
addProductNote: AddProductNote;
|
|
23
23
|
addProductFee: AddProductFee;
|
|
24
|
+
getProductModifierSelections: GetProductModifierSelections;
|
|
25
|
+
setProductModifierSelections: SetProductModifierSelections;
|
|
24
26
|
setActiveProductFee: SetActiveProductFee;
|
|
25
27
|
setActiveProductDiscount: SetActiveProductDiscount;
|
|
26
28
|
getActiveProduct: GetActiveProduct;
|
|
@@ -41,8 +43,6 @@ export interface RenderProviderActions {
|
|
|
41
43
|
extensionPayment: ExtensionPayment;
|
|
42
44
|
redeemPayment: RedeemPayment;
|
|
43
45
|
integrationPayment: IntegrationPayment;
|
|
44
|
-
createPaymentLink: CreatePaymentLink;
|
|
45
|
-
chargeMoto: ChargeMoto;
|
|
46
46
|
addNonRevenueItem: AddNonRevenueItem;
|
|
47
47
|
addCustomerNote: AddCustomerNote;
|
|
48
48
|
removeCustomerNote: RemoveCustomerNote;
|
|
@@ -103,5 +103,4 @@ export interface RenderProviderActions {
|
|
|
103
103
|
saveSmartGridLayout: SaveSmartGridLayout;
|
|
104
104
|
sendEmail: SendEmail;
|
|
105
105
|
sendSms: SendSms;
|
|
106
|
-
getTimeClockStatus: GetTimeClockStatus;
|
|
107
106
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CFActiveProduct, CFModifierSelection } from "../../../../CommonTypes";
|
|
2
|
+
import type { TopicEvent } from "../../../types";
|
|
3
|
+
/**
|
|
4
|
+
* Payload for product-modifiers-updated event (FT-0010) — fired when a cart
|
|
5
|
+
* line's modifier selections are replaced via setProductModifierSelections.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProductModifiersUpdatedPayload {
|
|
8
|
+
product: CFActiveProduct;
|
|
9
|
+
internalId?: string;
|
|
10
|
+
/** The line's complete new answers (full replacement). */
|
|
11
|
+
selections: CFModifierSelection[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Typed event for product-modifiers-updated
|
|
15
|
+
*/
|
|
16
|
+
export type ProductModifiersUpdatedEvent = TopicEvent<ProductModifiersUpdatedPayload>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -17,6 +17,7 @@ export * from "./product-fee-added/types";
|
|
|
17
17
|
export * from "./product-fee-removed/types";
|
|
18
18
|
export * from "./product-note-added/types";
|
|
19
19
|
export * from "./product-note-removed/types";
|
|
20
|
+
export * from "./product-modifiers-updated/types";
|
|
20
21
|
import type { CartCreatedPayload } from "./cart-created/types";
|
|
21
22
|
import type { CartCustomerAssignedPayload } from "./customer-assigned/types";
|
|
22
23
|
import type { ProductAddedPayload } from "./product-added/types";
|
|
@@ -32,5 +33,6 @@ import type { ProductFeeAddedPayload } from "./product-fee-added/types";
|
|
|
32
33
|
import type { ProductFeeRemovedPayload } from "./product-fee-removed/types";
|
|
33
34
|
import type { ProductNoteAddedPayload } from "./product-note-added/types";
|
|
34
35
|
import type { ProductNoteRemovedPayload } from "./product-note-removed/types";
|
|
35
|
-
|
|
36
|
-
export type
|
|
36
|
+
import type { ProductModifiersUpdatedPayload } from "./product-modifiers-updated/types";
|
|
37
|
+
export type CartEventPayload = CartCreatedPayload | CartCustomerAssignedPayload | ProductAddedPayload | ProductDeletedPayload | CartProductUpdatedPayload | CartDiscountAddedPayload | CartDiscountRemovedPayload | CartFeeAddedPayload | CartFeeRemovedPayload | ProductDiscountAddedPayload | ProductDiscountRemovedPayload | ProductFeeAddedPayload | ProductFeeRemovedPayload | ProductNoteAddedPayload | ProductNoteRemovedPayload | ProductModifiersUpdatedPayload;
|
|
38
|
+
export type CartEventType = "cart-created" | "customer-assigned" | "customer-unassigned" | "product-added" | "product-deleted" | "product-updated" | "cart-discount-added" | "cart-discount-removed" | "cart-fee-added" | "cart-fee-removed" | "product-discount-added" | "product-discount-removed" | "product-fee-added" | "product-fee-removed" | "product-note-added" | "product-note-removed" | "product-modifiers-updated";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@final-commerce/command-frame",
|
|
3
|
-
"version": "0.6.0-
|
|
3
|
+
"version": "0.6.0-staging3.1",
|
|
4
4
|
"description": "Commands Frame library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"ignoreBranchesMissingTickets": true
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@final-commerce/common": "2.2.
|
|
60
|
+
"@final-commerce/common": "2.2.3-staging3.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@commitlint/cli": "^19.0.0",
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { applyMockPayment, MOCK_CART } from '../../demo/database';
|
|
2
|
-
/** Mirrors kaching's `MOTO_MIN_AMOUNT_MINOR` — the processors' floor. */
|
|
3
|
-
const MOTO_MIN_AMOUNT_MINOR = 50;
|
|
4
|
-
/** The card fields that must be present and non-empty on every keyed charge. */
|
|
5
|
-
const REQUIRED_CARD_FIELDS = [
|
|
6
|
-
'encryptedCardNumber',
|
|
7
|
-
'encryptedExpiryMonth',
|
|
8
|
-
'encryptedExpiryYear',
|
|
9
|
-
'encryptedSecurityCode',
|
|
10
|
-
];
|
|
11
|
-
export const mockChargeMoto = async (params) => {
|
|
12
|
-
console.log('[Mock] chargeMoto called', params);
|
|
13
|
-
if (!params)
|
|
14
|
-
throw new Error('Params required');
|
|
15
|
-
if (!Number.isInteger(params.amount)) {
|
|
16
|
-
throw new Error('amount must be an integer number of minor units');
|
|
17
|
-
}
|
|
18
|
-
if (params.amount < MOTO_MIN_AMOUNT_MINOR) {
|
|
19
|
-
throw new Error(`amount must be at least ${MOTO_MIN_AMOUNT_MINOR} minor units`);
|
|
20
|
-
}
|
|
21
|
-
for (const field of REQUIRED_CARD_FIELDS) {
|
|
22
|
-
const value = params.card?.[field];
|
|
23
|
-
if (!value || !value.trim()) {
|
|
24
|
-
throw new Error(`card.${field} is required`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
if (!params.idempotencyKey || !params.idempotencyKey.trim()) {
|
|
28
|
-
throw new Error('idempotencyKey is required so a retry replays instead of recharging');
|
|
29
|
-
}
|
|
30
|
-
const balanceDue = MOCK_CART.amountToBeCharged ?? MOCK_CART.total;
|
|
31
|
-
if (params.amount > balanceDue) {
|
|
32
|
-
throw new Error(`amount ${params.amount} exceeds balance due ${balanceDue}`);
|
|
33
|
-
}
|
|
34
|
-
// The mock always completes the sale in one leg — it does not model
|
|
35
|
-
// kaching's real partial-leg (`saleFinalized: false`) path.
|
|
36
|
-
const order = applyMockPayment(balanceDue, 'card', 'adyen');
|
|
37
|
-
if (!order) {
|
|
38
|
-
throw new Error('MOCK_CHARGE_MOTO_PARTIAL_UNSUPPORTED: the mock only supports charging the full balance due');
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
success: true,
|
|
42
|
-
timestamp: new Date().toISOString(),
|
|
43
|
-
order,
|
|
44
|
-
saleFinalized: true,
|
|
45
|
-
remainingBalance: 0,
|
|
46
|
-
};
|
|
47
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { CFOrder } from '../../CommonTypes';
|
|
2
|
-
/**
|
|
3
|
-
* Provider-encrypted card fields, opaque to this library — mirrors kaching's
|
|
4
|
-
* `MotoCardFields` field for field. Never a raw PAN: these are the CSE blobs
|
|
5
|
-
* the provider's own client-side encrypter produces.
|
|
6
|
-
*/
|
|
7
|
-
export interface ChargeMotoCardFields {
|
|
8
|
-
encryptedCardNumber: string;
|
|
9
|
-
encryptedExpiryMonth: string;
|
|
10
|
-
encryptedExpiryYear: string;
|
|
11
|
-
encryptedSecurityCode: string;
|
|
12
|
-
/** Optional AVS postal code the operator entered. */
|
|
13
|
-
postalCode?: string;
|
|
14
|
-
/** Provider-side `reference` for this payment. Defaults to the idempotency key server-side. */
|
|
15
|
-
reference?: string;
|
|
16
|
-
}
|
|
17
|
-
export interface ChargeMotoParams {
|
|
18
|
-
/**
|
|
19
|
-
* Total to charge, base + tip, in integer MINOR currency units. Minimum 50
|
|
20
|
-
* minor units (the processors' floor). This is the leg amount: a value
|
|
21
|
-
* below the cart's balance due records a partial payment.
|
|
22
|
-
*/
|
|
23
|
-
amount: number;
|
|
24
|
-
/** Tip portion of `amount`, already collected by the caller's own UI. Defaults to 0. */
|
|
25
|
-
tipAmount?: number;
|
|
26
|
-
/**
|
|
27
|
-
* ISO 4217 code. Optional — the active company's currency is authoritative.
|
|
28
|
-
* When supplied it must match, or the charge is rejected before anything is sent.
|
|
29
|
-
*/
|
|
30
|
-
currency?: string;
|
|
31
|
-
card: ChargeMotoCardFields;
|
|
32
|
-
/**
|
|
33
|
-
* Idempotency key for this charge, HELD BY THE CALLER across retries. A
|
|
34
|
-
* retried charge must carry the SAME key so the charge is replayed instead
|
|
35
|
-
* of doubled; use a NEW key after changing the amount.
|
|
36
|
-
*/
|
|
37
|
-
idempotencyKey: string;
|
|
38
|
-
/** Optional tender label recorded on the payment method. */
|
|
39
|
-
paymentName?: string;
|
|
40
|
-
/** Fulfillment state to land on after full payment (default: auto-fulfill). */
|
|
41
|
-
targetFulfillmentState?: string;
|
|
42
|
-
}
|
|
43
|
-
export interface ChargeMotoResponse {
|
|
44
|
-
success: boolean;
|
|
45
|
-
timestamp: string;
|
|
46
|
-
/** The persisted order the charge landed on. */
|
|
47
|
-
order: CFOrder;
|
|
48
|
-
/** True only when this charge completed the sale (`paymentState === 'paid'`). */
|
|
49
|
-
saleFinalized: boolean;
|
|
50
|
-
/** Balance still due after this charge, in integer minor units. 0 when finalized. */
|
|
51
|
-
remainingBalance: number;
|
|
52
|
-
}
|
|
53
|
-
export type ChargeMoto = (params: ChargeMotoParams) => Promise<ChargeMotoResponse>;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create payment link action
|
|
3
|
-
* Calls the createPaymentLink action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const createPaymentLink = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('createPaymentLink', params);
|
|
8
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { MOCK_CART, mockPublishEvent, resetMockCart } from '../../demo/database';
|
|
2
|
-
export const mockCreatePaymentLink = async (params) => {
|
|
3
|
-
console.log('[Mock] createPaymentLink called', params);
|
|
4
|
-
if (!params)
|
|
5
|
-
throw new Error('Params required');
|
|
6
|
-
const email = params.email?.trim() ? params.email : undefined;
|
|
7
|
-
const phone = params.phone?.trim() ? params.phone : undefined;
|
|
8
|
-
if (email && phone) {
|
|
9
|
-
throw new Error('exactly one of email or phone delivers a payment link, not both');
|
|
10
|
-
}
|
|
11
|
-
if (!email && !phone) {
|
|
12
|
-
throw new Error('exactly one of email or phone is required to deliver the payment link');
|
|
13
|
-
}
|
|
14
|
-
const hasCart = MOCK_CART.products.length > 0 ||
|
|
15
|
-
(MOCK_CART.customSales?.length ?? 0) > 0 ||
|
|
16
|
-
(MOCK_CART.nonRevenueItems?.length ?? 0) > 0;
|
|
17
|
-
if (!hasCart || MOCK_CART.total <= 0) {
|
|
18
|
-
throw new Error('ring the sale up before creating a payment link: the cart is empty');
|
|
19
|
-
}
|
|
20
|
-
const mockOrderId = 'order_' + Date.now();
|
|
21
|
-
const mockLinkId = 'link_' + Math.random().toString(36).substr(2, 9);
|
|
22
|
-
// Marks the cart consumed, same as a successful send in kaching — the order
|
|
23
|
-
// now owns the line.
|
|
24
|
-
resetMockCart();
|
|
25
|
-
mockPublishEvent('cart', 'cart-created', {});
|
|
26
|
-
return {
|
|
27
|
-
success: true,
|
|
28
|
-
timestamp: new Date().toISOString(),
|
|
29
|
-
orderId: mockOrderId,
|
|
30
|
-
url: `https://mock.finalpos.dev/pay/${mockLinkId}`,
|
|
31
|
-
id: mockLinkId,
|
|
32
|
-
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
|
33
|
-
delivery: email ? { email: 'sent' } : { sms: 'sent' },
|
|
34
|
-
};
|
|
35
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export interface CreatePaymentLinkParams {
|
|
2
|
-
/** Address to email the link to. Exactly one of `email`/`phone` is required. */
|
|
3
|
-
email?: string;
|
|
4
|
-
/** Phone number to text the link to, E.164 (e.g. "+15555550123"). Exactly one of `email`/`phone` is required. */
|
|
5
|
-
phone?: string;
|
|
6
|
-
}
|
|
7
|
-
export interface CreatePaymentLinkResponse {
|
|
8
|
-
success: boolean;
|
|
9
|
-
timestamp: string;
|
|
10
|
-
/** Client `_id` of the order the station created for this link (charges the CURRENT CART). */
|
|
11
|
-
orderId: string;
|
|
12
|
-
/** Hosted payment page to send the shopper. */
|
|
13
|
-
url: string;
|
|
14
|
-
/** The provider's payment-link id. */
|
|
15
|
-
id: string;
|
|
16
|
-
/** When the link stops accepting payment (ISO date string). */
|
|
17
|
-
expiresAt: string;
|
|
18
|
-
/**
|
|
19
|
-
* Per-channel delivery outcome. OPTIONAL: an older hub omits it entirely,
|
|
20
|
-
* which reads as "delivered" — treat absence as success, not as a failure.
|
|
21
|
-
*/
|
|
22
|
-
delivery?: {
|
|
23
|
-
email?: 'sent' | 'failed';
|
|
24
|
-
sms?: 'sent' | 'failed';
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
export type CreatePaymentLink = (params: CreatePaymentLinkParams) => Promise<CreatePaymentLinkResponse>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Create Payment Link Types
|
|
2
|
-
//
|
|
3
|
-
// Creates a hosted payment link FOR THE CURRENT CART (station-v2 D-decisions,
|
|
4
|
-
// payment-link addendum). Mirrors kaching's `createPaymentLinkFromCart` input
|
|
5
|
-
// (`CreatePaymentLinkFromCartInput`) and result (`PaymentLinkFromCartResult`,
|
|
6
|
-
// which extends the provider's `PaymentLinkResponse` with the local `orderId`).
|
|
7
|
-
//
|
|
8
|
-
// The station creates the order (client `_id`, `unpaid × in_progress`) BEFORE
|
|
9
|
-
// the link is requested — only that id travels on the wire. On success the
|
|
10
|
-
// cart is cleared; on a failed send the order is voided and the cart is kept
|
|
11
|
-
// so the cashier can retry. Adyen-only today.
|
|
12
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get time clock status action
|
|
3
|
-
* Calls the getTimeClockStatus action on the parent window
|
|
4
|
-
*/
|
|
5
|
-
import { commandFrameClient } from '../../client';
|
|
6
|
-
export const getTimeClockStatus = async (params) => {
|
|
7
|
-
return await commandFrameClient.call('getTimeClockStatus', params);
|
|
8
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** Fixed shift start used by the mock — a clocked-in snapshot with no break taken. */
|
|
2
|
-
const MOCK_CLOCK_IN_TIME = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
|
|
3
|
-
export const mockGetTimeClockStatus = async (params) => {
|
|
4
|
-
console.log('[Mock] getTimeClockStatus called', params);
|
|
5
|
-
const workedMs = Date.now() - new Date(MOCK_CLOCK_IN_TIME).getTime();
|
|
6
|
-
return {
|
|
7
|
-
success: true,
|
|
8
|
-
timestamp: new Date().toISOString(),
|
|
9
|
-
status: 'clocked-in',
|
|
10
|
-
entry: {
|
|
11
|
-
clockInTime: MOCK_CLOCK_IN_TIME,
|
|
12
|
-
breakStartedAt: null,
|
|
13
|
-
totalBreakMinutes: 0,
|
|
14
|
-
workedMs,
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface TimeClockEntry {
|
|
2
|
-
/** ISO date string of when the current shift started. */
|
|
3
|
-
clockInTime: string;
|
|
4
|
-
/** ISO date string of when the current break started, or `null` when not on break. */
|
|
5
|
-
breakStartedAt: string | null;
|
|
6
|
-
/** Total break time accumulated on this shift so far, in minutes. */
|
|
7
|
-
totalBreakMinutes: number;
|
|
8
|
-
/** Milliseconds worked so far on this shift, as of when this response was generated. */
|
|
9
|
-
workedMs: number;
|
|
10
|
-
}
|
|
11
|
-
export interface GetTimeClockStatusResponse {
|
|
12
|
-
success: boolean;
|
|
13
|
-
timestamp: string;
|
|
14
|
-
status: 'out' | 'clocked-in' | 'on-break';
|
|
15
|
-
/** `null` when `status` is `'out'`. */
|
|
16
|
-
entry: TimeClockEntry | null;
|
|
17
|
-
}
|
|
18
|
-
export type GetTimeClockStatus = (params?: Record<string, never>) => Promise<GetTimeClockStatusResponse>;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
// Get Time Clock Status Types
|
|
2
|
-
//
|
|
3
|
-
// READ-ONLY query: is the active employee clocked out, clocked in, or on
|
|
4
|
-
// break, and since when? There are no clock-in/clock-out commands — this
|
|
5
|
-
// action only reports the current state; `workedMs` is a snapshot at call
|
|
6
|
-
// time and flows are expected to tick it client-side from `clockInTime`.
|
|
7
|
-
export {};
|
|
File without changes
|