@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.
Files changed (47) hide show
  1. package/dist/CommonTypes.d.ts +25 -1
  2. package/dist/actions/add-product-fee/mock.d.ts +1 -1
  3. package/dist/actions/add-product-fee/mock.js +15 -9
  4. package/dist/actions/add-product-to-cart/mock.d.ts +23 -0
  5. package/dist/actions/add-product-to-cart/mock.js +300 -1
  6. package/dist/actions/add-product-to-cart/types.d.ts +27 -1
  7. package/dist/actions/get-composite-availability/action.d.ts +6 -0
  8. package/dist/actions/get-composite-availability/action.js +8 -0
  9. package/dist/actions/get-composite-availability/mock.d.ts +2 -0
  10. package/dist/actions/get-composite-availability/mock.js +45 -0
  11. package/dist/actions/get-composite-availability/types.d.ts +29 -0
  12. package/dist/actions/get-composite-availability/types.js +1 -0
  13. package/dist/actions/get-composite-price/action.d.ts +6 -0
  14. package/dist/actions/get-composite-price/action.js +8 -0
  15. package/dist/actions/get-composite-price/mock.d.ts +2 -0
  16. package/dist/actions/get-composite-price/mock.js +37 -0
  17. package/dist/actions/get-composite-price/types.d.ts +31 -0
  18. package/dist/actions/get-composite-price/types.js +1 -0
  19. package/dist/actions/get-current-cart/mock.d.ts +1 -1
  20. package/dist/actions/get-current-cart/mock.js +13 -3
  21. package/dist/actions/get-current-cart/types.d.ts +7 -1
  22. package/dist/actions/get-product-modifier-selections/mock.js +12 -0
  23. package/dist/actions/get-products/mock.js +7 -3
  24. package/dist/actions/get-products/types.d.ts +1 -1
  25. package/dist/actions/get-refund-plan/mock.d.ts +0 -4
  26. package/dist/actions/get-refund-plan/mock.js +0 -8
  27. package/dist/actions/get-refund-plan/types.d.ts +0 -89
  28. package/dist/actions/set-product-modifier-selections/mock.js +12 -0
  29. package/dist/demo/database.d.ts +39 -1
  30. package/dist/demo/database.js +214 -1
  31. package/dist/index.d.ts +5 -1
  32. package/dist/index.js +4 -0
  33. package/dist/projects/render/mocks.js +4 -0
  34. package/dist/projects/render/types.d.ts +3 -1
  35. package/dist/pubsub/topics/products/catalog-visibility-changed/types.d.ts +17 -0
  36. package/dist/pubsub/topics/products/catalog-visibility-changed/types.js +1 -0
  37. package/dist/pubsub/topics/products/composite-changed/types.d.ts +17 -0
  38. package/dist/pubsub/topics/products/composite-changed/types.js +1 -0
  39. package/dist/pubsub/topics/products/index.d.ts +2 -2
  40. package/dist/pubsub/topics/products/index.js +33 -18
  41. package/dist/pubsub/topics/products/inventory-changed/types.d.ts +18 -0
  42. package/dist/pubsub/topics/products/inventory-changed/types.js +1 -0
  43. package/dist/pubsub/topics/products/types.d.ts +16 -10
  44. package/dist/pubsub/topics/products/types.js +7 -4
  45. package/package.json +2 -2
  46. package/dist/actions/get-refund-plan/mockRows.d.ts +0 -6
  47. 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,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>;
@@ -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 "../../types";
5
+ import type { TopicDefinition } from '../../types';
6
6
  export declare const productsTopic: TopicDefinition;
7
- export * from "./types";
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: "products",
7
- name: "Products",
8
- description: "Topic for product-related events",
6
+ id: 'products',
7
+ name: 'Products',
8
+ description: 'Topic for product-related events',
9
9
  eventTypes: [
10
10
  {
11
- id: "product-created",
12
- name: "Product Created",
13
- description: "Published when a new product is synced/created"
11
+ id: 'product-created',
12
+ name: 'Product Created',
13
+ description: 'Published when a new product is synced/created',
14
14
  },
15
15
  {
16
- id: "product-updated",
17
- name: "Product Updated",
18
- description: "Published when a product is synced/updated"
16
+ id: 'product-updated',
17
+ name: 'Product Updated',
18
+ description: 'Published when a product is synced/updated',
19
19
  },
20
20
  {
21
- id: "set-active-product",
22
- name: "Set Active Product",
23
- description: "Published when a product is set as the active product"
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: "get-active-product",
27
- name: "Get Active Product",
28
- description: "Published when a product is retrieved as the active product"
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 "./types";
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>;
@@ -2,13 +2,19 @@
2
2
  * Products Topic Types
3
3
  * Aggregated types for all product-related events
4
4
  */
5
- export * from "./product-created/types";
6
- export * from "./product-updated/types";
7
- export * from "./product-set-active/types";
8
- export * from "./product-get-active/types";
9
- import type { ProductCreatedPayload } from "./product-created/types";
10
- import type { ProductUpdatedPayload } from "./product-updated/types";
11
- import type { ProductSetActivePayload } from "./product-set-active/types";
12
- import type { ProductGetActivePayload } from "./product-get-active/types";
13
- export type ProductsEventPayload = ProductCreatedPayload | ProductUpdatedPayload | ProductSetActivePayload | ProductGetActivePayload;
14
- export type ProductsEventType = "product-created" | "product-updated" | "set-active-product" | "get-active-product";
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 "./product-created/types";
7
- export * from "./product-updated/types";
8
- export * from "./product-set-active/types";
9
- export * from "./product-get-active/types";
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.8.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.4.0"
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
- }