@final-commerce/command-frame 0.7.0-staging.9 → 0.7.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 (87) hide show
  1. package/dist/CommonTypes.d.ts +14 -26
  2. package/dist/actions/add-product-to-cart/mock.js +18 -1
  3. package/dist/actions/add-product-to-cart/types.d.ts +10 -0
  4. package/dist/actions/get-context/mock.js +0 -4
  5. package/dist/actions/get-product-modifier-selections/action.d.ts +6 -0
  6. package/dist/actions/get-product-modifier-selections/action.js +8 -0
  7. package/dist/actions/get-product-modifier-selections/mock.d.ts +2 -0
  8. package/dist/actions/get-product-modifier-selections/mock.js +30 -0
  9. package/dist/actions/get-product-modifier-selections/types.d.ts +23 -0
  10. package/dist/actions/get-refund-plan/mock.d.ts +4 -0
  11. package/dist/actions/get-refund-plan/mock.js +8 -0
  12. package/dist/actions/get-refund-plan/mockRows.d.ts +6 -0
  13. package/dist/actions/get-refund-plan/mockRows.js +114 -0
  14. package/dist/actions/get-refund-plan/types.d.ts +91 -5
  15. package/dist/actions/get-remaining-refundable-quantities/mock.js +0 -1
  16. package/dist/actions/get-remaining-refundable-quantities/types.d.ts +0 -8
  17. package/dist/actions/process-partial-refund/types.d.ts +2 -2
  18. package/dist/actions/set-product-modifier-selections/action.d.ts +6 -0
  19. package/dist/actions/set-product-modifier-selections/action.js +8 -0
  20. package/dist/actions/set-product-modifier-selections/mock.d.ts +2 -0
  21. package/dist/actions/set-product-modifier-selections/mock.js +49 -0
  22. package/dist/actions/set-product-modifier-selections/types.d.ts +27 -0
  23. package/dist/demo/database.d.ts +24 -12
  24. package/dist/demo/database.js +61 -121
  25. package/dist/index.d.ts +5 -17
  26. package/dist/index.js +4 -15
  27. package/dist/projects/render/mocks.js +4 -14
  28. package/dist/projects/render/types.d.ts +3 -8
  29. package/dist/pubsub/topics/cart/product-modifiers-updated/types.d.ts +16 -0
  30. package/dist/pubsub/topics/cart/types.d.ts +4 -2
  31. package/dist/pubsub/topics/cart/types.js +1 -0
  32. package/dist/pubsub/topics/index.d.ts +16 -17
  33. package/dist/pubsub/topics/index.js +16 -17
  34. package/dist/pubsub/topics/types.d.ts +0 -2
  35. package/package.json +5 -2
  36. package/dist/actions/add-booking-to-cart/action.d.ts +0 -6
  37. package/dist/actions/add-booking-to-cart/action.js +0 -8
  38. package/dist/actions/add-booking-to-cart/mock.d.ts +0 -2
  39. package/dist/actions/add-booking-to-cart/mock.js +0 -42
  40. package/dist/actions/add-booking-to-cart/types.d.ts +0 -23
  41. package/dist/actions/cancel-booking/action.d.ts +0 -6
  42. package/dist/actions/cancel-booking/action.js +0 -8
  43. package/dist/actions/cancel-booking/mock.d.ts +0 -2
  44. package/dist/actions/cancel-booking/mock.js +0 -10
  45. package/dist/actions/cancel-booking/types.d.ts +0 -10
  46. package/dist/actions/get-booking-availability/action.d.ts +0 -6
  47. package/dist/actions/get-booking-availability/action.js +0 -8
  48. package/dist/actions/get-booking-availability/mock.d.ts +0 -2
  49. package/dist/actions/get-booking-availability/mock.js +0 -6
  50. package/dist/actions/get-booking-availability/types.d.ts +0 -18
  51. package/dist/actions/get-booking-resources/action.d.ts +0 -6
  52. package/dist/actions/get-booking-resources/action.js +0 -8
  53. package/dist/actions/get-booking-resources/mock.d.ts +0 -2
  54. package/dist/actions/get-booking-resources/mock.js +0 -7
  55. package/dist/actions/get-booking-resources/types.d.ts +0 -12
  56. package/dist/actions/get-booking-resources/types.js +0 -1
  57. package/dist/actions/get-bookings/action.d.ts +0 -6
  58. package/dist/actions/get-bookings/action.js +0 -8
  59. package/dist/actions/get-bookings/mock.d.ts +0 -2
  60. package/dist/actions/get-bookings/mock.js +0 -20
  61. package/dist/actions/get-bookings/types.d.ts +0 -18
  62. package/dist/actions/get-bookings/types.js +0 -1
  63. package/dist/actions/hold-booking/action.d.ts +0 -6
  64. package/dist/actions/hold-booking/action.js +0 -8
  65. package/dist/actions/hold-booking/mock.d.ts +0 -2
  66. package/dist/actions/hold-booking/mock.js +0 -33
  67. package/dist/actions/hold-booking/types.d.ts +0 -24
  68. package/dist/actions/hold-booking/types.js +0 -1
  69. package/dist/actions/remove-booking-from-cart/action.d.ts +0 -6
  70. package/dist/actions/remove-booking-from-cart/action.js +0 -8
  71. package/dist/actions/remove-booking-from-cart/mock.d.ts +0 -2
  72. package/dist/actions/remove-booking-from-cart/mock.js +0 -26
  73. package/dist/actions/remove-booking-from-cart/types.d.ts +0 -12
  74. package/dist/actions/remove-booking-from-cart/types.js +0 -1
  75. package/dist/pubsub/topics/bookings/booking-created/types.d.ts +0 -6
  76. package/dist/pubsub/topics/bookings/booking-created/types.js +0 -1
  77. package/dist/pubsub/topics/bookings/booking-setup-changed/types.d.ts +0 -15
  78. package/dist/pubsub/topics/bookings/booking-setup-changed/types.js +0 -1
  79. package/dist/pubsub/topics/bookings/booking-updated/types.d.ts +0 -6
  80. package/dist/pubsub/topics/bookings/booking-updated/types.js +0 -1
  81. package/dist/pubsub/topics/bookings/index.d.ts +0 -3
  82. package/dist/pubsub/topics/bookings/index.js +0 -27
  83. package/dist/pubsub/topics/bookings/types.d.ts +0 -8
  84. package/dist/pubsub/topics/bookings/types.js +0 -3
  85. /package/dist/actions/{add-booking-to-cart → get-product-modifier-selections}/types.js +0 -0
  86. /package/dist/actions/{cancel-booking → set-product-modifier-selections}/types.js +0 -0
  87. /package/dist/{actions/get-booking-availability → pubsub/topics/cart/product-modifiers-updated}/types.js +0 -0
@@ -0,0 +1,27 @@
1
+ import type { ModifierSelection } from "../get-product-modifier-selections/types";
2
+ import type { CFProdModifierBreakdown } from "../../CommonTypes";
3
+ export interface SetProductModifierSelectionsParams {
4
+ /** The cart line to edit. Defaults to the active product's line. */
5
+ internalId?: string;
6
+ /**
7
+ * The line's COMPLETE new answers — replaces every existing selection on the
8
+ * line (send [] to clear all optional modifiers). Validated against the
9
+ * product's category-modifier rules exactly like addProductToCart({ modifiers }):
10
+ * a selection that breaks a rule rejects the edit and the line is unchanged.
11
+ */
12
+ selections: ModifierSelection[];
13
+ }
14
+ export interface SetProductModifierSelectionsResponse {
15
+ success: boolean;
16
+ /** Set when the edit was rejected (rule violation) — the line is unchanged. */
17
+ reason?: string;
18
+ internalId?: string;
19
+ /** The selections now on the line (the new ones on success, the old ones on rejection). */
20
+ selections: ModifierSelection[];
21
+ /** Display-ready — repaint from this instead of re-reading after an edit. */
22
+ rows: CFProdModifierBreakdown[];
23
+ /** Sum of `rows[].amount` for THIS line, in minor units. */
24
+ modifiersTotal: number;
25
+ timestamp: string;
26
+ }
27
+ export type SetProductModifierSelections = (params?: SetProductModifierSelectionsParams) => Promise<SetProductModifierSelectionsResponse>;
@@ -2,7 +2,7 @@
2
2
  * Mock Database for Standalone/Demo Mode
3
3
  * Stores mock data that mimics the Render environment
4
4
  */
5
- import { CFActiveCompany, CFActiveUser, CFActiveStation, CFActiveOutlet, CFActiveOrder, CFCustomer, CFProduct, CFActiveCart, CFCategory, CFActiveProduct, CFSession, CFActiveRefundDetails, CFSmartGridLayout, CFBooking, CFBookingAvailability, CFBookingResource } from '../CommonTypes';
5
+ import { CFActiveCompany, CFActiveUser, CFActiveStation, CFActiveOutlet, CFActiveOrder, CFCustomer, CFProduct, CFActiveCart, CFCategory, CFActiveProduct, CFSession, CFActiveRefundDetails, CFSmartGridLayout, CFCartLineModifier, CFProdModifierBreakdown, CFModifierSelection, CFResolvedModifier } from '../CommonTypes';
6
6
  export * from './mocks';
7
7
  /** Replace mock catalog / context data in place (same array references mock handlers use). */
8
8
  export interface MockDatabaseConfig {
@@ -15,10 +15,6 @@ export interface MockDatabaseConfig {
15
15
  products?: CFProduct[];
16
16
  orders?: CFActiveOrder[];
17
17
  parkedOrders?: CFActiveOrder[];
18
- /** Who is scarce: the staff, rooms or machines the dataset's services are booked against. */
19
- bookingResources?: CFBookingResource[];
20
- /** Windows already taken when the dataset loads, so a calendar does not open empty. */
21
- bookings?: CFBooking[];
22
18
  }
23
19
  export declare const MOCK_COMPANY: CFActiveCompany;
24
20
  export declare const MOCK_OUTLET_MAIN: CFActiveOutlet;
@@ -63,7 +59,6 @@ export declare const MOCK_STATIONS: import("@final-commerce/common/pos-types").A
63
59
  export declare const MOCK_OUTLETS: import("@final-commerce/common/pos-types").ActiveOutlet[];
64
60
  export declare const MOCK_CUSTOMERS: import("@final-commerce/common/pos-types").ActiveCustomer[];
65
61
  export declare const MOCK_CATEGORIES: import("@final-commerce/common/pos-types").Category[];
66
- export declare const MOCK_PRODUCT_HAIRCUT: CFProduct;
67
62
  export declare const MOCK_PRODUCTS: import("@final-commerce/common/pos-types").FullProduct[];
68
63
  export declare const MOCK_ORDERS: import("@final-commerce/common/pos-types").ActiveOrder[];
69
64
  export declare const MOCK_PARKED_ORDERS: CFActiveOrder[];
@@ -92,9 +87,26 @@ export declare const createOrderFromCart: (paymentType: string, amount: number,
92
87
  * open with `amountToBeCharged` reset to what's left, and returns null.
93
88
  */
94
89
  export declare const applyMockPayment: (amount: number, paymentType: string, processor?: string) => CFActiveOrder | null;
95
- export declare const MOCK_BOOKING_RULES_ID = "rule_salon_30";
96
- export declare const MOCK_BOOKING_RESOURCES: CFBookingResource[];
97
- export declare const MOCK_BOOKINGS: CFBooking[];
98
- /** Live = confirmed, or held and not yet expired. An expired hold occupies nothing. */
99
- export declare const mockLiveBookings: () => CFBooking[];
100
- export declare const mockBookingAvailability: (productId: string, from: Date, to: Date, resourceId?: string) => CFBookingAvailability;
90
+ /**
91
+ * Price the cashier's raw modifier answers into the rows a CART line carries (FT-0010).
92
+ *
93
+ * Here rather than in an action folder because two mocks need it — addProductToCart and
94
+ * setProductModifierSelections — and this module is already where the shared mock helpers
95
+ * live (`safeSerialize`, `resetMockCart`, `mockPublishEvent`).
96
+ *
97
+ * Note the two shapes that share the name `modifiers` and are NOT interchangeable:
98
+ * `FullProduct.modifiers` is `ResolvedModifier[]` (the menu — question + every choice),
99
+ * `ActiveProduct.modifiers` is `CartLineModifier[]` (one row per CHOSEN choice). The mock
100
+ * builds a cart line by spreading the product, so the menu must be stripped off the line
101
+ * before anything reads it, or every surface renders the catalogue as if it were picked.
102
+ *
103
+ * Names and unitPrice are snapshotted, as the real host does — a later rename never
104
+ * rewrites an open cart. No `total`: a cart row is per line UNIT, and the host extends it.
105
+ * Rule validation (required/min/max) is deliberately not mocked; the real host owns it.
106
+ */
107
+ /** Extend a line's priced modifier rows by the line quantity. Mirrors kaching's `buildProdModifiers`. */
108
+ export declare const buildModifierRows: (modifiers: CFCartLineModifier[] | undefined, lineQuantity: number | undefined) => {
109
+ rows: CFProdModifierBreakdown[];
110
+ modifiersTotal: number;
111
+ };
112
+ export declare const buildCartLineModifiers: (menu: CFResolvedModifier[] | undefined, selections: CFModifierSelection[] | undefined, productTaxTableId?: string) => CFCartLineModifier[];
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { CFProductType, CFUserTypes, CurrencyCode, } from '../CommonTypes';
6
6
  import { extendPrice, resolveUnit, toBase } from '@final-commerce/common';
7
- import { BookingRatePeriod, BookingResourceKind, BookingType, ReservationStatus } from '@final-commerce/common';
8
7
  export * from './mocks';
9
8
  // Asset Imports - Using Remote URLs to avoid build complexity with asset copying
10
9
  const ASSETS_BASE_URL = 'https://raw.githubusercontent.com/Final-Commerce/command-frame/refs/heads/main/src/demo/assets';
@@ -650,14 +649,6 @@ export const MOCK_CATEGORIES = [
650
649
  MOCK_CATEGORY_VEGAN,
651
650
  MOCK_CATEGORY_SPICY,
652
651
  ];
653
- // A service, not a thing on a shelf: no stock, sold as a slot of somebody's time.
654
- // `bookingRulesId` is what tells a catalogue screen to ask for slots instead of stock.
655
- export const MOCK_PRODUCT_HAIRCUT = {
656
- ...createSimpleProduct('prod_haircut', 'Haircut', 4500, '', [MOCK_CATEGORY_SPECIALTY], 'Cut and finish, 30 minutes.'),
657
- images: [],
658
- productType: CFProductType.BOOKING,
659
- bookingRulesId: 'rule_salon_30',
660
- };
661
652
  export const MOCK_PRODUCTS = [
662
653
  MOCK_PRODUCT_BASIL_ALMOND,
663
654
  MOCK_PRODUCT_BEER,
@@ -673,7 +664,6 @@ export const MOCK_PRODUCTS = [
673
664
  MOCK_PRODUCT_CHILI_GARLIC,
674
665
  MOCK_PRODUCT_HABANERO,
675
666
  MOCK_PRODUCT_BLACK_GARLIC,
676
- MOCK_PRODUCT_HAIRCUT,
677
667
  ];
678
668
  export const MOCK_ORDERS = [MOCK_ORDER_1, MOCK_ORDER_2, MOCK_ORDER_3, MOCK_ORDER_4];
679
669
  export const MOCK_PARKED_ORDERS = [MOCK_PARKED_ORDER_1, MOCK_PARKED_ORDER_2];
@@ -688,7 +678,6 @@ export let MOCK_CART = {
688
678
  remainingBalance: 0,
689
679
  products: [],
690
680
  customSales: [],
691
- reservations: [],
692
681
  nonRevenueItems: [],
693
682
  customer: null,
694
683
  };
@@ -709,7 +698,6 @@ export const resetMockCart = () => {
709
698
  remainingBalance: 0,
710
699
  products: [],
711
700
  customSales: [],
712
- reservations: [],
713
701
  nonRevenueItems: [],
714
702
  customer: null,
715
703
  };
@@ -754,12 +742,6 @@ export function setMockDatabase(config) {
754
742
  if (config.parkedOrders !== undefined) {
755
743
  MOCK_PARKED_ORDERS.splice(0, MOCK_PARKED_ORDERS.length, ...config.parkedOrders);
756
744
  }
757
- if (config.bookingResources !== undefined) {
758
- MOCK_BOOKING_RESOURCES.splice(0, MOCK_BOOKING_RESOURCES.length, ...config.bookingResources);
759
- }
760
- if (config.bookings !== undefined) {
761
- MOCK_BOOKINGS.splice(0, MOCK_BOOKINGS.length, ...config.bookings);
762
- }
763
745
  if (MOCK_OUTLETS.length > 0) {
764
746
  Object.assign(MOCK_OUTLET_MAIN, MOCK_OUTLETS[0]);
765
747
  if (MOCK_OUTLET_MAIN.id === undefined && MOCK_OUTLET_MAIN._id !== undefined) {
@@ -896,30 +878,6 @@ export const createOrderFromCart = (paymentType, amount, processor = 'cash') =>
896
878
  billing: MOCK_CART.customer?.billing || null,
897
879
  shipping: MOCK_CART.customer?.shipping || null,
898
880
  lineItems,
899
- // A paid booking is a sale: it belongs on the order (and thus the receipt),
900
- // in its own array rather than among the line items, and CONFIRMED — payment
901
- // is what turns a held window into a kept appointment.
902
- reservations: (MOCK_CART.reservations ?? []).map((reservation) => ({
903
- internalId: reservation.internalId,
904
- bookingId: reservation.bookingId,
905
- productId: reservation.productId,
906
- variantId: reservation.variantId,
907
- resourceId: reservation.resourceId,
908
- name: reservation.name,
909
- resourceName: reservation.resourceName,
910
- price: reservation.price,
911
- quantity: reservation.quantity,
912
- total: reservation.total,
913
- taxTableId: reservation.taxTableId,
914
- startAt: reservation.startAt,
915
- endAt: reservation.endAt,
916
- bufferEndAt: reservation.bufferEndAt,
917
- // The mock computes no tax anywhere — line items ship `taxes: []` too.
918
- taxes: [],
919
- // Neither `expiresAt` nor a status comes along: a booking's state lives on its own
920
- // row — which is what `getBookings` reads — and a copy frozen on the order would be
921
- // wrong from the next moment on.
922
- })),
923
881
  customSales: [],
924
882
  balance: 0,
925
883
  user: employeeUser,
@@ -956,88 +914,70 @@ export const applyMockPayment = (amount, paymentType, processor = 'cash') => {
956
914
  mockPublishEvent('payments', 'payment-done', { order });
957
915
  return order;
958
916
  };
959
- // ── Booking (FT-0064) ────────────────────────────────────────────────────────────
960
- // A salon: one service, two people who can perform it, a 30-minute slot with a
961
- // 5-minute turnaround, open 9–18. Enough to click through a booking screen with no
962
- // server. Availability here is COMPUTED, exactly as the host computes it — a mock
963
- // that returned a fixed list of slots would hide the one behaviour that matters:
964
- // a slot disappears once somebody takes it.
965
- export const MOCK_BOOKING_RULES_ID = 'rule_salon_30';
966
- const SLOT_MINUTES = 30;
967
- const BUFFER_MINUTES = 5;
968
- const OPEN_HOUR = 9;
969
- const CLOSE_HOUR = 18;
970
- // Rooms, not people: a resource is whatever is scarce, and a room is the case that
971
- // reads the same in every vertical a dataset might describe.
972
- export const MOCK_BOOKING_RESOURCES = [
973
- { id: 'res_room_1', name: 'Room 1', kind: BookingResourceKind.ROOM },
974
- { id: 'res_room_2', name: 'Room 2', kind: BookingResourceKind.ROOM },
975
- ];
976
- const at = (dayOffset, hour, minute = 0) => {
977
- const date = new Date();
978
- date.setDate(date.getDate() + dayOffset);
979
- date.setHours(hour, minute, 0, 0);
980
- return date;
981
- };
982
- const booking = (id, resourceId, start, status, customerName) => ({
983
- id,
984
- productId: MOCK_PRODUCT_HAIRCUT._id,
985
- resourceId,
986
- startAt: start.toISOString(),
987
- endAt: new Date(start.getTime() + SLOT_MINUTES * 60000).toISOString(),
988
- bufferEndAt: new Date(start.getTime() + (SLOT_MINUTES + BUFFER_MINUTES) * 60000).toISOString(),
989
- status,
990
- productName: MOCK_PRODUCT_HAIRCUT.name,
991
- resourceName: MOCK_BOOKING_RESOURCES.find((resource) => resource.id === resourceId)?.name,
992
- customerName,
993
- });
994
- export const MOCK_BOOKINGS = [
995
- booking('bk_1', 'res_room_1', at(0, 10), ReservationStatus.CONFIRMED, 'Alex Green'),
996
- booking('bk_2', 'res_room_2', at(0, 11, 30), ReservationStatus.CONFIRMED, 'Dana White'),
997
- booking('bk_3', 'res_room_1', at(1, 9, 30), ReservationStatus.CONFIRMED, 'Sam Blue'),
998
- ];
999
- /** Live = confirmed, or held and not yet expired. An expired hold occupies nothing. */
1000
- export const mockLiveBookings = () => MOCK_BOOKINGS.filter(({ status, expiresAt }) => status === ReservationStatus.CONFIRMED ||
1001
- (status === ReservationStatus.HELD && (!expiresAt || new Date(expiresAt) > new Date())));
1002
- const takenBy = (resourceId, startAt, bufferEndAt) => mockLiveBookings().some((entry) => entry.resourceId === resourceId && new Date(entry.startAt) < bufferEndAt && new Date(entry.bufferEndAt) > startAt);
1003
- export const mockBookingAvailability = (productId, from, to, resourceId) => {
1004
- const serving = resourceId
1005
- ? MOCK_BOOKING_RESOURCES.filter((resource) => resource.id === resourceId)
1006
- : MOCK_BOOKING_RESOURCES;
1007
- const slots = [];
1008
- const step = (SLOT_MINUTES + BUFFER_MINUTES) * 60000;
1009
- for (let day = 0; day < 14; day += 1) {
1010
- const open = at(day, OPEN_HOUR);
1011
- if (open < from || open > to)
917
+ /**
918
+ * Price the cashier's raw modifier answers into the rows a CART line carries (FT-0010).
919
+ *
920
+ * Here rather than in an action folder because two mocks need it — addProductToCart and
921
+ * setProductModifierSelections — and this module is already where the shared mock helpers
922
+ * live (`safeSerialize`, `resetMockCart`, `mockPublishEvent`).
923
+ *
924
+ * Note the two shapes that share the name `modifiers` and are NOT interchangeable:
925
+ * `FullProduct.modifiers` is `ResolvedModifier[]` (the menu — question + every choice),
926
+ * `ActiveProduct.modifiers` is `CartLineModifier[]` (one row per CHOSEN choice). The mock
927
+ * builds a cart line by spreading the product, so the menu must be stripped off the line
928
+ * before anything reads it, or every surface renders the catalogue as if it were picked.
929
+ *
930
+ * Names and unitPrice are snapshotted, as the real host does — a later rename never
931
+ * rewrites an open cart. No `total`: a cart row is per line UNIT, and the host extends it.
932
+ * Rule validation (required/min/max) is deliberately not mocked; the real host owns it.
933
+ */
934
+ /** Extend a line's priced modifier rows by the line quantity. Mirrors kaching's `buildProdModifiers`. */
935
+ export const buildModifierRows = (modifiers, lineQuantity) => {
936
+ const quantity = lineQuantity ?? 1;
937
+ const rows = (modifiers ?? []).map((modifier) => ({
938
+ modifierId: modifier.modifierId,
939
+ modifierName: modifier.modifierName,
940
+ choiceId: modifier.choiceId,
941
+ choiceName: modifier.choiceName,
942
+ label: modifier.label ?? `${modifier.modifierName} - ${modifier.choiceName}`,
943
+ unitPrice: modifier.unitPrice,
944
+ quantity: modifier.quantity,
945
+ // extendPrice, not a raw multiply: a fractional line quantity (1.5 kg) must not
946
+ // leave fractional minor units on the row.
947
+ amount: extendPrice(modifier.unitPrice * modifier.quantity, quantity),
948
+ tax: 0,
949
+ ...(modifier.taxTableId ? { taxTableId: modifier.taxTableId } : {}),
950
+ }));
951
+ return { rows, modifiersTotal: rows.reduce((sum, row) => sum + row.amount, 0) };
952
+ };
953
+ export const buildCartLineModifiers = (menu, selections, productTaxTableId) => {
954
+ if (!menu?.length || !selections?.length)
955
+ return [];
956
+ const byModifier = new Map(menu.map((modifier) => [modifier._id, modifier]));
957
+ const rows = [];
958
+ for (const selection of selections) {
959
+ const modifier = byModifier.get(selection.modifierId);
960
+ if (!modifier)
1012
961
  continue;
1013
- const close = at(day, CLOSE_HOUR);
1014
- for (let start = open.getTime(); start + SLOT_MINUTES * 60000 <= close.getTime(); start += step) {
1015
- const startAt = new Date(start);
1016
- const endAt = new Date(start + SLOT_MINUTES * 60000);
1017
- const bufferEndAt = new Date(start + (SLOT_MINUTES + BUFFER_MINUTES) * 60000);
1018
- if (bufferEndAt < new Date())
962
+ const byChoice = new Map(modifier.choices.map((choice) => [choice._id, choice]));
963
+ for (const picked of selection.choices ?? []) {
964
+ const choice = byChoice.get(picked.choiceId);
965
+ // `quantity` is units per ONE line unit; 0 means "not chosen" and carries no row.
966
+ if (!choice || !(picked.quantity > 0))
1019
967
  continue;
1020
- const resources = serving.map((resource) => {
1021
- const free = takenBy(resource.id, startAt, bufferEndAt) ? 0 : 1;
1022
- return { resourceId: resource.id, name: resource.name, capacity: 1, booked: 1 - free, free };
1023
- });
1024
- slots.push({
1025
- startAt: startAt.toISOString(),
1026
- endAt: endAt.toISOString(),
1027
- bufferEndAt: bufferEndAt.toISOString(),
1028
- canStart: true,
1029
- capacity: resources.length,
1030
- booked: resources.reduce((sum, entry) => sum + entry.booked, 0),
1031
- free: resources.reduce((sum, entry) => sum + entry.free, 0),
1032
- resources,
968
+ rows.push({
969
+ modifierId: modifier._id,
970
+ modifierName: modifier.name,
971
+ choiceId: choice._id,
972
+ choiceName: choice.name,
973
+ // The cart's display label, like CustomFee.label — "Toppings - Avocado".
974
+ label: `${modifier.name} - ${choice.name}`,
975
+ unitPrice: choice.price,
976
+ quantity: picked.quantity,
977
+ // Modifier tax follows the parent product's table, as a fee's does.
978
+ ...(productTaxTableId ? { taxTableId: productTaxTableId } : {}),
1033
979
  });
1034
980
  }
1035
981
  }
1036
- return {
1037
- productId,
1038
- bookingRulesId: MOCK_BOOKING_RULES_ID,
1039
- bookingType: BookingType.APPOINTMENT,
1040
- ratePeriod: BookingRatePeriod.SLOT,
1041
- slots,
1042
- };
982
+ return rows;
1043
983
  };
package/dist/index.d.ts CHANGED
@@ -2,13 +2,6 @@ export declare const command: {
2
2
  readonly exampleFunction: import(".").ExampleFunction;
3
3
  readonly generateAPIKey: import(".").GenerateAPIKey;
4
4
  readonly getProducts: import(".").GetProducts;
5
- readonly getBookingResources: import(".").GetBookingResources;
6
- readonly getBookingAvailability: import(".").GetBookingAvailability;
7
- readonly getBookings: import(".").GetBookings;
8
- readonly holdBooking: import(".").HoldBooking;
9
- readonly addBookingToCart: import(".").AddBookingToCart;
10
- readonly removeBookingFromCart: import(".").RemoveBookingFromCart;
11
- readonly cancelBooking: import(".").CancelBooking;
12
5
  readonly addCustomSale: import(".").AddCustomSale;
13
6
  readonly editCustomSale: import(".").EditCustomSale;
14
7
  readonly addNonRevenueItem: import(".").AddNonRevenueItem;
@@ -28,6 +21,8 @@ export declare const command: {
28
21
  readonly getFinalContext: import(".").GetFinalContext;
29
22
  readonly addProductNote: import(".").AddProductNote;
30
23
  readonly addProductFee: import(".").AddProductFee;
24
+ readonly getProductModifierSelections: import(".").GetProductModifierSelections;
25
+ readonly setProductModifierSelections: import(".").SetProductModifierSelections;
31
26
  readonly setActiveProductFee: import(".").SetActiveProductFee;
32
27
  readonly setActiveProductDiscount: import(".").SetActiveProductDiscount;
33
28
  readonly getActiveProduct: import(".").GetActiveProduct;
@@ -126,13 +121,6 @@ export declare const command: {
126
121
  export type { ExampleFunction, ExampleFunctionParams, ExampleFunctionResponse } from './actions/example-function/types';
127
122
  export type { GenerateAPIKey, GenerateAPIKeyParams, GenerateAPIKeyResponse } from './actions/generate-api-key/types';
128
123
  export type { GetProducts, GetProductsParams, GetProductsResponse } from './actions/get-products/types';
129
- export type { GetBookingResources, GetBookingResourcesParams, GetBookingResourcesResponse, } from './actions/get-booking-resources/types';
130
- export type { GetBookingAvailability, GetBookingAvailabilityParams, GetBookingAvailabilityResponse, } from './actions/get-booking-availability/types';
131
- export type { GetBookings, GetBookingsParams, GetBookingsResponse } from './actions/get-bookings/types';
132
- export type { HoldBooking, HoldBookingParams, HoldBookingResponse } from './actions/hold-booking/types';
133
- export type { AddBookingToCart, AddBookingToCartParams, AddBookingToCartResponse, } from './actions/add-booking-to-cart/types';
134
- export type { RemoveBookingFromCart, RemoveBookingFromCartParams, RemoveBookingFromCartResponse, } from './actions/remove-booking-from-cart/types';
135
- export type { CancelBooking, CancelBookingParams, CancelBookingResponse } from './actions/cancel-booking/types';
136
124
  export type { AddCustomSale, AddCustomSaleParams, AddCustomSaleResponse } from './actions/add-custom-sale/types';
137
125
  export type { EditCustomSale, EditCustomSaleParams, EditCustomSaleResponse } from './actions/edit-custom-sale/types';
138
126
  export type { AddNonRevenueItem, AddNonRevenueItemParams, AddNonRevenueItemResponse, } from './actions/add-non-revenue-item/types';
@@ -158,7 +146,7 @@ export type { CalculateRefundTotal, CalculateRefundTotalParams, CalculateRefundT
158
146
  export type { GetRemainingRefundableQuantities, GetRemainingRefundableQuantitiesParams, GetRemainingRefundableQuantitiesResponse, } from './actions/get-remaining-refundable-quantities/types';
159
147
  export type { ProcessPartialRefund, ProcessPartialRefundParams, ProcessPartialRefundResponse, } from './actions/process-partial-refund/types';
160
148
  export type { RedeemRefund, RedeemRefundParams, RedeemRefundResponse } from './actions/redeem-refund/types';
161
- export type { GetRefundPlan, GetRefundPlanParams, GetRefundPlanResponse, RefundPlanSource, RefundPlanAllocation, RefundPlanLeg, } from './actions/get-refund-plan/types';
149
+ export type { GetRefundPlan, GetRefundPlanParams, GetRefundPlanResponse, RefundPlanSource, RefundPlanAllocation, RefundPlanLeg, RefundPlanRowType, RefundPlanTaxLine, RefundPlanAmounts, RefundPlanRow, RefundPlanSelectedRow, RefundPlanTotals, RefundPlanBreakdown, } from './actions/get-refund-plan/types';
162
150
  export type { CheckPermission, CheckPermissionParams, CheckPermissionResponse } from './actions/check-permission/types';
163
151
  export type { InitiateRefund, InitiateRefundParams, InitiateRefundResponse } from './actions/initiate-refund/types';
164
152
  export type { GetCurrentCart, GetCurrentCartResponse } from './actions/get-current-cart/types';
@@ -171,6 +159,8 @@ export type { GetContext, GetContextResponse, GetContextResponseManage, GetConte
171
159
  export type { GetFinalContext, GetFinalContextResponse } from './actions/get-final-context/types';
172
160
  export type { AddProductNote, AddProductNoteParams, AddProductNoteResponse } from './actions/add-product-note/types';
173
161
  export type { AddProductFee, AddProductFeeParams, AddProductFeeResponse } from './actions/add-product-fee/types';
162
+ export type { GetProductModifierSelections, GetProductModifierSelectionsParams, GetProductModifierSelectionsResponse, ModifierSelection, ModifierChoiceSelection, } from './actions/get-product-modifier-selections/types';
163
+ export type { SetProductModifierSelections, SetProductModifierSelectionsParams, SetProductModifierSelectionsResponse, } from './actions/set-product-modifier-selections/types';
174
164
  export type { SetActiveProductFee, SetActiveProductFeeParams, SetActiveProductFeeResponse, } from './actions/set-active-product-fee/types';
175
165
  export type { SetActiveProductDiscount, SetActiveProductDiscountParams, SetActiveProductDiscountResponse, } from './actions/set-active-product-discount/types';
176
166
  export type { GetActiveProduct, GetActiveProductResponse } from './actions/get-active-product/types';
@@ -259,7 +249,6 @@ export { variantsTopic } from './pubsub/topics/variants';
259
249
  export { transactionsTopic } from './pubsub/topics/transactions';
260
250
  export { categoriesTopic } from './pubsub/topics/categories';
261
251
  export { attributesTopic } from './pubsub/topics/attributes';
262
- export { bookingsTopic } from './pubsub/topics/bookings';
263
252
  export type { CustomerCreatedPayload, CustomerUpdatedPayload, CustomerNoteAddedPayload, CustomerNoteDeletedPayload, CustomerAssignedPayload, CustomerUnassignedPayload, CustomerActiveSetPayload, CustomerActiveGetPayload, CustomerCreatedEvent, CustomerUpdatedEvent, CustomerNoteAddedEvent, CustomerNoteDeletedEvent, CustomerAssignedEvent, CustomerUnassignedEvent, CustomerActiveSetEvent, CustomerActiveGetEvent, CustomersEventType, CustomersEventPayload, } from './pubsub/topics/customers/types';
264
253
  export type { OrderCreatedPayload, OrderUpdatedPayload, OrderVoidedPayload, OrderActiveSetPayload, OrderActiveGetPayload, OrderCreatedEvent, OrderUpdatedEvent, OrderVoidedEvent, OrderActiveSetEvent, OrderActiveGetEvent, OrderStateTransitionCompletedPayload, OrderStateTransitionBlockedPayload, OrderStateTransitionCompletedEvent, OrderStateTransitionBlockedEvent, OrdersEventType, OrdersEventPayload, } from './pubsub/topics/orders/types';
265
254
  export type { RefundCreatedPayload, RefundUpdatedPayload, RefundActiveSetPayload, RefundActiveGetPayload, RefundCreatedEvent, RefundUpdatedEvent, RefundActiveSetEvent, RefundActiveGetEvent, RefundsEventType, RefundsEventPayload, } from './pubsub/topics/refunds/types';
@@ -270,7 +259,6 @@ export type { SessionActiveSetPayload, SessionActiveGetPayload, SessionActiveSet
270
259
  export type { UserActiveSetPayload, UserActiveGetPayload, UserActiveSetEvent, UserActiveGetEvent, UserCreatedPayload, UserCreatedEvent, UserUpdatedPayload, UserUpdatedEvent, UsersEventType, UsersEventPayload, } from './pubsub/topics/users/types';
271
260
  export type { VariantCreatedPayload, VariantCreatedEvent, VariantUpdatedPayload, VariantUpdatedEvent, VariantsEventType, VariantsEventPayload, } from './pubsub/topics/variants/types';
272
261
  export type { TransactionCreatedPayload, TransactionCreatedEvent, TransactionUpdatedPayload, TransactionUpdatedEvent, TransactionsEventType, TransactionsEventPayload, } from './pubsub/topics/transactions/types';
273
- export type { BookingCreatedPayload, BookingCreatedEvent, BookingUpdatedPayload, BookingUpdatedEvent, BookingSetupChangedPayload, BookingSetupChangedEvent, BookingsEventType, BookingsEventPayload, } from './pubsub/topics/bookings/types';
274
262
  export type { CategoryCreatedPayload, CategoryCreatedEvent, CategoryUpdatedPayload, CategoryUpdatedEvent, CategoriesEventType, CategoriesEventPayload, } from './pubsub/topics/categories/types';
275
263
  export type { AttributeCreatedPayload, AttributeCreatedEvent, AttributeUpdatedPayload, AttributeUpdatedEvent, AttributesEventType, AttributesEventPayload, } from './pubsub/topics/attributes/types';
276
264
  export type { CartCreatedPayload, CartCustomerAssignedPayload, ProductAddedPayload, ProductDeletedPayload, CartDiscountAddedPayload, CartDiscountRemovedPayload, CartFeeAddedPayload, CartFeeRemovedPayload, ProductDiscountAddedPayload, ProductDiscountRemovedPayload, ProductFeeAddedPayload, ProductFeeRemovedPayload, ProductNoteAddedPayload, ProductNoteRemovedPayload, CartCreatedEvent, CartCustomerAssignedEvent, ProductAddedEvent, ProductDeletedEvent, CartDiscountAddedEvent, CartDiscountRemovedEvent, CartFeeAddedEvent, CartFeeRemovedEvent, ProductDiscountAddedEvent, ProductDiscountRemovedEvent, ProductFeeAddedEvent, ProductFeeRemovedEvent, ProductNoteAddedEvent, ProductNoteRemovedEvent, CartEventType, CartEventPayload, } from './pubsub/topics/cart/types';
package/dist/index.js CHANGED
@@ -1,13 +1,6 @@
1
1
  // Import actions from new folder structure
2
2
  import { exampleFunction } from './actions/example-function/action';
3
3
  import { getProducts } from './actions/get-products/action';
4
- import { getBookingResources } from './actions/get-booking-resources/action';
5
- import { getBookingAvailability } from './actions/get-booking-availability/action';
6
- import { getBookings } from './actions/get-bookings/action';
7
- import { holdBooking } from './actions/hold-booking/action';
8
- import { addBookingToCart } from './actions/add-booking-to-cart/action';
9
- import { removeBookingFromCart } from './actions/remove-booking-from-cart/action';
10
- import { cancelBooking } from './actions/cancel-booking/action';
11
4
  import { addCustomSale } from './actions/add-custom-sale/action';
12
5
  import { editCustomSale } from './actions/edit-custom-sale/action';
13
6
  import { addNonRevenueItem } from './actions/add-non-revenue-item/action';
@@ -27,6 +20,8 @@ import { updateCartItemQuantity } from './actions/update-cart-item-quantity/acti
27
20
  // Product Actions
28
21
  import { addProductNote } from './actions/add-product-note/action';
29
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';
30
25
  import { setActiveProductFee } from './actions/set-active-product-fee/action';
31
26
  import { setActiveProductDiscount } from './actions/set-active-product-discount/action';
32
27
  import { getActiveProduct } from './actions/get-active-product/action';
@@ -144,13 +139,6 @@ export const command = {
144
139
  exampleFunction,
145
140
  generateAPIKey,
146
141
  getProducts,
147
- getBookingResources,
148
- getBookingAvailability,
149
- getBookings,
150
- holdBooking,
151
- addBookingToCart,
152
- removeBookingFromCart,
153
- cancelBooking,
154
142
  addCustomSale,
155
143
  editCustomSale,
156
144
  addNonRevenueItem,
@@ -171,6 +159,8 @@ export const command = {
171
159
  // Product Actions
172
160
  addProductNote,
173
161
  addProductFee,
162
+ getProductModifierSelections,
163
+ setProductModifierSelections,
174
164
  setActiveProductFee,
175
165
  setActiveProductDiscount,
176
166
  getActiveProduct,
@@ -315,7 +305,6 @@ export { variantsTopic } from './pubsub/topics/variants';
315
305
  export { transactionsTopic } from './pubsub/topics/transactions';
316
306
  export { categoriesTopic } from './pubsub/topics/categories';
317
307
  export { attributesTopic } from './pubsub/topics/attributes';
318
- export { bookingsTopic } from './pubsub/topics/bookings';
319
308
  // Export Custom Tables Types
320
309
  export { AttributeType } from './common-types/attribute-type';
321
310
  // State Machine Fragments
@@ -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';
@@ -42,13 +44,6 @@ import { mockGetCurrentCart } from '../../actions/get-current-cart/mock';
42
44
  import { mockGetCustomers } from '../../actions/get-customers/mock';
43
45
  import { mockGetOrders } from '../../actions/get-orders/mock';
44
46
  import { mockGetProducts } from '../../actions/get-products/mock';
45
- import { mockGetBookingResources } from '../../actions/get-booking-resources/mock';
46
- import { mockGetBookingAvailability } from '../../actions/get-booking-availability/mock';
47
- import { mockGetBookings } from '../../actions/get-bookings/mock';
48
- import { mockHoldBooking } from '../../actions/hold-booking/mock';
49
- import { mockAddBookingToCart } from '../../actions/add-booking-to-cart/mock';
50
- import { mockRemoveBookingFromCart } from '../../actions/remove-booking-from-cart/mock';
51
- import { mockCancelBooking } from '../../actions/cancel-booking/mock';
52
47
  import { mockGetRefunds } from '../../actions/get-refunds/mock';
53
48
  import { mockGetTaxTables } from '../../actions/get-tax-tables/mock';
54
49
  import { mockGetRemainingRefundableQuantities } from '../../actions/get-remaining-refundable-quantities/mock';
@@ -119,6 +114,8 @@ export const RENDER_MOCKS = {
119
114
  addOrderNote: mockAddOrderNote,
120
115
  addProductDiscount: mockAddProductDiscount,
121
116
  addProductFee: mockAddProductFee,
117
+ getProductModifierSelections: mockGetProductModifierSelections,
118
+ setProductModifierSelections: mockSetProductModifierSelections,
122
119
  setActiveProductFee: mockSetActiveProductFee,
123
120
  setActiveProductDiscount: mockSetActiveProductDiscount,
124
121
  getActiveProduct: mockGetActiveProduct,
@@ -145,13 +142,6 @@ export const RENDER_MOCKS = {
145
142
  getCustomers: mockGetCustomers,
146
143
  getOrders: mockGetOrders,
147
144
  getProducts: mockGetProducts,
148
- getBookingResources: mockGetBookingResources,
149
- getBookingAvailability: mockGetBookingAvailability,
150
- getBookings: mockGetBookings,
151
- holdBooking: mockHoldBooking,
152
- addBookingToCart: mockAddBookingToCart,
153
- removeBookingFromCart: mockRemoveBookingFromCart,
154
- cancelBooking: mockCancelBooking,
155
145
  getRefunds: mockGetRefunds,
156
146
  getTaxTables: mockGetTaxTables,
157
147
  getRemainingRefundableQuantities: mockGetRemainingRefundableQuantities,
@@ -1,14 +1,7 @@
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, 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, 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, CreatePaymentLink, ChargeMoto, GetTimeClockStatus } from '../../index';
2
2
  export interface RenderProviderActions {
3
3
  exampleFunction: ExampleFunction;
4
4
  getProducts: GetProducts;
5
- getBookingResources: GetBookingResources;
6
- getBookingAvailability: GetBookingAvailability;
7
- getBookings: GetBookings;
8
- holdBooking: HoldBooking;
9
- addBookingToCart: AddBookingToCart;
10
- removeBookingFromCart: RemoveBookingFromCart;
11
- cancelBooking: CancelBooking;
12
5
  addCustomSale: AddCustomSale;
13
6
  editCustomSale: EditCustomSale;
14
7
  getCustomers: GetCustomers;
@@ -28,6 +21,8 @@ export interface RenderProviderActions {
28
21
  getFinalContext: GetFinalContext;
29
22
  addProductNote: AddProductNote;
30
23
  addProductFee: AddProductFee;
24
+ getProductModifierSelections: GetProductModifierSelections;
25
+ setProductModifierSelections: SetProductModifierSelections;
31
26
  setActiveProductFee: SetActiveProductFee;
32
27
  setActiveProductDiscount: SetActiveProductDiscount;
33
28
  getActiveProduct: GetActiveProduct;
@@ -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>;
@@ -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
- export type CartEventPayload = CartCreatedPayload | CartCustomerAssignedPayload | ProductAddedPayload | ProductDeletedPayload | CartProductUpdatedPayload | CartDiscountAddedPayload | CartDiscountRemovedPayload | CartFeeAddedPayload | CartFeeRemovedPayload | ProductDiscountAddedPayload | ProductDiscountRemovedPayload | ProductFeeAddedPayload | ProductFeeRemovedPayload | ProductNoteAddedPayload | ProductNoteRemovedPayload;
36
- 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";
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";
@@ -18,3 +18,4 @@ export * from "./product-fee-added/types";
18
18
  export * from "./product-fee-removed/types";
19
19
  export * from "./product-note-added/types";
20
20
  export * from "./product-note-removed/types";
21
+ export * from "./product-modifiers-updated/types";
@@ -2,20 +2,19 @@
2
2
  * Pub/Sub Topics
3
3
  * Export all available topics and their types
4
4
  */
5
- export * from './customers';
6
- export * from './orders';
7
- export * from './bookings';
8
- export * from './refunds';
9
- export * from './products';
10
- export * from './cart';
11
- export * from './payments';
12
- export * from './custom-tables';
13
- export * from './print';
14
- export * from './outlet';
15
- export * from './station';
16
- export * from './session';
17
- export * from './users';
18
- export * from './variants';
19
- export * from './transactions';
20
- export * from './categories';
21
- export * from './attributes';
5
+ export * from "./customers";
6
+ export * from "./orders";
7
+ export * from "./refunds";
8
+ export * from "./products";
9
+ export * from "./cart";
10
+ export * from "./payments";
11
+ export * from "./custom-tables";
12
+ export * from "./print";
13
+ export * from "./outlet";
14
+ export * from "./station";
15
+ export * from "./session";
16
+ export * from "./users";
17
+ export * from "./variants";
18
+ export * from "./transactions";
19
+ export * from "./categories";
20
+ export * from "./attributes";