@final-commerce/command-frame 0.8.0 → 0.9.0-staging.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/dist/CommonTypes.d.ts +25 -1
- package/dist/actions/add-product-fee/mock.d.ts +1 -1
- package/dist/actions/add-product-fee/mock.js +15 -9
- package/dist/actions/add-product-to-cart/mock.d.ts +23 -0
- package/dist/actions/add-product-to-cart/mock.js +300 -1
- package/dist/actions/add-product-to-cart/types.d.ts +27 -1
- package/dist/actions/get-composite-availability/action.d.ts +6 -0
- package/dist/actions/get-composite-availability/action.js +8 -0
- package/dist/actions/get-composite-availability/mock.d.ts +2 -0
- package/dist/actions/get-composite-availability/mock.js +45 -0
- package/dist/actions/get-composite-availability/types.d.ts +29 -0
- package/dist/actions/get-composite-availability/types.js +1 -0
- package/dist/actions/get-composite-price/action.d.ts +6 -0
- package/dist/actions/get-composite-price/action.js +8 -0
- package/dist/actions/get-composite-price/mock.d.ts +2 -0
- package/dist/actions/get-composite-price/mock.js +37 -0
- package/dist/actions/get-composite-price/types.d.ts +31 -0
- package/dist/actions/get-composite-price/types.js +1 -0
- package/dist/actions/get-current-cart/mock.d.ts +1 -1
- package/dist/actions/get-current-cart/mock.js +13 -3
- package/dist/actions/get-current-cart/types.d.ts +7 -1
- package/dist/actions/get-product-modifier-selections/mock.js +12 -0
- package/dist/actions/get-products/mock.js +7 -3
- package/dist/actions/get-products/types.d.ts +1 -1
- package/dist/actions/get-refund-plan/mock.d.ts +0 -4
- package/dist/actions/get-refund-plan/mock.js +0 -8
- package/dist/actions/get-refund-plan/types.d.ts +0 -89
- package/dist/actions/set-product-modifier-selections/mock.js +12 -0
- package/dist/demo/database.d.ts +39 -1
- package/dist/demo/database.js +214 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -0
- package/dist/projects/render/mocks.js +4 -0
- package/dist/projects/render/types.d.ts +3 -1
- package/dist/pubsub/topics/products/catalog-visibility-changed/types.d.ts +17 -0
- package/dist/pubsub/topics/products/catalog-visibility-changed/types.js +1 -0
- package/dist/pubsub/topics/products/composite-changed/types.d.ts +17 -0
- package/dist/pubsub/topics/products/composite-changed/types.js +1 -0
- package/dist/pubsub/topics/products/index.d.ts +2 -2
- package/dist/pubsub/topics/products/index.js +33 -18
- package/dist/pubsub/topics/products/inventory-changed/types.d.ts +18 -0
- package/dist/pubsub/topics/products/inventory-changed/types.js +1 -0
- package/dist/pubsub/topics/products/types.d.ts +16 -10
- package/dist/pubsub/topics/products/types.js +7 -4
- package/package.json +2 -2
- package/dist/actions/get-refund-plan/mockRows.d.ts +0 -6
- package/dist/actions/get-refund-plan/mockRows.js +0 -114
package/dist/index.js
CHANGED
|
@@ -28,6 +28,8 @@ import { updateCartItemQuantity } from './actions/update-cart-item-quantity/acti
|
|
|
28
28
|
import { addProductNote } from './actions/add-product-note/action';
|
|
29
29
|
import { addProductFee } from './actions/add-product-fee/action';
|
|
30
30
|
import { getProductModifierSelections } from './actions/get-product-modifier-selections/action';
|
|
31
|
+
import { getCompositePrice } from './actions/get-composite-price/action';
|
|
32
|
+
import { getCompositeAvailability } from './actions/get-composite-availability/action';
|
|
31
33
|
import { setProductModifierSelections } from './actions/set-product-modifier-selections/action';
|
|
32
34
|
import { setActiveProductFee } from './actions/set-active-product-fee/action';
|
|
33
35
|
import { setActiveProductDiscount } from './actions/set-active-product-discount/action';
|
|
@@ -174,6 +176,8 @@ export const command = {
|
|
|
174
176
|
addProductNote,
|
|
175
177
|
addProductFee,
|
|
176
178
|
getProductModifierSelections,
|
|
179
|
+
getCompositePrice,
|
|
180
|
+
getCompositeAvailability,
|
|
177
181
|
setProductModifierSelections,
|
|
178
182
|
setActiveProductFee,
|
|
179
183
|
setActiveProductDiscount,
|
|
@@ -13,6 +13,8 @@ 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
15
|
import { mockGetProductModifierSelections } from '../../actions/get-product-modifier-selections/mock';
|
|
16
|
+
import { mockGetCompositePrice } from '../../actions/get-composite-price/mock';
|
|
17
|
+
import { mockGetCompositeAvailability } from '../../actions/get-composite-availability/mock';
|
|
16
18
|
import { mockSetProductModifierSelections } from '../../actions/set-product-modifier-selections/mock';
|
|
17
19
|
import { mockRemoveProductDiscount } from '../../actions/remove-product-discount/mock';
|
|
18
20
|
import { mockRemoveProductFee } from '../../actions/remove-product-fee/mock';
|
|
@@ -122,6 +124,8 @@ export const RENDER_MOCKS = {
|
|
|
122
124
|
addProductDiscount: mockAddProductDiscount,
|
|
123
125
|
addProductFee: mockAddProductFee,
|
|
124
126
|
getProductModifierSelections: mockGetProductModifierSelections,
|
|
127
|
+
getCompositePrice: mockGetCompositePrice,
|
|
128
|
+
getCompositeAvailability: mockGetCompositeAvailability,
|
|
125
129
|
setProductModifierSelections: mockSetProductModifierSelections,
|
|
126
130
|
setActiveProductFee: mockSetActiveProductFee,
|
|
127
131
|
setActiveProductDiscount: mockSetActiveProductDiscount,
|
|
@@ -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, 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, GetBookingResources, GetBookingAvailability, GetBookings, HoldBooking, AddBookingToCart, RemoveBookingFromCart, CancelBooking, CreatePaymentLink, ChargeMoto, GetTimeClockStatus } from '../../index';
|
|
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, GetCompositePrice, GetCompositeAvailability, 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, GetBookingResources, GetBookingAvailability, GetBookings, HoldBooking, AddBookingToCart, RemoveBookingFromCart, CancelBooking, CreatePaymentLink, ChargeMoto, GetTimeClockStatus } from '../../index';
|
|
2
2
|
export interface RenderProviderActions {
|
|
3
3
|
exampleFunction: ExampleFunction;
|
|
4
4
|
getProducts: GetProducts;
|
|
@@ -29,6 +29,8 @@ export interface RenderProviderActions {
|
|
|
29
29
|
addProductNote: AddProductNote;
|
|
30
30
|
addProductFee: AddProductFee;
|
|
31
31
|
getProductModifierSelections: GetProductModifierSelections;
|
|
32
|
+
getCompositePrice: GetCompositePrice;
|
|
33
|
+
getCompositeAvailability: GetCompositeAvailability;
|
|
32
34
|
setProductModifierSelections: SetProductModifierSelections;
|
|
33
35
|
setActiveProductFee: SetActiveProductFee;
|
|
34
36
|
setActiveProductDiscount: SetActiveProductDiscount;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TopicEvent } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Payload for catalog-visibility-changed: a product was hidden or shown at an outlet. `getProducts` leaves hidden
|
|
4
|
+
* products out and a composite offers only items sold at the till's outlet — debounce, then re-ask `getProducts`.
|
|
5
|
+
*/
|
|
6
|
+
export interface CatalogVisibilityChangedPayload {
|
|
7
|
+
visibility: {
|
|
8
|
+
_id: string;
|
|
9
|
+
productId: string;
|
|
10
|
+
outletId: string;
|
|
11
|
+
isDeleted?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Typed event for catalog-visibility-changed
|
|
16
|
+
*/
|
|
17
|
+
export type CatalogVisibilityChangedEvent = TopicEvent<CatalogVisibilityChangedPayload>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TopicEvent } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Payload for composite-changed (FT-83): a part or item of a composite arrived. A save replaces all of a composite's
|
|
4
|
+
* parts and items at once (old rows come as `isDeleted: true`, new ones with new ids), so one save fires this many
|
|
5
|
+
* times — debounce, then re-ask `getProducts`; never patch `product.composite` from the row.
|
|
6
|
+
*/
|
|
7
|
+
export interface CompositeChangedPayload {
|
|
8
|
+
compositeRow: {
|
|
9
|
+
_id: string;
|
|
10
|
+
compositeProductId: string;
|
|
11
|
+
isDeleted?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Typed event for composite-changed
|
|
16
|
+
*/
|
|
17
|
+
export type CompositeChangedEvent = TopicEvent<CompositeChangedPayload>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Products Topic Definition
|
|
3
3
|
* Defines the products topic and its available event types
|
|
4
4
|
*/
|
|
5
|
-
import type { TopicDefinition } from
|
|
5
|
+
import type { TopicDefinition } from '../../types';
|
|
6
6
|
export declare const productsTopic: TopicDefinition;
|
|
7
|
-
export * from
|
|
7
|
+
export * from './types';
|
|
@@ -3,31 +3,46 @@
|
|
|
3
3
|
* Defines the products topic and its available event types
|
|
4
4
|
*/
|
|
5
5
|
export const productsTopic = {
|
|
6
|
-
id:
|
|
7
|
-
name:
|
|
8
|
-
description:
|
|
6
|
+
id: 'products',
|
|
7
|
+
name: 'Products',
|
|
8
|
+
description: 'Topic for product-related events',
|
|
9
9
|
eventTypes: [
|
|
10
10
|
{
|
|
11
|
-
id:
|
|
12
|
-
name:
|
|
13
|
-
description:
|
|
11
|
+
id: 'product-created',
|
|
12
|
+
name: 'Product Created',
|
|
13
|
+
description: 'Published when a new product is synced/created',
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
|
-
id:
|
|
17
|
-
name:
|
|
18
|
-
description:
|
|
16
|
+
id: 'product-updated',
|
|
17
|
+
name: 'Product Updated',
|
|
18
|
+
description: 'Published when a product is synced/updated',
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
|
-
id:
|
|
22
|
-
name:
|
|
23
|
-
description: "Published when a
|
|
21
|
+
id: 'composite-changed',
|
|
22
|
+
name: 'Composite Changed',
|
|
23
|
+
description: "Published when a composite's part or item is synced; re-ask getProducts",
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
id:
|
|
27
|
-
name:
|
|
28
|
-
description:
|
|
29
|
-
}
|
|
30
|
-
|
|
26
|
+
id: 'catalog-visibility-changed',
|
|
27
|
+
name: 'Catalog Visibility Changed',
|
|
28
|
+
description: 'Published when a product is hidden or shown at an outlet; re-ask getProducts',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'inventory-changed',
|
|
32
|
+
name: 'Inventory Changed',
|
|
33
|
+
description: "Published when a variant's stock at an outlet syncs; re-ask getProducts",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'set-active-product',
|
|
37
|
+
name: 'Set Active Product',
|
|
38
|
+
description: 'Published when a product is set as the active product',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'get-active-product',
|
|
42
|
+
name: 'Get Active Product',
|
|
43
|
+
description: 'Published when a product is retrieved as the active product',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
31
46
|
};
|
|
32
47
|
// Re-export types
|
|
33
|
-
export * from
|
|
48
|
+
export * from './types';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TopicEvent } from '../../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Payload for inventory-changed (B35): a variant's stock at an outlet moved. A composite may turn Sold out or
|
|
4
|
+
* Unavailable by its components' shelves — debounce, then re-ask `getProducts`.
|
|
5
|
+
*/
|
|
6
|
+
export interface InventoryChangedPayload {
|
|
7
|
+
inventory: {
|
|
8
|
+
_id: string;
|
|
9
|
+
variantId: string;
|
|
10
|
+
outletId: string;
|
|
11
|
+
quantity?: number | null;
|
|
12
|
+
manageStock?: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Typed event for inventory-changed
|
|
17
|
+
*/
|
|
18
|
+
export type InventoryChangedEvent = TopicEvent<InventoryChangedPayload>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
* Products Topic Types
|
|
3
3
|
* Aggregated types for all product-related events
|
|
4
4
|
*/
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import type {
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
export * from './product-created/types';
|
|
6
|
+
export * from './product-updated/types';
|
|
7
|
+
export * from './composite-changed/types';
|
|
8
|
+
export * from './catalog-visibility-changed/types';
|
|
9
|
+
export * from './inventory-changed/types';
|
|
10
|
+
export * from './product-set-active/types';
|
|
11
|
+
export * from './product-get-active/types';
|
|
12
|
+
import type { ProductCreatedPayload } from './product-created/types';
|
|
13
|
+
import type { ProductUpdatedPayload } from './product-updated/types';
|
|
14
|
+
import type { CompositeChangedPayload } from './composite-changed/types';
|
|
15
|
+
import type { CatalogVisibilityChangedPayload } from './catalog-visibility-changed/types';
|
|
16
|
+
import type { InventoryChangedPayload } from './inventory-changed/types';
|
|
17
|
+
import type { ProductSetActivePayload } from './product-set-active/types';
|
|
18
|
+
import type { ProductGetActivePayload } from './product-get-active/types';
|
|
19
|
+
export type ProductsEventPayload = ProductCreatedPayload | ProductUpdatedPayload | CompositeChangedPayload | CatalogVisibilityChangedPayload | InventoryChangedPayload | ProductSetActivePayload | ProductGetActivePayload;
|
|
20
|
+
export type ProductsEventType = 'product-created' | 'product-updated' | 'composite-changed' | 'catalog-visibility-changed' | 'inventory-changed' | 'set-active-product' | 'get-active-product';
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
* Aggregated types for all product-related events
|
|
4
4
|
*/
|
|
5
5
|
// Re-export all event types
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
6
|
+
export * from './product-created/types';
|
|
7
|
+
export * from './product-updated/types';
|
|
8
|
+
export * from './composite-changed/types';
|
|
9
|
+
export * from './catalog-visibility-changed/types';
|
|
10
|
+
export * from './inventory-changed/types';
|
|
11
|
+
export * from './product-set-active/types';
|
|
12
|
+
export * from './product-get-active/types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@final-commerce/command-frame",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0-staging.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.
|
|
60
|
+
"@final-commerce/common": "2.5.0-staging.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@commitlint/cli": "^19.0.0",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { CFActiveOrder } from '../../CommonTypes';
|
|
2
|
-
import type { GetRefundPlanParams, RefundPlanBreakdown, RefundPlanRow } from './types';
|
|
3
|
-
/** Every row of a demo order. The demo has no refund ledger, so everything is refundable. */
|
|
4
|
-
export declare function mockRefundRows(order: CFActiveOrder): RefundPlanRow[];
|
|
5
|
-
/** The selection's breakdown; no `items` means everything, like the demo's full-refund legs. */
|
|
6
|
-
export declare function mockRefundBreakdown(rows: RefundPlanRow[], items?: GetRefundPlanParams['items']): RefundPlanBreakdown;
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
// Demo derivation of `getRefundPlan`'s `rows` and `allocation.breakdown`, for
|
|
2
|
-
// local/standalone mode only. See the note on `mockGetRefundPlan`.
|
|
3
|
-
const minor = (v) => Math.round(Number(v ?? 0)) || 0;
|
|
4
|
-
/** A line's whole-quantity money, reading `total` as tax-inclusive (the engine's reading). */
|
|
5
|
-
function lineAmounts(line) {
|
|
6
|
-
const tax = minor(line.totalTax);
|
|
7
|
-
const itemDiscount = (line.discount?.itemDiscounts ?? []).reduce((s, d) => s + minor(d.amount), 0);
|
|
8
|
-
const cartDiscount = minor(line.discount?.cartDiscount?.amount);
|
|
9
|
-
const net = Math.max(0, minor(line.total) - tax);
|
|
10
|
-
const taxes = (line.taxes ?? []).map((t) => ({
|
|
11
|
-
name: String(t.name ?? 'Tax'),
|
|
12
|
-
percentage: t.percentage,
|
|
13
|
-
amount: minor(t.amount),
|
|
14
|
-
}));
|
|
15
|
-
return { subtotal: net + itemDiscount + cartDiscount, itemDiscount, cartDiscount, tax, taxes, total: net + tax };
|
|
16
|
-
}
|
|
17
|
-
function scale(a, share) {
|
|
18
|
-
if (share >= 1)
|
|
19
|
-
return a;
|
|
20
|
-
const r = (n) => Math.round(n * share);
|
|
21
|
-
const out = {
|
|
22
|
-
subtotal: r(a.subtotal),
|
|
23
|
-
itemDiscount: r(a.itemDiscount),
|
|
24
|
-
cartDiscount: r(a.cartDiscount),
|
|
25
|
-
tax: r(a.tax),
|
|
26
|
-
taxes: a.taxes.map((t) => ({ ...t, amount: r(t.amount) })),
|
|
27
|
-
};
|
|
28
|
-
return { ...out, total: out.subtotal - out.itemDiscount - out.cartDiscount + out.tax };
|
|
29
|
-
}
|
|
30
|
-
/** Every row of a demo order. The demo has no refund ledger, so everything is refundable. */
|
|
31
|
-
export function mockRefundRows(order) {
|
|
32
|
-
const rows = [];
|
|
33
|
-
for (const li of order.lineItems ?? []) {
|
|
34
|
-
const itemKey = String(li.internalId || li.variantId || '');
|
|
35
|
-
if (!itemKey || !(li.quantity > 0))
|
|
36
|
-
continue;
|
|
37
|
-
rows.push({
|
|
38
|
-
type: 'product',
|
|
39
|
-
itemKey,
|
|
40
|
-
label: String(li.name ?? 'Item'),
|
|
41
|
-
...(li.sku ? { sku: li.sku } : {}),
|
|
42
|
-
...(li.attributes ? { attributes: li.attributes } : {}),
|
|
43
|
-
quantity: li.quantity,
|
|
44
|
-
refundableQuantity: li.quantity,
|
|
45
|
-
amounts: lineAmounts(li),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
for (const cs of order.customSales ?? []) {
|
|
49
|
-
if (!cs.customSaleId || !(cs.quantity > 0))
|
|
50
|
-
continue;
|
|
51
|
-
rows.push({
|
|
52
|
-
type: 'customSale',
|
|
53
|
-
itemKey: cs.customSaleId,
|
|
54
|
-
label: String(cs.name ?? 'Custom sale'),
|
|
55
|
-
quantity: cs.quantity,
|
|
56
|
-
refundableQuantity: cs.quantity,
|
|
57
|
-
amounts: lineAmounts(cs),
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
for (const fee of order.cartFees ?? []) {
|
|
61
|
-
const amount = minor(fee.amount);
|
|
62
|
-
const tax = minor(fee.tax);
|
|
63
|
-
rows.push({
|
|
64
|
-
type: 'fee',
|
|
65
|
-
itemKey: String(fee.id),
|
|
66
|
-
label: String(fee.label || 'Cart fee'),
|
|
67
|
-
quantity: 1,
|
|
68
|
-
refundableQuantity: 1,
|
|
69
|
-
amounts: { subtotal: amount, itemDiscount: 0, cartDiscount: 0, tax, taxes: [], total: amount + tax },
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
for (const pm of order.paymentMethods ?? []) {
|
|
73
|
-
const tip = minor(pm.tip?.amount);
|
|
74
|
-
if (tip <= 0)
|
|
75
|
-
continue;
|
|
76
|
-
rows.push({
|
|
77
|
-
type: 'tip',
|
|
78
|
-
itemKey: pm.transactionId,
|
|
79
|
-
label: 'Tip',
|
|
80
|
-
paymentType: pm.paymentType,
|
|
81
|
-
quantity: 1,
|
|
82
|
-
refundableQuantity: 1,
|
|
83
|
-
amounts: { subtotal: tip, itemDiscount: 0, cartDiscount: 0, tax: 0, taxes: [], total: tip },
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
return rows;
|
|
87
|
-
}
|
|
88
|
-
/** The selection's breakdown; no `items` means everything, like the demo's full-refund legs. */
|
|
89
|
-
export function mockRefundBreakdown(rows, items) {
|
|
90
|
-
const picked = new Map((items ?? []).map((i) => [i.itemKey, i.quantity]));
|
|
91
|
-
const selected = rows
|
|
92
|
-
.map((row) => {
|
|
93
|
-
const quantity = items?.length
|
|
94
|
-
? Math.min(picked.get(row.itemKey) ?? 0, row.refundableQuantity)
|
|
95
|
-
: row.refundableQuantity;
|
|
96
|
-
return { type: row.type, itemKey: row.itemKey, quantity, amounts: scale(row.amounts, quantity / row.quantity) };
|
|
97
|
-
})
|
|
98
|
-
.filter((r) => r.quantity > 0);
|
|
99
|
-
const totals = { items: 0, discounts: 0, fees: 0, tax: 0, tip: 0, total: 0 };
|
|
100
|
-
for (const r of selected) {
|
|
101
|
-
const a = r.amounts;
|
|
102
|
-
if (r.type === 'fee')
|
|
103
|
-
totals.fees += a.subtotal;
|
|
104
|
-
else if (r.type === 'tip')
|
|
105
|
-
totals.tip += a.subtotal;
|
|
106
|
-
else {
|
|
107
|
-
totals.items += a.subtotal;
|
|
108
|
-
totals.discounts += a.itemDiscount + a.cartDiscount;
|
|
109
|
-
}
|
|
110
|
-
totals.tax += a.tax;
|
|
111
|
-
totals.total += a.total;
|
|
112
|
-
}
|
|
113
|
-
return { rows: selected, totals };
|
|
114
|
-
}
|