@pisell/pisellos 2.2.313 → 2.2.315

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 (215) 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/modules/BookingContext/utils/productExtend.d.ts +7 -0
  10. package/dist/modules/BookingContext/utils/productExtend.js +62 -18
  11. package/dist/modules/BookingContext/utils/resources.js +1 -1
  12. package/dist/modules/BusinessAvailability/index.d.ts +30 -0
  13. package/dist/modules/BusinessAvailability/index.js +204 -0
  14. package/dist/modules/Cart/index.js +4 -3
  15. package/dist/modules/Cart/types.d.ts +2 -0
  16. package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
  17. package/dist/modules/Cart/utils/cartProduct.js +59 -32
  18. package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
  19. package/dist/modules/FulfillmentTiming/index.js +407 -0
  20. package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
  21. package/dist/modules/FulfillmentTiming/types.js +1 -0
  22. package/dist/modules/OpenData/types.d.ts +14 -0
  23. package/dist/modules/Order/index.d.ts +14 -2
  24. package/dist/modules/Order/index.js +856 -486
  25. package/dist/modules/Order/localEftposState.d.ts +13 -0
  26. package/dist/modules/Order/localEftposState.js +39 -0
  27. package/dist/modules/Order/pickupTiming.d.ts +46 -0
  28. package/dist/modules/Order/pickupTiming.js +53 -0
  29. package/dist/modules/Order/types.d.ts +30 -2
  30. package/dist/modules/Order/utils.js +25 -7
  31. package/dist/modules/Payment/index.js +9 -10
  32. package/dist/modules/Product/types.d.ts +11 -0
  33. package/dist/modules/ProductList/index.js +1 -1
  34. package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
  35. package/dist/modules/ResourcePlanner/planner.js +332 -23
  36. package/dist/modules/ResourcePlanner/types.d.ts +29 -0
  37. package/dist/modules/Schedule/index.d.ts +8 -0
  38. package/dist/modules/Schedule/index.js +141 -39
  39. package/dist/modules/index.d.ts +1 -0
  40. package/dist/modules/index.js +1 -0
  41. package/dist/plugins/request.d.ts +7 -0
  42. package/dist/server/index.d.ts +1 -0
  43. package/dist/server/index.js +1536 -1309
  44. package/dist/server/modules/form/index.d.ts +19 -0
  45. package/dist/server/modules/form/index.js +205 -0
  46. package/dist/server/modules/form/types.d.ts +13 -0
  47. package/dist/server/modules/form/types.js +3 -0
  48. package/dist/server/modules/index.d.ts +3 -0
  49. package/dist/server/modules/index.js +4 -0
  50. package/dist/server/modules/order/index.d.ts +15 -0
  51. package/dist/server/modules/order/index.js +920 -688
  52. package/dist/server/modules/order/types.d.ts +1 -0
  53. package/dist/server/test.json +1 -1
  54. package/dist/server/utils/small-ticket.d.ts +1 -85
  55. package/dist/server/utils/small-ticket.js +2 -2542
  56. package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
  57. package/dist/shared/payment/loadPaymentMethods.js +66 -0
  58. package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  59. package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
  60. package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  61. package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
  62. package/dist/shared/receipt/small-ticket.d.ts +96 -0
  63. package/dist/shared/receipt/small-ticket.js +2751 -0
  64. package/dist/shared/receipt/templateVisibility.d.ts +23 -0
  65. package/dist/shared/receipt/templateVisibility.js +64 -0
  66. package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  67. package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
  68. package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  69. package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
  70. package/dist/solution/BaseSales/index.d.ts +39 -16
  71. package/dist/solution/BaseSales/index.js +1754 -1154
  72. package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
  73. package/dist/solution/BaseSales/pickupTiming.js +616 -0
  74. package/dist/solution/BaseSales/types.d.ts +11 -0
  75. package/dist/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  76. package/dist/solution/BookingByStep/index.d.ts +4 -2
  77. package/dist/solution/BookingByStep/index.js +8 -3
  78. package/dist/solution/BookingTicket/index.d.ts +8 -2
  79. package/dist/solution/BookingTicket/index.js +513 -436
  80. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  81. package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
  82. package/dist/solution/BookingTicket/utils/cartView.js +3 -1
  83. package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
  84. package/dist/solution/OrderInvoicePreview/index.js +340 -0
  85. package/dist/solution/RegisterAndLogin/config.js +54 -11
  86. package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
  87. package/dist/solution/RegisterAndLogin/index.js +1 -1
  88. package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
  89. package/dist/solution/RegisterAndLogin/utils.js +36 -16
  90. package/dist/solution/Sales/index.js +1 -1
  91. package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  92. package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
  93. package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
  94. package/dist/solution/UnifiedBookingSales/index.js +1714 -905
  95. package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
  96. package/dist/solution/VenueBooking/index.d.ts +15 -2
  97. package/dist/solution/VenueBooking/index.js +1062 -785
  98. package/dist/solution/VenueBooking/types.d.ts +2 -1
  99. package/dist/solution/VenueBooking/types.js +1 -0
  100. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  101. package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
  102. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  103. package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
  104. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  105. package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
  106. package/dist/solution/index.d.ts +1 -0
  107. package/dist/solution/index.js +2 -1
  108. package/lib/index.d.ts +2 -0
  109. package/lib/index.js +21 -1
  110. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  111. package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
  112. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  113. package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
  114. package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
  115. package/lib/model/strategy/adapter/itemRule/type.js +10 -0
  116. package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
  117. package/lib/modules/BookingContext/utils/productExtend.js +45 -2
  118. package/lib/modules/BookingContext/utils/resources.js +1 -1
  119. package/lib/modules/BusinessAvailability/index.d.ts +30 -0
  120. package/lib/modules/BusinessAvailability/index.js +146 -0
  121. package/lib/modules/Cart/index.js +4 -2
  122. package/lib/modules/Cart/types.d.ts +2 -0
  123. package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
  124. package/lib/modules/Cart/utils/cartProduct.js +39 -20
  125. package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
  126. package/lib/modules/FulfillmentTiming/index.js +359 -0
  127. package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
  128. package/lib/modules/FulfillmentTiming/types.js +5 -0
  129. package/lib/modules/OpenData/types.d.ts +14 -0
  130. package/lib/modules/Order/index.d.ts +14 -2
  131. package/lib/modules/Order/index.js +240 -38
  132. package/lib/modules/Order/localEftposState.d.ts +13 -0
  133. package/lib/modules/Order/localEftposState.js +44 -0
  134. package/lib/modules/Order/pickupTiming.d.ts +46 -0
  135. package/lib/modules/Order/pickupTiming.js +61 -0
  136. package/lib/modules/Order/types.d.ts +30 -2
  137. package/lib/modules/Order/utils.js +21 -5
  138. package/lib/modules/Payment/index.js +3 -4
  139. package/lib/modules/Product/types.d.ts +11 -0
  140. package/lib/modules/ProductList/index.js +1 -1
  141. package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
  142. package/lib/modules/ResourcePlanner/planner.js +252 -8
  143. package/lib/modules/ResourcePlanner/types.d.ts +29 -0
  144. package/lib/modules/Schedule/index.d.ts +8 -0
  145. package/lib/modules/Schedule/index.js +68 -12
  146. package/lib/modules/index.d.ts +1 -0
  147. package/lib/modules/index.js +11 -0
  148. package/lib/plugins/request.d.ts +7 -0
  149. package/lib/server/index.d.ts +1 -0
  150. package/lib/server/index.js +158 -37
  151. package/lib/server/modules/form/index.d.ts +19 -0
  152. package/lib/server/modules/form/index.js +73 -0
  153. package/lib/server/modules/form/types.d.ts +13 -0
  154. package/lib/server/modules/form/types.js +9 -0
  155. package/lib/server/modules/index.d.ts +3 -0
  156. package/lib/server/modules/index.js +15 -1
  157. package/lib/server/modules/order/index.d.ts +15 -0
  158. package/lib/server/modules/order/index.js +114 -3
  159. package/lib/server/modules/order/types.d.ts +1 -0
  160. package/lib/server/test.json +1 -1
  161. package/lib/server/utils/small-ticket.d.ts +1 -85
  162. package/lib/server/utils/small-ticket.js +9 -2305
  163. package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
  164. package/lib/shared/payment/loadPaymentMethods.js +40 -0
  165. package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  166. package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
  167. package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  168. package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
  169. package/lib/shared/receipt/small-ticket.d.ts +96 -0
  170. package/lib/shared/receipt/small-ticket.js +2546 -0
  171. package/lib/shared/receipt/templateVisibility.d.ts +23 -0
  172. package/lib/shared/receipt/templateVisibility.js +63 -0
  173. package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  174. package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
  175. package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  176. package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
  177. package/lib/solution/BaseSales/index.d.ts +39 -16
  178. package/lib/solution/BaseSales/index.js +333 -31
  179. package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
  180. package/lib/solution/BaseSales/pickupTiming.js +290 -0
  181. package/lib/solution/BaseSales/types.d.ts +11 -0
  182. package/lib/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  183. package/lib/solution/BookingByStep/index.d.ts +4 -2
  184. package/lib/solution/BookingByStep/index.js +7 -3
  185. package/lib/solution/BookingTicket/index.d.ts +8 -2
  186. package/lib/solution/BookingTicket/index.js +65 -6
  187. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  188. package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
  189. package/lib/solution/BookingTicket/utils/cartView.js +3 -1
  190. package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
  191. package/lib/solution/OrderInvoicePreview/index.js +246 -0
  192. package/lib/solution/RegisterAndLogin/config.js +57 -11
  193. package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
  194. package/lib/solution/RegisterAndLogin/index.js +9 -1
  195. package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
  196. package/lib/solution/RegisterAndLogin/utils.js +24 -17
  197. package/lib/solution/Sales/index.js +1 -1
  198. package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  199. package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
  200. package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
  201. package/lib/solution/UnifiedBookingSales/index.js +561 -74
  202. package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
  203. package/lib/solution/VenueBooking/index.d.ts +15 -2
  204. package/lib/solution/VenueBooking/index.js +243 -96
  205. package/lib/solution/VenueBooking/types.d.ts +2 -1
  206. package/lib/solution/VenueBooking/types.js +1 -0
  207. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  208. package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
  209. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  210. package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
  211. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  212. package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
  213. package/lib/solution/index.d.ts +1 -0
  214. package/lib/solution/index.js +11 -0
  215. package/package.json +1 -1
@@ -7,6 +7,7 @@ var _exportNames = {};
7
7
  exports.default = void 0;
8
8
  var _dayjs = _interopRequireDefault(require("dayjs"));
9
9
  var _decimal = _interopRequireDefault(require("decimal.js"));
10
+ var _localEftposState = require("../modules/Order/localEftposState");
10
11
  var _lodashEs = require("lodash-es");
11
12
  var _products = require("./modules/products");
12
13
  var _menu = require("./modules/menu");
@@ -16,6 +17,7 @@ var _resource = require("./modules/resource");
16
17
  var _floorPlan = require("./modules/floor-plan");
17
18
  var _types = require("./modules/floor-plan/types");
18
19
  var _payment = require("./modules/payment");
20
+ var _form = require("./modules/form");
19
21
  var _schedule2 = require("./utils/schedule");
20
22
  var _time = require("./utils/time");
21
23
  var _types2 = require("./modules/products/types");
@@ -25,6 +27,7 @@ var _types3 = require("./modules/order/types");
25
27
  var _filterOrders = require("./modules/order/utils/filterOrders");
26
28
  var _filterBookings = require("./modules/order/utils/filterBookings");
27
29
  var _smallTicket = require("./utils/small-ticket");
30
+ var _templateVisibility = require("../shared/receipt/templateVisibility");
28
31
  var _BaseSales = require("../solution/BaseSales");
29
32
  var _paymentUtils = require("../modules/Order/payment-utils");
30
33
  var _salesNotes = require("../modules/Order/salesNotes");
@@ -181,6 +184,16 @@ class Server {
181
184
  payMethods: []
182
185
  }
183
186
  },
187
+ form: {
188
+ name: 'form',
189
+ moduleClass: _form.FormModule,
190
+ moduleName: 'server_form',
191
+ version: '1.0.0',
192
+ defaultStore: {
193
+ list: [],
194
+ map: new Map()
195
+ }
196
+ },
184
197
  resource: {
185
198
  name: 'resource',
186
199
  moduleClass: _resource.ResourceModule,
@@ -645,7 +658,7 @@ class Server {
645
658
  const normalizedData = await this.normalizeCheckoutSubmitData(params.data, title);
646
659
  const numberedData = await this.ensureCheckoutOrderNumbers(normalizedData, title);
647
660
  const checkoutData = this.normalizeCheckoutCollections((0, _osPrivatePayload.stripOsPrivatePayloadFields)(this.applyCheckoutFulfillmentBuzzer(numberedData, title)));
648
- const remoteCheckoutData = this.buildRemoteCheckoutData(checkoutData, title);
661
+ const remoteCheckoutData = (0, _localEftposState.stripLocalEftposState)(this.buildRemoteCheckoutData(checkoutData, title));
649
662
  const deviceHeaders = await this.buildCheckoutDeviceHeaders(title);
650
663
  if (!this.app?.request?.post) {
651
664
  throw new Error('app.request 不可用');
@@ -783,7 +796,7 @@ class Server {
783
796
  }
784
797
  const freshPayments = freshRecord.payments;
785
798
  const mergedPayments = (0, _paymentUtils.mergeOrderPaymentListsByIdentity)(localPayments, freshPayments, {
786
- preserveUnmatchedExistingWhen: _paymentUtils.isIdentifiedPendingOrderPayment
799
+ preserveUnmatchedExistingWhen: payment => (0, _paymentUtils.isIdentifiedPendingOrderPayment)(payment) || (0, _localEftposState.isLocalFinalizedPayment)(payment)
787
800
  });
788
801
  const remoteIdentityKeys = new Set(freshPayments.flatMap(payment => (0, _paymentUtils.getOrderPaymentIdentityKeys)(payment)));
789
802
  const preservedPending = localPayments.filter(payment => (0, _paymentUtils.isIdentifiedPendingOrderPayment)(payment) && !(0, _paymentUtils.getOrderPaymentIdentityKeys)(payment).some(key => remoteIdentityKeys.has(key)));
@@ -1336,6 +1349,19 @@ class Server {
1336
1349
  method: 'post',
1337
1350
  path: '/shop/local/updateLocalPayment',
1338
1351
  handler: this.handleUpdateLocalPayment.bind(this)
1352
+ }, {
1353
+ method: 'post',
1354
+ path: '/shop/local/finalizeLocalEftposPayment',
1355
+ handler: this.handleFinalizeLocalEftposPayment.bind(this)
1356
+ }, {
1357
+ method: 'post',
1358
+ path: '/shop/local/orderPaymentReadiness',
1359
+ handler: async ({
1360
+ data
1361
+ }) => ({
1362
+ code: 200,
1363
+ data: await this.order?.getLocalOrderForPaymentReadiness(data?.sale_id)
1364
+ })
1339
1365
  }, {
1340
1366
  method: 'post',
1341
1367
  path: '/shop/machinecode/batch',
@@ -2997,7 +3023,7 @@ class Server {
2997
3023
  data: null
2998
3024
  };
2999
3025
  }
3000
- const queueKey = `${String(saleId)}:${String(paymentNumber)}`;
3026
+ const queueKey = String(saleId);
3001
3027
  return this.runLocalPaymentUpdateInQueue(queueKey, () => this.processLocalPaymentUpdate({
3002
3028
  operationId,
3003
3029
  saleId,
@@ -3009,6 +3035,42 @@ class Server {
3009
3035
  hasSurchargeInput
3010
3036
  }), requestContext);
3011
3037
  };
3038
+ handleFinalizeLocalEftposPayment = async ({
3039
+ data
3040
+ }) => {
3041
+ const {
3042
+ sale_id: saleId,
3043
+ payment_number: paymentNumber,
3044
+ result,
3045
+ failed_transaction_numbers: numbers = []
3046
+ } = data || {};
3047
+ if (!saleId || !paymentNumber || !Array.isArray(numbers) || numbers.some(number => typeof number !== 'string' || !number.trim()) || result !== 'failed' && result !== 'not_started' || result === 'failed' && numbers.length === 0 || result === 'not_started' && numbers.length !== 0) {
3048
+ return {
3049
+ code: 400,
3050
+ status: false,
3051
+ message: '缺少明确的支付结果或交易编号',
3052
+ data: null
3053
+ };
3054
+ }
3055
+ return this.runLocalPaymentUpdateInQueue(String(saleId), async () => {
3056
+ if (!this.order) throw new Error('Order 模块未注册');
3057
+ const finalized = await this.order.finalizeLocalEftposPayment({
3058
+ saleId,
3059
+ paymentNumber,
3060
+ result,
3061
+ failedTransactionNumbers: [...new Set(numbers)]
3062
+ });
3063
+ return {
3064
+ code: 200,
3065
+ status: true,
3066
+ local_only: true,
3067
+ data: finalized
3068
+ };
3069
+ }, {
3070
+ sale_id: saleId,
3071
+ payment_number: paymentNumber
3072
+ });
3073
+ };
3012
3074
  async runLocalPaymentUpdateInQueue(key, task, context) {
3013
3075
  const queuedAt = Date.now();
3014
3076
  const hasPreviousTask = this.localPaymentUpdateQueues.has(key);
@@ -3768,7 +3830,7 @@ class Server {
3768
3830
  device_id: debugDeviceId,
3769
3831
  payload: {
3770
3832
  backendPath: params.backendPath,
3771
- data: params.data,
3833
+ data: (0, _localEftposState.stripLocalEftposState)(params.data),
3772
3834
  invoice: this.normalizePrintInvoiceLayoutConfig(params.invoiceLayoutConfig),
3773
3835
  template_settings: this.normalizePrintInvoiceTemplateSettings(params.invoiceTemplateSettings),
3774
3836
  external_sale_number: params.data?.external_sale_number,
@@ -3851,7 +3913,8 @@ class Server {
3851
3913
  }
3852
3914
  const printableOrder = await this.withLocalSmallTicketData(params.order, {
3853
3915
  requireFullyPaid: params.requireFullyPaid,
3854
- invoiceTemplateSettings: params.invoiceTemplateSettings
3916
+ invoiceTemplateSettings: params.invoiceTemplateSettings,
3917
+ applyTemplateVisibility: true
3855
3918
  });
3856
3919
  if (!(0, _smallTicket.hasSmallTicketData)(printableOrder.payment_info?.small_ticket_data)) {
3857
3920
  return {
@@ -3873,9 +3936,11 @@ class Server {
3873
3936
  invoiceLayoutConfig: params.invoiceLayoutConfig,
3874
3937
  invoiceTemplateSettings: params.invoiceTemplateSettings
3875
3938
  });
3939
+ // Receipt visibility belongs to this output only. Do not return a filtered
3940
+ // snapshot to callers that may retain the order for later sync or reprints.
3876
3941
  return {
3877
3942
  printed: true,
3878
- order: printableOrder
3943
+ order: (0, _templateVisibility.requiresInvoiceDataFiltering)(params.invoiceTemplateSettings) ? params.order : printableOrder
3879
3944
  };
3880
3945
  }
3881
3946
  shouldLookupLocalPrintOrder(input) {
@@ -4084,7 +4149,10 @@ class Server {
4084
4149
  small_ticket_data_flag: 1,
4085
4150
  payment_info: paymentInfo
4086
4151
  }, {
4087
- locales: this.normalizeRequestedReceiptLocales(input.locales)
4152
+ locales: this.normalizeRequestedReceiptLocales(input.locales),
4153
+ invoiceTemplateSettings: input.template_settings === undefined ? undefined : this.normalizePrintInvoiceTemplateSettings(input.template_settings),
4154
+ applyTemplateVisibility: true,
4155
+ includeReceiptKeys: input.template_settings !== undefined
4088
4156
  });
4089
4157
  const smallTicketData = rebuiltOrder.payment_info?.small_ticket_data;
4090
4158
  if (!(0, _smallTicket.hasSmallTicketData)(smallTicketData)) {
@@ -4102,7 +4170,17 @@ class Server {
4102
4170
  status: true,
4103
4171
  message: '',
4104
4172
  data: {
4105
- small_ticket_data: smallTicketData
4173
+ small_ticket_data: smallTicketData,
4174
+ template_visibility_applied: true,
4175
+ // These products and currency settings are the exact source used for
4176
+ // this receipt, not the potentially newer active tempOrder.
4177
+ source: {
4178
+ ...rebuiltOrder,
4179
+ payment_info: {
4180
+ ...(rebuiltOrder.payment_info || {}),
4181
+ small_ticket_data: undefined
4182
+ }
4183
+ }
4106
4184
  }
4107
4185
  };
4108
4186
  } catch (error) {
@@ -4307,6 +4385,16 @@ class Server {
4307
4385
  backendPath,
4308
4386
  title
4309
4387
  } = params;
4388
+ const lookup = params.data?.order_id || params.data?.external_sale_number;
4389
+ const localOrder = lookup && (await this.order?.getLocalOrderByLookup?.(lookup));
4390
+ if ((0, _localEftposState.requiresLocalPaymentRefresh)(params.data) || (0, _localEftposState.requiresLocalPaymentRefresh)(localOrder)) {
4391
+ return {
4392
+ code: 409,
4393
+ status: false,
4394
+ message: _localEftposState.PAYMENT_REFRESH_MESSAGE,
4395
+ data: null
4396
+ };
4397
+ }
4310
4398
  const extractedInvoice = this.extractInvoiceLayoutConfig(params.data, {
4311
4399
  includePublicInvoice: true
4312
4400
  });
@@ -4343,15 +4431,24 @@ class Server {
4343
4431
  });
4344
4432
  if (pendingResult?.status === true) {
4345
4433
  const pendingOrder = pendingResult.data;
4346
- if (pendingOrder && this.shouldBuildSmallTicketData(checkoutData) && this.isSalesOrderFullyPaid(pendingOrder) && this.shouldAutoPrintCheckoutReceipt()) {
4347
- await this.dispatchLocalReceiptPrint({
4348
- checkoutData,
4349
- order: pendingOrder,
4350
- response: pendingResult,
4351
- requireFullyPaid: true,
4352
- invoiceLayoutConfig,
4353
- invoiceTemplateSettings
4354
- });
4434
+ if (pendingOrder && this.shouldBuildSmallTicketData(checkoutData, invoiceTemplateSettings) && this.isSalesOrderFullyPaid(pendingOrder) && this.shouldAutoPrintCheckoutReceipt()) {
4435
+ try {
4436
+ await this.dispatchLocalReceiptPrint({
4437
+ checkoutData,
4438
+ order: pendingOrder,
4439
+ response: pendingResult,
4440
+ requireFullyPaid: true,
4441
+ invoiceLayoutConfig,
4442
+ invoiceTemplateSettings
4443
+ });
4444
+ } catch (error) {
4445
+ // The sale is already persisted. A failed receipt must not cancel its
4446
+ // sync task or send an unfiltered fallback to the printer.
4447
+ pendingResult.receipt_print_error = this.getUnknownErrorMessage(error);
4448
+ this.logError(`${title}: 小票生成失败,订单仍继续同步`, {
4449
+ error: pendingResult.receipt_print_error
4450
+ });
4451
+ }
4355
4452
  }
4356
4453
  await this.dispatchCheckoutSyncTask({
4357
4454
  backendPath,
@@ -4409,16 +4506,24 @@ class Server {
4409
4506
  }
4410
4507
  const response = this.withSyncedOrderIdInCheckoutResponse(syncResult.normalizedResponse, syncResult.syncedOrder);
4411
4508
  const syncedOrder = syncResult.syncedOrder;
4412
- if (syncedOrder && this.shouldBuildSmallTicketData(syncResult.checkoutData) && this.isSalesOrderFullyPaid(syncedOrder)) {
4413
- await this.dispatchLocalReceiptPrint({
4414
- checkoutData: syncResult.checkoutData,
4415
- order: syncedOrder,
4416
- response: syncResult.normalizedResponse,
4417
- requireFullyPaid: true,
4418
- invoiceLayoutConfig,
4419
- invoiceTemplateSettings
4420
- // print_all 的 type=0 是收据打印;不要沿用同步成功后的券/手环打印 type=99。
4421
- });
4509
+ if (syncedOrder && this.shouldBuildSmallTicketData(syncResult.checkoutData, invoiceTemplateSettings) && this.isSalesOrderFullyPaid(syncedOrder)) {
4510
+ try {
4511
+ await this.dispatchLocalReceiptPrint({
4512
+ checkoutData: syncResult.checkoutData,
4513
+ order: syncedOrder,
4514
+ response: syncResult.normalizedResponse,
4515
+ requireFullyPaid: true,
4516
+ invoiceLayoutConfig,
4517
+ invoiceTemplateSettings
4518
+ });
4519
+ } catch (error) {
4520
+ // Checkout already succeeded remotely; report the receipt failure
4521
+ // separately instead of implying that payment/order creation failed.
4522
+ response.receipt_print_error = this.getUnknownErrorMessage(error);
4523
+ this.logError(`${title}: 小票生成失败,订单已同步`, {
4524
+ error: response.receipt_print_error
4525
+ });
4526
+ }
4422
4527
  }
4423
4528
  return response;
4424
4529
  } catch (error) {
@@ -4627,10 +4732,12 @@ class Server {
4627
4732
  if (this.core.context?.getPlatform?.() !== 'android') return true;
4628
4733
  return this.app?.storage?.getStorage?.(AUTO_PRINT_STORAGE_KEY) !== 'false';
4629
4734
  }
4630
- shouldBuildSmallTicketData(order) {
4735
+ shouldBuildSmallTicketData(order, invoiceTemplateSettings) {
4631
4736
  if (!order || typeof order !== 'object') return false;
4632
- // if (hasSmallTicketData(order.payment_info?.small_ticket_data)) return false;
4633
- return Number(order.small_ticket_data_flag ?? order.smallTicketDataFlag ?? 0) === 1;
4737
+ const flag = order.small_ticket_data_flag ?? order.smallTicketDataFlag;
4738
+ // A synced order can omit the generation flag; required display filtering
4739
+ // still rebuilds its output. An explicit 0 retains the no-auto-print intent.
4740
+ return Number(flag ?? 0) === 1 || flag == null && (0, _templateVisibility.requiresInvoiceDataFiltering)(invoiceTemplateSettings);
4634
4741
  }
4635
4742
  shouldPrintSyncedOrder(params) {
4636
4743
  if (this.hasPaymentStatus(params.syncedOrder)) {
@@ -4934,7 +5041,8 @@ class Server {
4934
5041
  }
4935
5042
  }
4936
5043
  async withLocalSmallTicketData(order, options) {
4937
- if (!this.shouldBuildSmallTicketData(order)) return order;
5044
+ const mustApplyVisibility = options?.applyTemplateVisibility === true && (0, _templateVisibility.requiresInvoiceDataFiltering)(options.invoiceTemplateSettings);
5045
+ if (!this.shouldBuildSmallTicketData(order) && !mustApplyVisibility) return order;
4938
5046
  if (options?.requireFullyPaid && !this.isSalesOrderFullyPaid(order)) return order;
4939
5047
  try {
4940
5048
  const normalizedCollections = (0, _orderCollectionIdentity.normalizeOrderCollections)(order, {
@@ -4958,7 +5066,9 @@ class Server {
4958
5066
  order: enrichedOrder,
4959
5067
  shopInfo: this.getSmallTicketShopInfo(),
4960
5068
  locales: [...(0, _OpenData.resolveInvoiceReceiptLocales)(options?.invoiceTemplateSettings), ...(options?.locales || [])],
4961
- productMap
5069
+ productMap,
5070
+ includeReceiptKeys: options?.includeReceiptKeys,
5071
+ templateSettings: options?.applyTemplateVisibility ? options.invoiceTemplateSettings : undefined
4962
5072
  });
4963
5073
  return {
4964
5074
  ...enrichedOrder,
@@ -4971,6 +5081,7 @@ class Server {
4971
5081
  this.logError('withLocalSmallTicketData: 生成本地小票数据失败', {
4972
5082
  error: error instanceof Error ? error.message : String(error)
4973
5083
  });
5084
+ if (mustApplyVisibility) throw error;
4974
5085
  return order;
4975
5086
  }
4976
5087
  }
@@ -5032,7 +5143,15 @@ class Server {
5032
5143
  order: null
5033
5144
  };
5034
5145
  }
5035
- await this.order.upsertOrdersFromRemote([fresh]);
5146
+ const localBeforeRefresh = this.order.getLocalOrderFromMemoryByLookup?.(lookup) || (this.shouldForceRemoteSalesDetail(data) ? await this.order.getLocalOrderByLookup(lookup) : null);
5147
+ if ((0, _localEftposState.requiresLocalPaymentRefresh)(localBeforeRefresh)) {
5148
+ if (String(fresh.order_id) !== String(localBeforeRefresh.order_id)) {
5149
+ throw new Error('远端订单身份不匹配,请重新刷新');
5150
+ }
5151
+ await this.order.completeLocalPaymentRefresh(fresh);
5152
+ } else {
5153
+ await this.order.upsertOrdersFromRemote([fresh]);
5154
+ }
5036
5155
  let savedOrder = await this.order.getLocalOrderByLookup(lookup);
5037
5156
  if (!savedOrder && fresh.order_id !== undefined && fresh.order_id !== null && String(fresh.order_id) !== String(lookup)) {
5038
5157
  savedOrder = await this.order.getLocalOrderByLookup(fresh.order_id);
@@ -5349,7 +5468,7 @@ class Server {
5349
5468
  }
5350
5469
  buildOrderSalesDetailBackendPath(lookup, data) {
5351
5470
  const rawWith = data && typeof data === 'object' ? data.with : undefined;
5352
- const withFields = Array.isArray(rawWith) && rawWith.length > 0 ? rawWith : ['products', 'scheduleEvents'];
5471
+ const withFields = Array.isArray(rawWith) && rawWith.length > 0 ? rawWith : ['all'];
5353
5472
  const searchParams = new URLSearchParams();
5354
5473
  withFields.forEach(field => {
5355
5474
  if (field === undefined || field === null || field === '') return;
@@ -5750,9 +5869,11 @@ class Server {
5750
5869
 
5751
5870
  // 使用 filterOrders 进行过滤、排序、分页
5752
5871
  const result = (0, _filterOrders.filterOrders)(rawList, data);
5753
- result.list.forEach(order => {
5754
- order.payments = order.payments?.filter(payment => !(0, _paymentUtils.isPendingOrderPayment)(payment));
5755
- });
5872
+ // filterOrders retains store object references; hide pending only in the list response.
5873
+ result.list = result.list.map(order => ({
5874
+ ...order,
5875
+ payments: order.payments?.filter(payment => !(0, _paymentUtils.isPendingOrderPayment)(payment))
5876
+ }));
5756
5877
  this.logInfo('computeOrderQueryResult: 过滤结果', {
5757
5878
  rawCount: rawList.length,
5758
5879
  filteredCount: result.count,
@@ -0,0 +1,19 @@
1
+ import { BaseModule } from '../../../modules/BaseModule';
2
+ import type { Module, ModuleOptions, PisellCore } from '../../../types';
3
+ /**
4
+ * 表单定义缓存。数据源负责 HTTP 与 Ably 订阅;本模块仅向 OS 消费方公开只读标题映射。
5
+ */
6
+ export declare class FormModule extends BaseModule implements Module {
7
+ protected defaultName: string;
8
+ protected defaultVersion: string;
9
+ private store;
10
+ private dataSource;
11
+ private refreshTimer?;
12
+ initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
13
+ preload(): Promise<void>;
14
+ getTitleMap(): Record<string, Record<string, string> | string>;
15
+ private scheduleRefresh;
16
+ private refresh;
17
+ destroy(): Promise<void>;
18
+ }
19
+ export default FormModule;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.FormModule = void 0;
7
+ var _BaseModule = require("../../../modules/BaseModule");
8
+ var _types = require("./types");
9
+ const FORM_LIST_URL = '/shop/form/simple/list';
10
+
11
+ /**
12
+ * 表单定义缓存。数据源负责 HTTP 与 Ably 订阅;本模块仅向 OS 消费方公开只读标题映射。
13
+ */
14
+ class FormModule extends _BaseModule.BaseModule {
15
+ defaultName = 'form';
16
+ defaultVersion = '1.0.0';
17
+ store;
18
+ dataSource;
19
+ refreshTimer;
20
+ async initialize(core, options) {
21
+ this.core = core;
22
+ const initialStore = options?.store;
23
+ this.store = {
24
+ list: Array.isArray(initialStore?.list) ? initialStore.list : [],
25
+ map: initialStore?.map instanceof Map ? initialStore.map : new Map()
26
+ };
27
+ const FormDataSource = this.core.serverOptions?.All_DATA_SOURCES?.FormDataSource;
28
+ this.dataSource = FormDataSource ? new FormDataSource() : undefined;
29
+ if (this.dataSource) {
30
+ await this.dataSource.run({
31
+ pubsub: {
32
+ callback: () => this.scheduleRefresh()
33
+ }
34
+ });
35
+ }
36
+ }
37
+ async preload() {
38
+ await this.refresh();
39
+ }
40
+ getTitleMap() {
41
+ return this.store.list.reduce((result, item) => {
42
+ if (item.id !== undefined && item.id !== null && item.title) result[String(item.id)] = item.title;
43
+ return result;
44
+ }, {});
45
+ }
46
+ scheduleRefresh() {
47
+ if (this.refreshTimer) clearTimeout(this.refreshTimer);
48
+ this.refreshTimer = setTimeout(() => void this.refresh(), 300);
49
+ }
50
+ async refresh() {
51
+ try {
52
+ const response = this.dataSource ? await this.dataSource.run({
53
+ http: {
54
+ url: FORM_LIST_URL
55
+ }
56
+ }) : await this.core.getPlugin('request')?.get(FORM_LIST_URL);
57
+ const data = response?.data;
58
+ const list = Array.isArray(data) ? data : data?.list || data?.data || [];
59
+ if (!Array.isArray(list)) return;
60
+ this.store.list = list;
61
+ this.store.map = new Map(this.store.list.map(item => [String(item.id), item]));
62
+ await this.core.effects.emit(_types.FormHooks.onChanged, this.getTitleMap());
63
+ } catch {
64
+ // 接口尚未发布或临时失败时保留现有缓存,展示层会回退订单历史标题。
65
+ }
66
+ }
67
+ async destroy() {
68
+ if (this.refreshTimer) clearTimeout(this.refreshTimer);
69
+ this.dataSource?.destroy?.();
70
+ }
71
+ }
72
+ exports.FormModule = FormModule;
73
+ var _default = exports.default = FormModule;
@@ -0,0 +1,13 @@
1
+ export interface FormDefinition {
2
+ id: string | number;
3
+ code?: string;
4
+ title?: Record<string, string> | string;
5
+ [key: string]: unknown;
6
+ }
7
+ export interface FormState {
8
+ list: FormDefinition[];
9
+ map: Map<string, FormDefinition>;
10
+ }
11
+ export declare const FormHooks: {
12
+ readonly onChanged: "form:onChanged";
13
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FormHooks = void 0;
7
+ const FormHooks = exports.FormHooks = {
8
+ onChanged: 'form:onChanged'
9
+ };
@@ -24,4 +24,7 @@ export { FloorPlanHooks } from './floor-plan/types';
24
24
  export { ResourceModule, resourceModule } from './resource';
25
25
  export type { ResourceState, ResourceData, ResourceId, ResourceBooking, ResourcePageQuery, ResourcePageResult, QueryOptions, ScheduleEventResource, } from './resource';
26
26
  export { ResourceHooks } from './resource';
27
+ export { FormModule } from './form';
28
+ export type { FormDefinition, FormState } from './form/types';
29
+ export { FormHooks } from './form/types';
27
30
  export type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, } from '../types';
@@ -15,6 +15,18 @@ Object.defineProperty(exports, "FloorPlanModule", {
15
15
  return _floorPlan.FloorPlanModule;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "FormHooks", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _types6.FormHooks;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "FormModule", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _form.FormModule;
28
+ }
29
+ });
18
30
  Object.defineProperty(exports, "MenuHooks", {
19
31
  enumerable: true,
20
32
  get: function () {
@@ -105,4 +117,6 @@ var _types4 = require("./order/types");
105
117
  var _payment = require("./payment");
106
118
  var _floorPlan = require("./floor-plan");
107
119
  var _types5 = require("./floor-plan/types");
108
- var _resource = require("./resource");
120
+ var _resource = require("./resource");
121
+ var _form = require("./form");
122
+ var _types6 = require("./form/types");
@@ -105,6 +105,8 @@ export declare class OrderModule extends BaseModule implements Module {
105
105
  getOrderByOrderId(orderId: OrderId): OrderData | undefined;
106
106
  private buildLocalPaymentOrderLogContext;
107
107
  getLocalOrderFromMemoryByLookup(lookup: OrderId): OrderData | null;
108
+ /** Read-only payment gate lookup; never hydrate the whole order list on a miss. */
109
+ getLocalOrderForPaymentReadiness(lookup: OrderId): Promise<OrderData | null>;
108
110
  getLocalOrderByLookup(lookup: OrderId, options?: {
109
111
  operationId?: string;
110
112
  }): Promise<OrderData | null>;
@@ -123,11 +125,24 @@ export declare class OrderModule extends BaseModule implements Module {
123
125
  paymentNumber: OrderId;
124
126
  operationId?: string;
125
127
  updates: Record<string, any>;
128
+ finalizeUnsuccessful?: boolean;
126
129
  }): Promise<{
127
130
  order: OrderData;
128
131
  payment: Record<string, any>;
129
132
  previousPayment: Record<string, any>;
130
133
  } | null>;
134
+ finalizeLocalEftposPayment(params: {
135
+ saleId: OrderId;
136
+ paymentNumber: OrderId;
137
+ result: 'failed' | 'not_started';
138
+ failedTransactionNumbers: string[];
139
+ }): Promise<{
140
+ order: OrderData;
141
+ payment: Record<string, any>;
142
+ previousPayment: Record<string, any>;
143
+ } | null>;
144
+ /** Only a successful full detail GET may release the persisted payment gate. */
145
+ completeLocalPaymentRefresh(fresh: OrderData): Promise<OrderData>;
131
146
  loadOrdersByServer(options?: {
132
147
  trigger?: string;
133
148
  }): Promise<OrderData[]>;