@pisell/pisellos 2.2.314 → 2.2.316

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 (268) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +3 -1
  3. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  4. package/dist/model/strategy/adapter/itemRule/adapter.js +74 -7
  5. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  6. package/dist/model/strategy/adapter/itemRule/evaluator.js +13 -0
  7. package/dist/model/strategy/adapter/itemRule/type.d.ts +40 -1
  8. package/dist/model/strategy/adapter/itemRule/type.js +10 -0
  9. package/dist/model/strategy/adapter/promotion/evaluator.js +89 -104
  10. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
  11. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +28 -4
  12. package/dist/modules/BookingContext/utils/productExtend.d.ts +7 -0
  13. package/dist/modules/BookingContext/utils/productExtend.js +62 -18
  14. package/dist/modules/BookingContext/utils/resources.js +1 -1
  15. package/dist/modules/BusinessAvailability/index.d.ts +30 -0
  16. package/dist/modules/BusinessAvailability/index.js +204 -0
  17. package/dist/modules/Cart/index.js +4 -3
  18. package/dist/modules/Cart/types.d.ts +2 -0
  19. package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
  20. package/dist/modules/Cart/utils/cartProduct.js +59 -32
  21. package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
  22. package/dist/modules/FulfillmentTiming/index.js +407 -0
  23. package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
  24. package/dist/modules/FulfillmentTiming/types.js +1 -0
  25. package/dist/modules/Holder/utils.d.ts +2 -0
  26. package/dist/modules/Holder/utils.js +32 -2
  27. package/dist/modules/OpenData/contactInfo.d.ts +20 -0
  28. package/dist/modules/OpenData/contactInfo.js +70 -0
  29. package/dist/modules/OpenData/index.d.ts +1 -0
  30. package/dist/modules/OpenData/index.js +1 -0
  31. package/dist/modules/OpenData/types.d.ts +23 -0
  32. package/dist/modules/Order/holderRelations.d.ts +14 -0
  33. package/dist/modules/Order/holderRelations.js +154 -0
  34. package/dist/modules/Order/index.d.ts +16 -4
  35. package/dist/modules/Order/index.js +926 -511
  36. package/dist/modules/Order/localEftposState.d.ts +13 -0
  37. package/dist/modules/Order/localEftposState.js +39 -0
  38. package/dist/modules/Order/pickupTiming.d.ts +46 -0
  39. package/dist/modules/Order/pickupTiming.js +53 -0
  40. package/dist/modules/Order/types.d.ts +49 -3
  41. package/dist/modules/Order/types.js +2 -0
  42. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
  43. package/dist/modules/Order/utils/discountProductLineIdentity.js +142 -7
  44. package/dist/modules/Order/utils/orderCollectionIdentity.js +24 -10
  45. package/dist/modules/Order/utils.d.ts +2 -1
  46. package/dist/modules/Order/utils.js +61 -17
  47. package/dist/modules/Payment/index.js +9 -10
  48. package/dist/modules/Product/types.d.ts +11 -0
  49. package/dist/modules/ProductList/index.js +1 -1
  50. package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
  51. package/dist/modules/ResourcePlanner/planner.js +332 -23
  52. package/dist/modules/ResourcePlanner/types.d.ts +29 -0
  53. package/dist/modules/Rules/index.js +62 -61
  54. package/dist/modules/Schedule/index.d.ts +8 -0
  55. package/dist/modules/Schedule/index.js +141 -39
  56. package/dist/modules/index.d.ts +1 -0
  57. package/dist/modules/index.js +1 -0
  58. package/dist/plugins/request.d.ts +7 -0
  59. package/dist/server/index.d.ts +1 -0
  60. package/dist/server/index.js +1557 -1322
  61. package/dist/server/modules/form/index.d.ts +19 -0
  62. package/dist/server/modules/form/index.js +205 -0
  63. package/dist/server/modules/form/types.d.ts +13 -0
  64. package/dist/server/modules/form/types.js +3 -0
  65. package/dist/server/modules/index.d.ts +3 -0
  66. package/dist/server/modules/index.js +4 -0
  67. package/dist/server/modules/order/index.d.ts +19 -0
  68. package/dist/server/modules/order/index.js +1071 -774
  69. package/dist/server/modules/order/types.d.ts +4 -0
  70. package/dist/server/modules/products/index.d.ts +28 -7
  71. package/dist/server/modules/products/index.js +1297 -770
  72. package/dist/server/modules/products/replication.d.ts +8 -0
  73. package/dist/server/modules/products/replication.js +69 -0
  74. package/dist/server/modules/products/types.d.ts +12 -1
  75. package/dist/server/modules/products/types.js +4 -0
  76. package/dist/server/test.json +1 -1
  77. package/dist/server/utils/small-ticket.d.ts +1 -85
  78. package/dist/server/utils/small-ticket.js +2 -2542
  79. package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
  80. package/dist/shared/payment/loadPaymentMethods.js +66 -0
  81. package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  82. package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
  83. package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  84. package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
  85. package/dist/shared/receipt/small-ticket.d.ts +96 -0
  86. package/dist/shared/receipt/small-ticket.js +2763 -0
  87. package/dist/shared/receipt/templateVisibility.d.ts +26 -0
  88. package/dist/shared/receipt/templateVisibility.js +68 -0
  89. package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  90. package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
  91. package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  92. package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
  93. package/dist/solution/BaseSales/index.d.ts +43 -16
  94. package/dist/solution/BaseSales/index.js +2028 -1247
  95. package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
  96. package/dist/solution/BaseSales/pickupTiming.js +616 -0
  97. package/dist/solution/BaseSales/types.d.ts +12 -0
  98. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
  99. package/dist/solution/BaseSales/utils/parseSalesResponse.js +10 -3
  100. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -4
  101. package/dist/solution/BookingByStep/index.d.ts +4 -2
  102. package/dist/solution/BookingByStep/index.js +8 -3
  103. package/dist/solution/BookingTicket/index.d.ts +23 -3
  104. package/dist/solution/BookingTicket/index.js +867 -507
  105. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  106. package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
  107. package/dist/solution/BookingTicket/utils/cartView.js +3 -1
  108. package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
  109. package/dist/solution/OrderInvoicePreview/index.js +340 -0
  110. package/dist/solution/RegisterAndLogin/config.js +54 -11
  111. package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
  112. package/dist/solution/RegisterAndLogin/index.js +1 -1
  113. package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
  114. package/dist/solution/RegisterAndLogin/utils.js +36 -16
  115. package/dist/solution/ScanOrder/index.js +65 -31
  116. package/dist/solution/ScanOrder/types.d.ts +3 -0
  117. package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  118. package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
  119. package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
  120. package/dist/solution/UnifiedBookingSales/index.js +1715 -906
  121. package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
  122. package/dist/solution/VenueBooking/index.d.ts +15 -2
  123. package/dist/solution/VenueBooking/index.js +1062 -785
  124. package/dist/solution/VenueBooking/types.d.ts +2 -1
  125. package/dist/solution/VenueBooking/types.js +1 -0
  126. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  127. package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
  128. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  129. package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
  130. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  131. package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
  132. package/dist/solution/index.d.ts +1 -0
  133. package/dist/solution/index.js +2 -1
  134. package/lib/index.d.ts +2 -0
  135. package/lib/index.js +21 -1
  136. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  137. package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
  138. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  139. package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
  140. package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
  141. package/lib/model/strategy/adapter/itemRule/type.js +10 -0
  142. package/lib/model/strategy/adapter/promotion/evaluator.js +9 -14
  143. package/lib/model/strategy/adapter/promotion/index.js +46 -1
  144. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
  145. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +17 -1
  146. package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
  147. package/lib/modules/BookingContext/utils/productExtend.js +45 -2
  148. package/lib/modules/BookingContext/utils/resources.js +1 -1
  149. package/lib/modules/BusinessAvailability/index.d.ts +30 -0
  150. package/lib/modules/BusinessAvailability/index.js +146 -0
  151. package/lib/modules/Cart/index.js +4 -2
  152. package/lib/modules/Cart/types.d.ts +2 -0
  153. package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
  154. package/lib/modules/Cart/utils/cartProduct.js +39 -20
  155. package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
  156. package/lib/modules/FulfillmentTiming/index.js +359 -0
  157. package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
  158. package/lib/modules/FulfillmentTiming/types.js +5 -0
  159. package/lib/modules/Holder/utils.d.ts +2 -0
  160. package/lib/modules/Holder/utils.js +27 -1
  161. package/lib/modules/OpenData/contactInfo.d.ts +20 -0
  162. package/lib/modules/OpenData/contactInfo.js +56 -0
  163. package/lib/modules/OpenData/index.d.ts +1 -0
  164. package/lib/modules/OpenData/index.js +12 -0
  165. package/lib/modules/OpenData/types.d.ts +23 -0
  166. package/lib/modules/Order/holderRelations.d.ts +14 -0
  167. package/lib/modules/Order/holderRelations.js +98 -0
  168. package/lib/modules/Order/index.d.ts +16 -4
  169. package/lib/modules/Order/index.js +284 -50
  170. package/lib/modules/Order/localEftposState.d.ts +13 -0
  171. package/lib/modules/Order/localEftposState.js +44 -0
  172. package/lib/modules/Order/pickupTiming.d.ts +46 -0
  173. package/lib/modules/Order/pickupTiming.js +61 -0
  174. package/lib/modules/Order/types.d.ts +49 -3
  175. package/lib/modules/Order/types.js +1 -0
  176. package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
  177. package/lib/modules/Order/utils/discountProductLineIdentity.js +51 -2
  178. package/lib/modules/Order/utils/orderCollectionIdentity.js +5 -0
  179. package/lib/modules/Order/utils.d.ts +2 -1
  180. package/lib/modules/Order/utils.js +49 -11
  181. package/lib/modules/Payment/index.js +3 -4
  182. package/lib/modules/Product/types.d.ts +11 -0
  183. package/lib/modules/ProductList/index.js +1 -1
  184. package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
  185. package/lib/modules/ResourcePlanner/planner.js +252 -8
  186. package/lib/modules/ResourcePlanner/types.d.ts +29 -0
  187. package/lib/modules/Rules/index.js +2 -1
  188. package/lib/modules/Schedule/index.d.ts +8 -0
  189. package/lib/modules/Schedule/index.js +68 -12
  190. package/lib/modules/index.d.ts +1 -0
  191. package/lib/modules/index.js +11 -0
  192. package/lib/plugins/request.d.ts +7 -0
  193. package/lib/server/index.d.ts +1 -0
  194. package/lib/server/index.js +166 -39
  195. package/lib/server/modules/form/index.d.ts +19 -0
  196. package/lib/server/modules/form/index.js +73 -0
  197. package/lib/server/modules/form/types.d.ts +13 -0
  198. package/lib/server/modules/form/types.js +9 -0
  199. package/lib/server/modules/index.d.ts +3 -0
  200. package/lib/server/modules/index.js +15 -1
  201. package/lib/server/modules/order/index.d.ts +19 -0
  202. package/lib/server/modules/order/index.js +160 -7
  203. package/lib/server/modules/order/types.d.ts +4 -0
  204. package/lib/server/modules/products/index.d.ts +28 -7
  205. package/lib/server/modules/products/index.js +226 -63
  206. package/lib/server/modules/products/replication.d.ts +8 -0
  207. package/lib/server/modules/products/replication.js +30 -0
  208. package/lib/server/modules/products/types.d.ts +12 -1
  209. package/lib/server/modules/products/types.js +3 -0
  210. package/lib/server/test.json +1 -1
  211. package/lib/server/utils/small-ticket.d.ts +1 -85
  212. package/lib/server/utils/small-ticket.js +9 -2305
  213. package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
  214. package/lib/shared/payment/loadPaymentMethods.js +40 -0
  215. package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  216. package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
  217. package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  218. package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
  219. package/lib/shared/receipt/small-ticket.d.ts +96 -0
  220. package/lib/shared/receipt/small-ticket.js +2555 -0
  221. package/lib/shared/receipt/templateVisibility.d.ts +26 -0
  222. package/lib/shared/receipt/templateVisibility.js +67 -0
  223. package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  224. package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
  225. package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  226. package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
  227. package/lib/solution/BaseSales/index.d.ts +43 -16
  228. package/lib/solution/BaseSales/index.js +401 -33
  229. package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
  230. package/lib/solution/BaseSales/pickupTiming.js +290 -0
  231. package/lib/solution/BaseSales/types.d.ts +12 -0
  232. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
  233. package/lib/solution/BaseSales/utils/parseSalesResponse.js +7 -0
  234. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -8
  235. package/lib/solution/BookingByStep/index.d.ts +4 -2
  236. package/lib/solution/BookingByStep/index.js +7 -3
  237. package/lib/solution/BookingTicket/index.d.ts +23 -3
  238. package/lib/solution/BookingTicket/index.js +197 -9
  239. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  240. package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
  241. package/lib/solution/BookingTicket/utils/cartView.js +3 -1
  242. package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
  243. package/lib/solution/OrderInvoicePreview/index.js +246 -0
  244. package/lib/solution/RegisterAndLogin/config.js +57 -11
  245. package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
  246. package/lib/solution/RegisterAndLogin/index.js +9 -1
  247. package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
  248. package/lib/solution/RegisterAndLogin/utils.js +24 -17
  249. package/lib/solution/ScanOrder/index.js +59 -20
  250. package/lib/solution/ScanOrder/types.d.ts +3 -0
  251. package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  252. package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
  253. package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
  254. package/lib/solution/UnifiedBookingSales/index.js +562 -75
  255. package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
  256. package/lib/solution/VenueBooking/index.d.ts +15 -2
  257. package/lib/solution/VenueBooking/index.js +243 -96
  258. package/lib/solution/VenueBooking/types.d.ts +2 -1
  259. package/lib/solution/VenueBooking/types.js +1 -0
  260. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  261. package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
  262. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  263. package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
  264. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  265. package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
  266. package/lib/solution/index.d.ts +1 -0
  267. package/lib/solution/index.js +11 -0
  268. package/package.json +1 -1
@@ -0,0 +1,13 @@
1
+ /** Local reconciliation state; never part of a cloud checkout payload. */
2
+ export declare const LOCAL_EFTPOS_REFRESH_REQUIRED = "_local_eftpos_refresh_required";
3
+ export declare const LOCAL_EFTPOS_FINALIZED = "_local_eftpos_finalized";
4
+ export declare const PAYMENT_REFRESH_MESSAGE = "\u8BA2\u5355\u9700\u8981\u5237\u65B0\uFF0C\u8BF7\u8054\u7F51\u5237\u65B0\u8BA2\u5355\u540E\u518D\u4ED8\u6B3E";
5
+ export interface LocalEftposFinalization {
6
+ saleId: string | number;
7
+ paymentNumber: string;
8
+ result: 'failed' | 'not_started';
9
+ failedTransactionNumbers: string[];
10
+ }
11
+ export declare function requiresLocalPaymentRefresh(order: any): boolean;
12
+ export declare function isLocalFinalizedPayment(payment: any): boolean;
13
+ export declare function stripLocalEftposState<T extends Record<string, any>>(order: T): T;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PAYMENT_REFRESH_MESSAGE = exports.LOCAL_EFTPOS_REFRESH_REQUIRED = exports.LOCAL_EFTPOS_FINALIZED = void 0;
7
+ exports.isLocalFinalizedPayment = isLocalFinalizedPayment;
8
+ exports.requiresLocalPaymentRefresh = requiresLocalPaymentRefresh;
9
+ exports.stripLocalEftposState = stripLocalEftposState;
10
+ /** Local reconciliation state; never part of a cloud checkout payload. */
11
+ const LOCAL_EFTPOS_REFRESH_REQUIRED = exports.LOCAL_EFTPOS_REFRESH_REQUIRED = '_local_eftpos_refresh_required';
12
+ const LOCAL_EFTPOS_FINALIZED = exports.LOCAL_EFTPOS_FINALIZED = '_local_eftpos_finalized';
13
+ const PAYMENT_REFRESH_MESSAGE = exports.PAYMENT_REFRESH_MESSAGE = '订单需要刷新,请联网刷新订单后再付款';
14
+ function requiresLocalPaymentRefresh(order) {
15
+ return order?.metadata?.[LOCAL_EFTPOS_REFRESH_REQUIRED] === true;
16
+ }
17
+ function isLocalFinalizedPayment(payment) {
18
+ return payment?.status === 'voided' && payment?.metadata?.[LOCAL_EFTPOS_FINALIZED] === true;
19
+ }
20
+ function stripLocalEftposState(order) {
21
+ const result = {
22
+ ...order
23
+ };
24
+ if (order.metadata) {
25
+ result.metadata = {
26
+ ...order.metadata
27
+ };
28
+ delete result.metadata[LOCAL_EFTPOS_REFRESH_REQUIRED];
29
+ }
30
+ if (Array.isArray(order.payments)) {
31
+ result.payments = order.payments.filter(payment => !isLocalFinalizedPayment(payment)).map(payment => {
32
+ if (!payment.metadata?.[LOCAL_EFTPOS_FINALIZED]) return payment;
33
+ const metadata = {
34
+ ...payment.metadata
35
+ };
36
+ delete metadata[LOCAL_EFTPOS_FINALIZED];
37
+ return {
38
+ ...payment,
39
+ metadata
40
+ };
41
+ });
42
+ }
43
+ return result;
44
+ }
@@ -0,0 +1,46 @@
1
+ export type PickupTimingSelectionMode = 'asap' | 'scheduled';
2
+ export type PickupTimingSource = 'asap' | 'schedule' | 'pos_manual';
3
+ export interface PickupTimingBookingInput {
4
+ mode: PickupTimingSelectionMode;
5
+ source: PickupTimingSource;
6
+ /** Store-local calendar date and minute; the caller validates availability. */
7
+ date: string;
8
+ time: string;
9
+ /** Absolute timestamp disambiguates a repeated local minute at a DST change. */
10
+ instant?: string;
11
+ timezone?: string;
12
+ frozen?: boolean;
13
+ }
14
+ export interface PickupTimingBookingMetadata {
15
+ unique_identification_number: string;
16
+ is_fulfillment_timing: true;
17
+ fulfillment_timing: {
18
+ method: 'pick_up';
19
+ mode: PickupTimingSelectionMode;
20
+ source: PickupTimingSource;
21
+ instant?: string;
22
+ timezone?: string;
23
+ frozen?: boolean;
24
+ };
25
+ [key: string]: any;
26
+ }
27
+ export interface PickupTimingBooking {
28
+ schedule_id: number | string;
29
+ start_date: string;
30
+ end_date: string;
31
+ start_time: string;
32
+ end_time: string;
33
+ select_date: string;
34
+ duration: 0;
35
+ is_all: 0;
36
+ sub_type: 'minutes';
37
+ like_status: string;
38
+ resources: [];
39
+ metadata: PickupTimingBookingMetadata;
40
+ schedule_event_id?: number | string;
41
+ [key: string]: any;
42
+ }
43
+ /** The explicit marker is the only authority; unlinked ordinary bookings remain ordinary. */
44
+ export declare function isFulfillmentTimingBooking(booking: unknown): boolean;
45
+ /** Update an independent pickup appointment without changing its persisted row identity. */
46
+ export declare function buildPickupTimingBooking(input: PickupTimingBookingInput, existing?: Record<string, any> | null): PickupTimingBooking;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildPickupTimingBooking = buildPickupTimingBooking;
7
+ exports.isFulfillmentTimingBooking = isFulfillmentTimingBooking;
8
+ var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
9
+ /** The explicit marker is the only authority; unlinked ordinary bookings remain ordinary. */
10
+ function isFulfillmentTimingBooking(booking) {
11
+ return booking?.metadata?.is_fulfillment_timing === true;
12
+ }
13
+
14
+ /** Update an independent pickup appointment without changing its persisted row identity. */
15
+ function buildPickupTimingBooking(input, existing) {
16
+ const booking = {
17
+ ...(existing || {})
18
+ };
19
+ const metadata = {
20
+ ...(booking.metadata || {})
21
+ };
22
+ // A fulfillment appointment never becomes a product/resource/holder purchase line.
23
+ for (const key of ['product_uid', 'product', 'holder', 'holder_id', 'collect_pax', 'capacity']) {
24
+ delete booking[key];
25
+ delete metadata[key];
26
+ }
27
+ delete metadata.booking_uid;
28
+ return {
29
+ ...booking,
30
+ schedule_id: booking.schedule_id || 0,
31
+ start_date: input.date,
32
+ end_date: input.date,
33
+ start_time: input.time,
34
+ end_time: input.time,
35
+ select_date: input.date,
36
+ duration: 0,
37
+ is_all: 0,
38
+ sub_type: 'minutes',
39
+ like_status: booking.like_status || 'common',
40
+ resources: [],
41
+ metadata: {
42
+ ...metadata,
43
+ unique_identification_number: String(metadata.unique_identification_number || (0, _orderCollectionIdentity.createUuidV4)()),
44
+ is_fulfillment_timing: true,
45
+ fulfillment_timing: {
46
+ method: 'pick_up',
47
+ mode: input.mode,
48
+ source: input.source,
49
+ ...(input.instant !== undefined ? {
50
+ instant: input.instant
51
+ } : {}),
52
+ ...(input.timezone !== undefined ? {
53
+ timezone: input.timezone
54
+ } : {}),
55
+ ...(input.frozen !== undefined ? {
56
+ frozen: input.frozen
57
+ } : {})
58
+ }
59
+ }
60
+ };
61
+ }
@@ -7,9 +7,10 @@ import type { SubmitPayloadEnhancer } from './utils';
7
7
  import type { PaymentItem } from '../Payment/types';
8
8
  import type { ICustomer } from '../AccountList/types';
9
9
  import type { OrderProductDiscountItem } from '../../server/modules/order/types';
10
+ import type { PickupTimingBooking, PickupTimingBookingInput } from './pickupTiming';
10
11
  export type { OrderProductDiscountItem } from '../../server/modules/order/types';
11
12
  export type PickupReferenceMode = 'counter_pickup' | 'table_service';
12
- export type ShopServiceType = 'dine_in' | 'takeaway';
13
+ export type ShopServiceType = 'dine_in' | 'takeaway' | 'pick_up' | 'delivery';
13
14
  export interface ShopServiceData {
14
15
  pickup_reference_mode?: PickupReferenceMode;
15
16
  service_type?: ShopServiceType | '';
@@ -212,6 +213,7 @@ export interface VirtualCurrencySnapshotItem {
212
213
  id: number | string;
213
214
  tag: 'virtual_currency';
214
215
  product_id?: number | string;
216
+ code?: string;
215
217
  product_name: string;
216
218
  par_value: string;
217
219
  used_par_value: string;
@@ -241,6 +243,11 @@ export interface OrderProduct extends OrderProductIdentity {
241
243
  product_cover?: string;
242
244
  metadata: Record<string, any>;
243
245
  note?: string;
246
+ /** 仅作按行更新输入;正式数据保存于订单顶层。 */
247
+ _extend?: {
248
+ holder_relations?: OrderHolderRelation[];
249
+ [key: string]: any;
250
+ };
244
251
  }
245
252
  export interface OrderSummary {
246
253
  product_quantity: number;
@@ -338,6 +345,17 @@ export interface SalesNotesMutationSnapshot {
338
345
  }
339
346
  export type SalesNoteProtocolRelation = SalesNoteRelation;
340
347
  export type SalesNoteProtocol = SalesNote;
348
+ /** 后端关系及 metadata 均为开放对象,未知字段必须往返保留。 */
349
+ export interface OrderHolderRelation {
350
+ /** 关系自身的 UUID;新选择/旧草稿可缺省,入单与提交时由 OS 补齐。 */
351
+ uuid?: string;
352
+ relation_model: string;
353
+ relation_uuid: string;
354
+ holder_type: 'form' | 'customer';
355
+ holder_id: number;
356
+ metadata?: Record<string, any>;
357
+ [key: string]: any;
358
+ }
341
359
  export interface OrderTempOrder {
342
360
  order_id: number | null;
343
361
  external_sale_number: string;
@@ -377,6 +395,7 @@ export interface OrderTempOrder {
377
395
  created_at: string | undefined;
378
396
  request_unique_idempotency_token?: string;
379
397
  products: OrderProduct[];
398
+ holder_relations?: OrderHolderRelation[];
380
399
  notes: SalesNote[];
381
400
  bookings: any[];
382
401
  payments: any[];
@@ -396,7 +415,7 @@ export interface OrderTempOrder {
396
415
  [key: string]: any;
397
416
  };
398
417
  }
399
- export interface OrderSubmitProduct extends Omit<OrderProduct, 'unique_identification_number' | 'num'> {
418
+ export interface OrderSubmitProduct extends Omit<OrderProduct, 'unique_identification_number' | 'num' | '_extend'> {
400
419
  product_quantity: number;
401
420
  payment_price: string;
402
421
  product_sku: OrderProductSku;
@@ -439,16 +458,29 @@ export type AddProductBookingInput = Record<string, any>;
439
458
  */
440
459
  export interface AddProductToOrderOptions {
441
460
  insertAfterProductUid?: string;
461
+ /** 新增商品行插入 products 首位,优先于 insertAfterProductUid。 */
462
+ insertAtStart?: boolean;
442
463
  /** 跳过同商品/规格匹配,始终新增购物车行。 */
443
464
  disableMerge?: boolean;
444
465
  /** 商品行 UID 落定后,由 OrderModule 原子绑定到该行的 Sales Notes 草稿。 */
445
466
  salesNotes?: SalesNoteDraftInput[];
467
+ /**
468
+ * 自动预约加购的同步提交门禁;抛错时不发布本次新增。
469
+ * 带门禁时先在私有草稿中准备全部商品/booking,异步等待后及原子发布前重新调用。
470
+ * 门禁须校验当前订单身份/版本和真实时间;发布前不会因本次拆行改变订单版本。
471
+ * 不传时保留原有人工加购行为。
472
+ */
473
+ availabilityCommitGuard?: () => void;
474
+ /** 发布后的订单/业务归属检查;只用于阻止旧异步收尾写入新单,不再校验截止或 revision。 */
475
+ availabilityCommitTargetGuard?: () => boolean;
446
476
  }
447
477
  /**
448
478
  * 删除商品后的可选位置保持策略。
449
479
  * 预约合并行减量时仍删除最新真实行,再把剩余代表行移动到被删除代表行原位置。
450
480
  */
451
481
  export interface RemoveProductsFromOrderOptions {
482
+ /** 自动购物车写入的订单归属检查;失效时不再变更或发布异步收尾结果。 */
483
+ isCurrentOrder?: () => boolean;
452
484
  preserveDisplayPosition?: {
453
485
  remainingProductUid: string;
454
486
  anchorProductUid: string;
@@ -516,7 +548,15 @@ export type OrderProductMergeDecisionResult = boolean | {
516
548
  reason?: string;
517
549
  [key: string]: any;
518
550
  };
551
+ export interface OrderCartIntentCommitContext {
552
+ action: 'add_product' | 'update_product' | 'increase_quantity' | 'scan_promotion';
553
+ tempOrder: OrderTempOrder | null;
554
+ }
519
555
  export interface OrderHooksConfig {
556
+ /** Optional customer-order guard; called synchronously before the first cart write. */
557
+ beforeCartIntentCommit?: (context: OrderCartIntentCommitContext) => void;
558
+ /** Captures tenant/business runtime identity for asynchronous cart intents. */
559
+ getCartIntentScope?: () => unknown;
520
560
  onBeforeMergeProductToOrder?: (context: OrderProductMergeDecisionContext) => OrderProductMergeDecisionResult | Promise<OrderProductMergeDecisionResult>;
521
561
  }
522
562
  /**
@@ -584,6 +624,7 @@ export interface SubmitSalesOrderParams {
584
624
  schedule_date: string;
585
625
  created_at?: string | undefined;
586
626
  products: OrderSubmitProduct[];
627
+ holder_relations?: OrderHolderRelation[];
587
628
  bookings: OrderSubmitBooking[];
588
629
  payments: any[];
589
630
  vouchers: any[];
@@ -863,6 +904,9 @@ export interface OrderModuleAPI {
863
904
  updateTempOrderCustomer: (customer: UpdateTempOrderCustomerInput) => OrderSnapshot['customer'];
864
905
  updateTempOrderPickupReferenceMode: (mode: PickupReferenceMode) => ShopServiceData;
865
906
  updateTempOrderServiceType: (serviceType: ShopServiceType) => ShopServiceData;
907
+ getPickupTimingBooking: () => PickupTimingBooking | null;
908
+ setPickupTimingBooking: (input: PickupTimingBookingInput) => PickupTimingBooking;
909
+ clearPickupTimingBooking: () => void;
866
910
  updateTempOrderBuzzer: (buzzer: string) => string;
867
911
  updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
868
912
  addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions) => Promise<OrderProduct[]>;
@@ -875,7 +919,9 @@ export interface OrderModuleAPI {
875
919
  updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
876
920
  /** 批量更新购物车行,末尾仅触发一次促销重算与 summary 刷新 */
877
921
  updateOrderProducts: (paramsList: UpdateOrderProductParams[]) => Promise<OrderProduct[]>;
878
- updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
922
+ updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams, options?: {
923
+ isCurrentOrder?: () => boolean;
924
+ }) => Promise<OrderProduct[]>;
879
925
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
880
926
  removeProductFromOrder: (identity: OrderProductIdentity, options?: RemoveProductsFromOrderOptions) => Promise<OrderProduct[]>;
881
927
  /** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
@@ -63,6 +63,7 @@ let OrderHooks = exports.OrderHooks = /*#__PURE__*/function (OrderHooks) {
63
63
  * Sales Notes 乐观写入前的可恢复快照。
64
64
  * 该对象应视为 opaque token,只用于原样传回 restoreSalesNotesMutationSnapshot。
65
65
  */
66
+ /** 后端关系及 metadata 均为开放对象,未知字段必须往返保留。 */
66
67
  /**
67
68
  * 添加商品行时的顺序控制。
68
69
  * 默认追加到 products 尾部;预约数量同步可插入到既有预约组的最新行之后,
@@ -31,7 +31,7 @@ export declare const DISCOUNT_SPLIT_ORIGIN_UID_KEY = "discountSplitOriginUid";
31
31
  * 没有 UID 的裸商品不会被补写 UID。这是为了兼容 Rules/mock 的历史协议形状;
32
32
  * 正常 Order 写路径会在 normalize 阶段提前创建 UID。
33
33
  */
34
- export declare function ensureUniqueProductLineUids(tempOrder: OrderTempOrder): void;
34
+ export declare function ensureUniqueProductLineUids(tempOrder: OrderTempOrder, discounts?: Array<Record<string, any>>): void;
35
35
  /**
36
36
  * 把券移除后已经恢复原价的同源折扣拆分行重新合并。
37
37
  *
@@ -9,6 +9,7 @@ exports.ensureUniqueProductLineUids = ensureUniqueProductLineUids;
9
9
  var _lodashEs = require("lodash-es");
10
10
  var _utils = require("../../../solution/ScanOrder/utils");
11
11
  var _orderCollectionIdentity = require("./orderCollectionIdentity");
12
+ var _holderRelations = require("../holderRelations");
12
13
  /**
13
14
  * 商品券拆行的身份与回并工具。
14
15
  *
@@ -72,16 +73,20 @@ function ensureProductsByUid(tempOrder) {
72
73
  * 没有 UID 的裸商品不会被补写 UID。这是为了兼容 Rules/mock 的历史协议形状;
73
74
  * 正常 Order 写路径会在 normalize 阶段提前创建 UID。
74
75
  */
75
- function ensureUniqueProductLineUids(tempOrder) {
76
+ function ensureUniqueProductLineUids(tempOrder, discounts = []) {
76
77
  // usedUids 只描述本次 Rules 返回的商品集合,不能直接依赖 productsByUid:
77
78
  // productsByUid 可能还保留已删除行的历史 runtime,历史 UID 不应导致当前行被改号。
78
79
  const usedUids = new Set();
79
80
  const productsByUid = ensureProductsByUid(tempOrder);
81
+ const splitGroups = new Map();
80
82
  tempOrder.products = (tempOrder.products || []).map(product => {
81
83
  const sourceUid = getProductLineUid(product);
82
84
  // 单测 mock 或兼容旧 Rules 时可能返回没有 UID 的裸商品。
83
85
  // 这里不主动补 UID,避免一个“校验重复”的工具意外改变旧协议对象形状。
84
86
  if (!sourceUid) return product;
87
+ const group = splitGroups.get(sourceUid) || [];
88
+ group.push(product);
89
+ splitGroups.set(sourceUid, group);
85
90
 
86
91
  // 实际场景:可乐 ×5 首次进入 Rules 时只有一行。
87
92
  // 使用三张券后 Rules 可能返回「可乐 ×2 + 三条可乐 ×1」,但四条都复制原 UID。
@@ -122,6 +127,50 @@ function ensureUniqueProductLineUids(tempOrder) {
122
127
  usedUids.add(splitUid);
123
128
  return product;
124
129
  });
130
+
131
+ // 仅按本次券上的明确 Holder 分配迁移。数组顺序不能代表券对应的人。
132
+ // 未能明确分配时保留原 UID,不把整组关系复制给每一个拆分行。
133
+ for (const [sourceUid, products] of splitGroups) {
134
+ if (products.length < 2) continue;
135
+ const relations = (0, _holderRelations.getProductHolderRelations)(tempOrder, {
136
+ metadata: {
137
+ unique_identification_number: sourceUid
138
+ }
139
+ });
140
+ if (!relations.length || relations.some(relation => relation.holder_type !== 'form')) continue;
141
+ const assignments = new Map();
142
+ let remaining = [...relations];
143
+ let ambiguous = false;
144
+ for (const product of products) {
145
+ const holderIds = new Set();
146
+ for (const item of product.discount_list || []) {
147
+ const discount = discounts.find(candidate => String(candidate.id) === String(item.discount?.resource_id));
148
+ if (discount?.holder?.holder_type !== 'form') continue;
149
+ const value = discount.holder.holder_id;
150
+ (Array.isArray(value) ? value : [value]).forEach(id => {
151
+ const recordId = id && typeof id === 'object' ? id.form_record_id : id;
152
+ if (recordId !== undefined && recordId !== null && recordId !== '') holderIds.add(String(recordId));
153
+ });
154
+ }
155
+ if (!holderIds.size) continue;
156
+ const assigned = remaining.filter(relation => holderIds.has(String(relation.holder_id)));
157
+ if (assigned.length !== Number(product.num)) {
158
+ ambiguous = true;
159
+ break;
160
+ }
161
+ assignments.set(product, assigned);
162
+ remaining = remaining.filter(relation => !assigned.includes(relation));
163
+ }
164
+ const unassigned = products.filter(product => !assignments.has(product));
165
+ if (ambiguous || unassigned.length > 1) continue;
166
+ if (unassigned.length === 1) {
167
+ if (remaining.length !== Number(unassigned[0].num)) continue;
168
+ assignments.set(unassigned[0], remaining);
169
+ } else if (remaining.length) continue;
170
+ for (const [product, assigned] of assignments) {
171
+ for (const relation of assigned) relation.relation_uuid = String(getProductLineUid(product));
172
+ }
173
+ }
125
174
  }
126
175
 
127
176
  /**
@@ -154,7 +203,7 @@ function consolidateDiscountFreeProductLines(tempOrder) {
154
203
  // - 手动改价/备注:用户显式表达了不同价格或不同制作要求;
155
204
  // - 称重商品:每次称重的净重和金额属于独立交易事实;
156
205
  // - 预约/holder/历史订单行:分别关联预约、持有人或后端 order_detail。
157
- const hasMergeBoundary = hasDiscount || Boolean(product.metadata?._giftInfo || product._giftInfo) || Boolean(product.metadata?._promotion) || isManualProductDiscountLine(product) || hasProductLineNote(product) || Number(product.product_sku?.open_sold_weight || 0) === 1 || product.metadata?.is_edit_for_runtime === true || bookingId !== undefined && bookingId !== null && bookingId !== 0 && bookingId !== '0' || bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '' || holderId !== undefined && holderId !== null && String(holderId) !== '' || orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '';
206
+ const hasMergeBoundary = hasDiscount || Boolean(product.metadata?._giftInfo || product._giftInfo) || Boolean(product.metadata?._promotion) || isManualProductDiscountLine(product) || hasProductLineNote(product) || Number(product.product_sku?.open_sold_weight || 0) === 1 || product.metadata?.is_edit_for_runtime === true || bookingId !== undefined && bookingId !== null && bookingId !== 0 && bookingId !== '0' || bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '' || (0, _holderRelations.getProductHolderRelations)(tempOrder, product).length > 0 || holderId !== undefined && holderId !== null && String(holderId) !== '' || orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '';
158
207
  if (hasMergeBoundary) {
159
208
  consolidatedProducts.push(product);
160
209
  continue;
@@ -331,6 +331,11 @@ function applyOrderCollectionUidRemaps(sourceOrder, uidRemaps) {
331
331
  }
332
332
  // 冲突 UID 仍由第一条持有;赠品父引用缺少可用的持久化行定位时不能全局改写。
333
333
  if (remap.scope !== 'linked-owner') {
334
+ for (const relation of order.holder_relations || []) {
335
+ if (relation.relation_model === 'order_detail' && String(relation.relation_uuid) === remap.from) {
336
+ relation.relation_uuid = remap.to;
337
+ }
338
+ }
334
339
  for (const product of order.products || []) {
335
340
  if (String(product?.metadata?.parent_unique_identification_number || '') === remap.from) {
336
341
  product.metadata = {
@@ -173,7 +173,7 @@ export declare function resolveManualOverrideLineOriginalPrice(params: {
173
173
  * // => -4
174
174
  */
175
175
  export declare function resolveEffectivePerUnitDiscount(product: Record<string, any>): number;
176
- export declare function createDefaultOrderRulesHooks(getBookings?: () => OrderTempOrder['bookings']): RulesParamsHooks;
176
+ export declare function createDefaultOrderRulesHooks(getBookings?: () => OrderTempOrder['bookings'], getHolderRelations?: () => OrderTempOrder['holder_relations']): RulesParamsHooks;
177
177
  /**
178
178
  * 通过 session 类商品的开始时间结束时间生成商品的时长
179
179
  * @param {CartItem} cartItem
@@ -213,6 +213,7 @@ export declare function normalizeBookingSubType(booking: Record<string, any>): s
213
213
  export declare function normalizeSubmitBooking<T extends {
214
214
  metadata?: Record<string, any>;
215
215
  }>(booking: T): T;
216
+ export declare function resolveTableOccupancyDuration(tempOrder: OrderTempOrder): number;
216
217
  /** 提交用人数:有限且为正则向下取整,否则为 1 */
217
218
  export declare function normalizeSubmitCollectPaxValue(value: unknown): number;
218
219
  /** 从临时订单 metadata 解析合成 booking 的 collect_pax */
@@ -109,6 +109,7 @@ Object.defineProperty(exports, "resolveSafeProductNum", {
109
109
  });
110
110
  exports.resolveSubmitCollectPax = resolveSubmitCollectPax;
111
111
  exports.resolveSubmitOrderType = resolveSubmitOrderType;
112
+ exports.resolveTableOccupancyDuration = resolveTableOccupancyDuration;
112
113
  Object.defineProperty(exports, "shouldBuildManualProductDiscount", {
113
114
  enumerable: true,
114
115
  get: function () {
@@ -128,6 +129,7 @@ Object.defineProperty(exports, "syncManualProductDiscountProductNum", {
128
129
  return _manualProductDiscount.syncManualProductDiscountProductNum;
129
130
  }
130
131
  });
132
+ var _lodashEs = require("lodash-es");
131
133
  var _dayjs = _interopRequireDefault(require("dayjs"));
132
134
  var _customParseFormat = _interopRequireDefault(require("dayjs/plugin/customParseFormat"));
133
135
  var _decimal = _interopRequireDefault(require("decimal.js"));
@@ -137,6 +139,8 @@ var _utils = require("../Holder/utils");
137
139
  var _utils2 = require("../../solution/ScanOrder/utils");
138
140
  var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
139
141
  var _salesNotes = require("./salesNotes");
142
+ var _pickupTiming = require("./pickupTiming");
143
+ var _holderRelations = require("./holderRelations");
140
144
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
141
145
  _dayjs.default.extend(_customParseFormat.default);
142
146
  const POINT_CARD_SNAPSHOT_TAG = 'point_card';
@@ -283,6 +287,10 @@ function normalizeVirtualCurrencySnapshotItem(value) {
283
287
  if (productId !== undefined) {
284
288
  snapshot.product_id = productId;
285
289
  }
290
+ const code = normalizeSnapshotScalar(value.code);
291
+ if (code !== undefined) {
292
+ snapshot.code = String(code).trim();
293
+ }
286
294
  return snapshot;
287
295
  }
288
296
  function normalizeVirtualCurrencySnapshotList(value) {
@@ -313,6 +321,10 @@ function buildVirtualCurrencySnapshotFromList(value) {
313
321
  if (productId !== undefined) {
314
322
  snapshot.product_id = productId;
315
323
  }
324
+ const code = normalizeSnapshotScalar(item.code);
325
+ if (code !== undefined) {
326
+ snapshot.code = String(code).trim();
327
+ }
316
328
  result.push(snapshot);
317
329
  return result;
318
330
  }, []);
@@ -823,7 +835,7 @@ function resolveEffectivePerUnitDiscount(product) {
823
835
  if (!Number.isFinite(originalPrice) || !Number.isFinite(finalPrice)) return fromList;
824
836
  return fromList + (originalPrice - finalPrice);
825
837
  }
826
- function createDefaultOrderRulesHooks(getBookings) {
838
+ function createDefaultOrderRulesHooks(getBookings, getHolderRelations) {
827
839
  const getProductStartDate = product => {
828
840
  const productUid = String(product.metadata?.unique_identification_number ?? product.unique_identification_number ?? '');
829
841
  const bookingUid = String(product.booking_uid ?? product.metadata?.booking_uid ?? '');
@@ -941,7 +953,9 @@ function createDefaultOrderRulesHooks(getBookings) {
941
953
  // 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
942
954
  // 无券时会把 bundle 价还原成 original_price(手动改价套餐会从 20 回到 30)。
943
955
  isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
944
- holder_id: product.metadata?.holder_id,
956
+ holder_id: (0, _holderRelations.hasProductBooking)(product) || !getHolderRelations ? product.metadata?.holder_id : (0, _holderRelations.getProductHolderRelations)({
957
+ holder_relations: getHolderRelations()
958
+ }, product).filter(relation => relation.holder_type === 'form').map(relation => relation.holder_id),
945
959
  startDate: getProductStartDate(product),
946
960
  main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString() : undefined,
947
961
  inPromotion: metadataAny._promotion?.inPromotion === true,
@@ -1232,6 +1246,7 @@ function normalizeSubmitProduct(product, formatOptions = {}) {
1232
1246
  } = product;
1233
1247
  const {
1234
1248
  num,
1249
+ _extend: _productExtend,
1235
1250
  surcharge_fee: _productSurchargeFee,
1236
1251
  discount_amount: _deprecatedDiscountAmount,
1237
1252
  discount_type: _deprecatedDiscountType,
@@ -1318,7 +1333,7 @@ function normalizeSubmitProduct(product, formatOptions = {}) {
1318
1333
  payment_price: formatOptions.virtualSettlementMode ? virtualPrice : submitProduct.payment_price ?? submitProduct.selling_price
1319
1334
  };
1320
1335
  }
1321
- const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder'];
1336
+ const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder', 'is_fulfillment_timing', 'fulfillment_timing'];
1322
1337
  function normalizeBookingIsAll(booking) {
1323
1338
  return booking.is_all === true || booking.is_all === 1 || booking.is_all === '1' || booking.is_all === 'true' ? 1 : 0;
1324
1339
  }
@@ -1337,7 +1352,9 @@ function normalizeSubmitBooking(booking) {
1337
1352
  cleanMetadata[key] = rawMetadata[key];
1338
1353
  }
1339
1354
  }
1340
- if (cleanMetadata.holder_id === undefined) cleanMetadata.holder_id = null;
1355
+ if (cleanMetadata.holder_id === undefined && !(0, _pickupTiming.isFulfillmentTimingBooking)(booking)) {
1356
+ cleanMetadata.holder_id = null;
1357
+ }
1341
1358
  const bookingRecord = booking;
1342
1359
  const startDate = bookingRecord.start_date;
1343
1360
  const shouldRestoreSelectDate = bookingRecord.select_date === undefined || bookingRecord.select_date === null || bookingRecord.select_date === '';
@@ -1349,6 +1366,10 @@ function normalizeSubmitBooking(booking) {
1349
1366
  } : {}),
1350
1367
  is_all: normalizeBookingIsAll(bookingRecord),
1351
1368
  sub_type: normalizeBookingSubType(bookingRecord),
1369
+ ...((0, _pickupTiming.isFulfillmentTimingBooking)(booking) ? {
1370
+ like_status: bookingRecord.like_status || 'common',
1371
+ schedule_id: bookingRecord.schedule_id || 0
1372
+ } : {}),
1352
1373
  metadata: cleanMetadata
1353
1374
  };
1354
1375
  }
@@ -1412,6 +1433,7 @@ function createDefaultTempOrder(params) {
1412
1433
  request_unique_idempotency_token: '',
1413
1434
  vouchers: [],
1414
1435
  products: [],
1436
+ holder_relations: [],
1415
1437
  notes: [],
1416
1438
  bookings: [],
1417
1439
  payments: [],
@@ -1434,6 +1456,7 @@ function hasBoundBookingResource(bookings) {
1434
1456
  if (!Array.isArray(bookings)) return false;
1435
1457
  return bookings.some(booking => {
1436
1458
  if (!booking || typeof booking !== 'object') return false;
1459
+ if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) return false;
1437
1460
  if (Number(booking.parent_id) === 0) return false;
1438
1461
  const resources = booking.resources;
1439
1462
  if (!Array.isArray(resources)) return false;
@@ -1469,7 +1492,7 @@ function resolveSubmitOrderType(params) {
1469
1492
  return 'table-order';
1470
1493
  }
1471
1494
  if (currentType) return currentType;
1472
- if (Array.isArray(bookings) && bookings.length > 0) {
1495
+ if (Array.isArray(bookings) && bookings.some(booking => !(0, _pickupTiming.isFulfillmentTimingBooking)(booking))) {
1473
1496
  return businessCode === 'dine_in' ? 'table-order' : 'appointment_booking';
1474
1497
  }
1475
1498
  return 'virtual';
@@ -1486,6 +1509,7 @@ function buildSubmitPayload(params) {
1486
1509
  summary,
1487
1510
  enhance
1488
1511
  } = params;
1512
+ (0, _holderRelations.ensureHolderRelationUuids)(tempOrder);
1489
1513
  const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
1490
1514
  const bookingUuid = (0, _orderCollectionIdentity.createUuidV4)();
1491
1515
  const virtualSettlementMode = tempOrder.metadata?.currency_settlement_config?.settlement_type === 'virtual_currency';
@@ -1525,6 +1549,9 @@ function buildSubmitPayload(params) {
1525
1549
  });
1526
1550
  const payload = {
1527
1551
  ...tempOrderRest,
1552
+ ...(tempOrder.holder_relations !== undefined ? {
1553
+ holder_relations: (0, _lodashEs.cloneDeep)(tempOrder.holder_relations)
1554
+ } : {}),
1528
1555
  customer_id: tempOrder.customer_id ?? 1,
1529
1556
  customer_name: tempOrder.customer_name || 'Walk-In',
1530
1557
  country_calling_code: String(tempOrder.country_calling_code ?? ''),
@@ -1551,10 +1578,10 @@ function buildSubmitPayload(params) {
1551
1578
  shop_discount: tempOrder.shop_discount || '0.00',
1552
1579
  surcharge_fee: tempOrder.surcharge_fee || '0.00',
1553
1580
  note: tempOrder.note || '',
1554
- delivery_type: tempOrder.delivery_type || 'nil',
1581
+ delivery_type: tempOrder.delivery_type || 'shop_service',
1555
1582
  schedule_date: scheduleDate,
1556
1583
  // created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
1557
- bookings: (tempOrder.bookings || []).filter(booking => Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
1584
+ bookings: (tempOrder.bookings || []).filter(booking => (0, _pickupTiming.isFulfillmentTimingBooking)(booking) || Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
1558
1585
  payments: tempOrder.payments || [],
1559
1586
  relation_forms: tempOrder.relation_forms || [],
1560
1587
  // contacts: tempOrder.contacts || [],
@@ -1717,15 +1744,24 @@ function hasAssignedHolderId(value) {
1717
1744
  * clearTempOrderHolderAssignments(tempOrder);
1718
1745
  */
1719
1746
  function clearTempOrderHolderAssignments(tempOrder) {
1720
- let changed = false;
1747
+ const previousRelationCount = tempOrder.holder_relations?.length || 0;
1748
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, (tempOrder.products || []).filter(product => !(0, _holderRelations.hasProductBooking)(product)));
1749
+ let changed = previousRelationCount !== (tempOrder.holder_relations?.length || 0);
1721
1750
  const resetHolderField = (target, key = 'holder_id') => {
1722
1751
  if (!hasAssignedHolderId(target[key])) return;
1723
1752
  target[key] = null;
1724
1753
  changed = true;
1725
1754
  };
1755
+ const clearHolder = target => {
1756
+ resetHolderField(target);
1757
+ if (target.holder !== undefined && target.holder !== null) {
1758
+ target.holder = null;
1759
+ changed = true;
1760
+ }
1761
+ };
1726
1762
  for (const product of tempOrder.products || []) {
1727
1763
  if (product.metadata && typeof product.metadata === 'object') {
1728
- resetHolderField(product.metadata);
1764
+ clearHolder(product.metadata);
1729
1765
  }
1730
1766
  }
1731
1767
  for (const booking of tempOrder.bookings || []) {
@@ -1743,11 +1779,13 @@ function clearTempOrderHolderAssignments(tempOrder) {
1743
1779
  for (const entry of Object.values(productsByUid)) {
1744
1780
  const origin = entry?.origin;
1745
1781
  if (!origin || typeof origin !== 'object') continue;
1782
+ clearHolder(origin);
1746
1783
  if (origin.metadata && typeof origin.metadata === 'object') {
1747
- resetHolderField(origin.metadata);
1784
+ clearHolder(origin.metadata);
1748
1785
  }
1749
1786
  if (origin._extend && typeof origin._extend === 'object') {
1750
- resetHolderField(origin._extend);
1787
+ clearHolder(origin._extend);
1788
+ delete origin._extend.holder_relations;
1751
1789
  }
1752
1790
  }
1753
1791
  }