@pisell/pisellos 0.10.28 → 0.10.29

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 (84) hide show
  1. package/dist/core/index.d.ts +7 -0
  2. package/dist/core/index.js +108 -65
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.js +13 -2
  4. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  5. package/dist/modules/Discount/index.js +4 -1
  6. package/dist/modules/Discount/types.d.ts +14 -4
  7. package/dist/modules/Order/index.d.ts +4 -2
  8. package/dist/modules/Order/index.js +89 -16
  9. package/dist/modules/Order/types.d.ts +13 -0
  10. package/dist/modules/Order/utils.d.ts +17 -2
  11. package/dist/modules/Order/utils.js +133 -27
  12. package/dist/modules/Quotation/index.d.ts +6 -0
  13. package/dist/modules/Quotation/index.js +77 -25
  14. package/dist/modules/ResourcePlanner/planner.js +14 -4
  15. package/dist/modules/ResourcePlanner/types.d.ts +2 -0
  16. package/dist/plugins/request.d.ts +1 -0
  17. package/dist/server/index.d.ts +13 -2
  18. package/dist/server/index.js +1531 -1230
  19. package/dist/server/modules/floor-plan/index.d.ts +4 -0
  20. package/dist/server/modules/floor-plan/index.js +240 -98
  21. package/dist/server/modules/menu/index.js +48 -23
  22. package/dist/server/modules/order/index.d.ts +17 -7
  23. package/dist/server/modules/order/index.js +419 -207
  24. package/dist/server/modules/order/types.d.ts +50 -0
  25. package/dist/server/modules/order/types.js +2 -0
  26. package/dist/server/modules/products/index.d.ts +10 -4
  27. package/dist/server/modules/products/index.js +177 -84
  28. package/dist/server/modules/resource/index.js +21 -13
  29. package/dist/server/utils/product.d.ts +1 -1
  30. package/dist/server/utils/product.js +186 -22
  31. package/dist/server/utils/small-ticket.d.ts +4 -1
  32. package/dist/server/utils/small-ticket.js +482 -100
  33. package/dist/solution/BaseSales/index.d.ts +3 -3
  34. package/dist/solution/BaseSales/index.js +171 -198
  35. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  36. package/dist/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  37. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  38. package/dist/solution/BookingByStep/index.d.ts +2 -2
  39. package/dist/solution/Sales/index.d.ts +7 -0
  40. package/dist/solution/Sales/index.js +87 -31
  41. package/dist/solution/UnifiedBookingSales/index.d.ts +2 -2
  42. package/dist/solution/UnifiedBookingSales/index.js +38 -21
  43. package/lib/core/index.d.ts +7 -0
  44. package/lib/core/index.js +20 -2
  45. package/lib/model/strategy/adapter/dataVariant/evaluator.js +12 -2
  46. package/lib/modules/Discount/index.js +4 -1
  47. package/lib/modules/Discount/types.d.ts +14 -4
  48. package/lib/modules/Order/index.d.ts +4 -2
  49. package/lib/modules/Order/index.js +69 -1
  50. package/lib/modules/Order/types.d.ts +13 -0
  51. package/lib/modules/Order/utils.d.ts +17 -2
  52. package/lib/modules/Order/utils.js +131 -18
  53. package/lib/modules/Quotation/index.d.ts +6 -0
  54. package/lib/modules/Quotation/index.js +52 -8
  55. package/lib/modules/ResourcePlanner/planner.js +9 -1
  56. package/lib/modules/ResourcePlanner/types.d.ts +2 -0
  57. package/lib/plugins/request.d.ts +1 -0
  58. package/lib/server/index.d.ts +13 -2
  59. package/lib/server/index.js +210 -19
  60. package/lib/server/modules/floor-plan/index.d.ts +4 -0
  61. package/lib/server/modules/floor-plan/index.js +60 -7
  62. package/lib/server/modules/menu/index.js +26 -4
  63. package/lib/server/modules/order/index.d.ts +17 -7
  64. package/lib/server/modules/order/index.js +194 -57
  65. package/lib/server/modules/order/types.d.ts +50 -0
  66. package/lib/server/modules/order/types.js +1 -0
  67. package/lib/server/modules/products/index.d.ts +10 -4
  68. package/lib/server/modules/products/index.js +93 -23
  69. package/lib/server/modules/resource/index.js +12 -2
  70. package/lib/server/utils/product.d.ts +1 -1
  71. package/lib/server/utils/product.js +163 -3
  72. package/lib/server/utils/small-ticket.d.ts +4 -1
  73. package/lib/server/utils/small-ticket.js +448 -75
  74. package/lib/solution/BaseSales/index.d.ts +3 -3
  75. package/lib/solution/BaseSales/index.js +9 -14
  76. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  77. package/lib/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  78. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  79. package/lib/solution/BookingByStep/index.d.ts +2 -2
  80. package/lib/solution/Sales/index.d.ts +7 -0
  81. package/lib/solution/Sales/index.js +48 -3
  82. package/lib/solution/UnifiedBookingSales/index.d.ts +2 -2
  83. package/lib/solution/UnifiedBookingSales/index.js +19 -3
  84. package/package.json +1 -1
@@ -22,9 +22,12 @@ const LABELS = {
22
22
  pickUpTime: 'Pick-up time',
23
23
  asap: 'ASAP',
24
24
  cash: 'Cash',
25
+ cashReceived: 'Cash received',
26
+ changeDue: 'Change due',
25
27
  eftpos: 'Eftpos',
26
28
  wallet: 'Wallet',
27
29
  giftCard: 'Gift card',
30
+ balance: 'Balance',
28
31
  remainingAmount: 'Remaining amount',
29
32
  redeemPoints: 'Redeem points',
30
33
  remainingPoints: 'Remaining points',
@@ -32,9 +35,12 @@ const LABELS = {
32
35
  orderDiscount: 'Order discount',
33
36
  manualDiscount: 'Manual discount',
34
37
  payProcessingFee: 'Pay processing fee',
38
+ surchargeIncluded: 'Surcharge(Included)',
35
39
  rounding: 'Rounding',
36
40
  gross: 'Gross',
37
- tare: 'Tare'
41
+ tare: 'Tare',
42
+ handoverTime: 'Handover time',
43
+ refund: 'Refund'
38
44
  },
39
45
  zh_CN: {
40
46
  contactName: '联系人姓名',
@@ -48,9 +54,12 @@ const LABELS = {
48
54
  pickUpTime: '取餐时间',
49
55
  asap: '尽快',
50
56
  cash: '现金支付',
57
+ cashReceived: '收取现金',
58
+ changeDue: '找零',
51
59
  eftpos: '刷卡支付',
52
60
  wallet: '钱包支付',
53
61
  giftCard: '礼品卡',
62
+ balance: '余额',
54
63
  remainingAmount: '剩余金额',
55
64
  redeemPoints: '本次使用积分',
56
65
  remainingPoints: '剩余积分',
@@ -58,9 +67,12 @@ const LABELS = {
58
67
  orderDiscount: '整单折扣',
59
68
  manualDiscount: '手动折扣',
60
69
  payProcessingFee: '支付手续费',
70
+ surchargeIncluded: '手续费(已含)',
61
71
  rounding: '抹零',
62
72
  gross: '重量',
63
- tare: '去皮'
73
+ tare: '去皮',
74
+ handoverTime: '交付时间',
75
+ refund: '退款'
64
76
  },
65
77
  zh_HK: {
66
78
  contactName: '聯絡人姓名',
@@ -74,9 +86,12 @@ const LABELS = {
74
86
  pickUpTime: '取餐時間',
75
87
  asap: '盡快',
76
88
  cash: '現金支付',
89
+ cashReceived: '收取現金',
90
+ changeDue: '找零',
77
91
  eftpos: '刷卡支付',
78
92
  wallet: '錢包支付',
79
93
  giftCard: '禮品卡',
94
+ balance: '餘額',
80
95
  remainingAmount: '剩餘金額',
81
96
  redeemPoints: '本次使用積分',
82
97
  remainingPoints: '剩餘積分',
@@ -84,9 +99,12 @@ const LABELS = {
84
99
  orderDiscount: '整單折扣',
85
100
  manualDiscount: '手動折扣',
86
101
  payProcessingFee: '支付手續費',
102
+ surchargeIncluded: '手續費(已含)',
87
103
  rounding: '抹零',
88
104
  gross: '重量',
89
- tare: '去皮'
105
+ tare: '去皮',
106
+ handoverTime: '交付時間',
107
+ refund: '退款'
90
108
  },
91
109
  ja: {
92
110
  contactName: '連絡先名',
@@ -103,6 +121,7 @@ const LABELS = {
103
121
  eftpos: 'カード',
104
122
  wallet: 'ウォレット',
105
123
  giftCard: 'ギフトカード',
124
+ balance: '残高',
106
125
  remainingAmount: '残高',
107
126
  redeemPoints: '利用ポイント',
108
127
  remainingPoints: '残りポイント',
@@ -112,7 +131,11 @@ const LABELS = {
112
131
  payProcessingFee: '決済手数料',
113
132
  rounding: '端数調整',
114
133
  gross: '総重量',
115
- tare: '風袋'
134
+ tare: '風袋',
135
+ handoverTime: '受け渡し時間',
136
+ refund: '返金',
137
+ cashReceived: 'お預かり',
138
+ changeDue: 'お釣り'
116
139
  },
117
140
  pt: {
118
141
  contactName: 'Nome de contato',
@@ -129,6 +152,7 @@ const LABELS = {
129
152
  eftpos: 'Cartão',
130
153
  wallet: 'Carteira',
131
154
  giftCard: 'Cartão-presente',
155
+ balance: 'Saldo',
132
156
  remainingAmount: 'Saldo restante',
133
157
  redeemPoints: 'Pontos utilizados',
134
158
  remainingPoints: 'Pontos restantes',
@@ -138,7 +162,11 @@ const LABELS = {
138
162
  payProcessingFee: 'Taxa de processamento',
139
163
  rounding: 'Arredondamento',
140
164
  gross: 'Peso bruto',
141
- tare: 'Tara'
165
+ tare: 'Tara',
166
+ handoverTime: 'Hora de entrega',
167
+ refund: 'Reembolso',
168
+ cashReceived: 'Dinheiro recebido',
169
+ changeDue: 'Troco'
142
170
  }
143
171
  };
144
172
  function buildSmallTicketData(params) {
@@ -169,11 +197,15 @@ function buildLocaleData(params) {
169
197
  const products = buildProducts(order, locale, productMap);
170
198
  const summary = getSummary(order);
171
199
  const currencySymbol = getCurrencySymbol(order, shopInfo);
200
+ const financials = resolveReceiptFinancials(order, summary);
201
+ const delivery = buildDelivery(order, locale);
172
202
  return {
173
203
  base_data: buildBaseData({
174
204
  order,
175
205
  shopInfo,
176
- locale
206
+ locale,
207
+ currencySymbol,
208
+ financials
177
209
  }),
178
210
  products,
179
211
  fees: buildFees({
@@ -182,11 +214,14 @@ function buildLocaleData(params) {
182
214
  locale,
183
215
  products,
184
216
  summary,
185
- currencySymbol
217
+ currencySymbol,
218
+ financials
186
219
  }),
187
220
  customer: buildCustomer(order, locale),
188
221
  appointment: buildAppointment(order, locale),
189
- // delivery: buildDelivery(order, locale),
222
+ ...(delivery.length ? {
223
+ delivery
224
+ } : {}),
190
225
  resources: buildResources(order, locale),
191
226
  payment_data: buildPaymentData({
192
227
  order,
@@ -200,7 +235,11 @@ function buildLocaleData(params) {
200
235
  }),
201
236
  tickets: Array.isArray(order.tickets) ? order.tickets : [],
202
237
  source_shop: [],
203
- refund_data: [],
238
+ refund_data: buildRefundData({
239
+ order,
240
+ locale,
241
+ currencySymbol
242
+ }),
204
243
  expend_data: []
205
244
  };
206
245
  }
@@ -208,7 +247,9 @@ function buildBaseData(params) {
208
247
  const {
209
248
  order,
210
249
  shopInfo,
211
- locale
250
+ locale,
251
+ currencySymbol,
252
+ financials
212
253
  } = params;
213
254
  const orderNumber = stringify(order.buzzer || order.shop_full_order_number);
214
255
  return {
@@ -219,7 +260,13 @@ function buildBaseData(params) {
219
260
  shop_tax_number: stringify(shopInfo.tax_number || order.shop_tax_number),
220
261
  shop_phone: stringify(shopInfo.phone || order.shop_phone),
221
262
  shop_address: stringify(shopInfo.receipt_address || shopInfo.address || buildShopAddress(shopInfo) || order.shop_address),
222
- original_payment_status: stringify(order.payment_status),
263
+ original_payment_status: financials.paymentStatus,
264
+ payment_status: financials.paymentStatus,
265
+ total_amount: formatMoney(financials.totalAmount, currencySymbol),
266
+ has_pay: formatMoney(financials.netPaymentApplied, currencySymbol),
267
+ ...(isPresentId(financials.amountGap) ? {
268
+ amount_gap: formatMoney(financials.amountGap, currencySymbol)
269
+ } : {}),
223
270
  is_repeat: 0,
224
271
  buzzer: stringify(order.buzzer || order.pickup_number || order.metadata?.buzzer),
225
272
  order_no: orderNumber,
@@ -269,11 +316,16 @@ function buildProducts(order, locale, productMap) {
269
316
  quantity,
270
317
  originalPrice
271
318
  });
319
+ const productNote = resolveProductNote(product, locale);
320
+ const basePrice = resolveProductBasePrice(product);
272
321
  return {
273
322
  product_title: productTitle,
274
323
  product_quantity: quantity,
275
324
  selling_price: formatMoney(sellingPrice, currencySymbol),
276
325
  original_price: formatMoney(originalPrice, currencySymbol),
326
+ ...(isPresentId(basePrice) ? {
327
+ base_price: formatMoney(basePrice, currencySymbol)
328
+ } : {}),
277
329
  total_original_price: formatMoney(new _decimal.default(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
278
330
  extension_list: extensionList,
279
331
  ...(isPresentId(productUid) ? {
@@ -282,20 +334,31 @@ function buildProducts(order, locale, productMap) {
282
334
  ...(isPresentId(bookingUid) ? {
283
335
  booking_uid: bookingUid
284
336
  } : {}),
337
+ ...(productNote ? {
338
+ product_note: productNote
339
+ } : {}),
285
340
  ...(options.length ? {
286
341
  options
287
342
  } : {}),
288
343
  ...(resolvedVariant ? {
289
344
  variant: resolvedVariant
290
345
  } : {}),
291
- ...(Array.isArray(product.combinations) ? {
292
- combinations: product.combinations
346
+ ...(Array.isArray(product.combinations) && product.combinations.length ? {
347
+ combinations: normalizeExistingCombinations(product.combinations, locale)
293
348
  } : combinations.length ? {
294
349
  combinations
295
350
  } : {})
296
351
  };
297
352
  });
298
353
  }
354
+ function resolveProductBasePrice(product) {
355
+ const metadata = product.metadata || {};
356
+ const origin = product._origin || metadata.origin || {};
357
+ const variantId = product.product_variant_id ?? product.variant_id;
358
+ const variant = Array.isArray(origin.variant) && isPresentId(variantId) ? origin.variant.find(item => isSameId(item?.id, variantId)) : undefined;
359
+ const isV2 = metadata.price_schema_version === 2 || metadata.price_schema_version === '2';
360
+ return firstPresentValue(metadata.source_product_price, variant?.price, product._origin?.price, product._origin?.base_price, !isV2 ? metadata.main_product_original_price : undefined, product.base_price, product.price);
361
+ }
299
362
  function normalizeProductDiscounts(params) {
300
363
  const {
301
364
  product,
@@ -463,15 +526,50 @@ function normalizeProductCombinations(params) {
463
526
  locale,
464
527
  parentProduct
465
528
  });
466
- const optionTitle = buildOptionTitleSuffix(combinationsOptions);
529
+ const productNote = resolveProductNote(bundle, locale);
530
+ const nestedCombinations = Array.isArray(bundle.combinations) ? normalizeExistingCombinations(bundle.combinations, locale) : [];
467
531
  return {
468
- product_title: `${baseTitle}${optionTitle}`,
532
+ product_title: baseTitle,
469
533
  product_quantity: toNumber(bundle.num ?? bundle.quantity ?? 1, 1),
470
534
  price: formatBundlePrice(bundle, currencySymbol),
471
- combinations_options: combinationsOptions
535
+ combinations_options: combinationsOptions,
536
+ ...(productNote ? {
537
+ product_note: productNote
538
+ } : {}),
539
+ ...(nestedCombinations.length ? {
540
+ combinations: nestedCombinations
541
+ } : {})
542
+ };
543
+ });
544
+ }
545
+ function normalizeExistingCombinations(combinations, locale) {
546
+ return combinations.map(combination => {
547
+ if (!combination || typeof combination !== 'object' || Array.isArray(combination)) {
548
+ return combination;
549
+ }
550
+ const productNote = resolveProductNote(combination, locale);
551
+ const nestedCombinations = Array.isArray(combination.combinations) ? normalizeExistingCombinations(combination.combinations, locale) : undefined;
552
+ const snapshot = {
553
+ ...combination
554
+ };
555
+ delete snapshot.product_note;
556
+ delete snapshot.note;
557
+ return {
558
+ ...snapshot,
559
+ ...(productNote ? {
560
+ product_note: productNote
561
+ } : {}),
562
+ ...(nestedCombinations ? {
563
+ combinations: nestedCombinations
564
+ } : {})
472
565
  };
473
566
  });
474
567
  }
568
+ function resolveProductNote(product, locale) {
569
+ const productNote = getLocalizedValue(product.product_note, locale).trim();
570
+ if (productNote) return productNote;
571
+ return getLocalizedValue(product.note, locale).trim();
572
+ }
475
573
  function resolveBundleProductTitle(params) {
476
574
  const {
477
575
  bundle,
@@ -654,15 +752,6 @@ function isSameId(left, right) {
654
752
  if (!isPresentId(left) || !isPresentId(right)) return false;
655
753
  return String(left) === String(right);
656
754
  }
657
- function buildOptionTitleSuffix(options) {
658
- const text = options.map(option => {
659
- const name = stringify(option.name).trim();
660
- if (!name) return '';
661
- const quantity = option.num ?? 1;
662
- return `${name} x ${quantity}`;
663
- }).filter(Boolean).join(', ');
664
- return text ? `(${text})` : '';
665
- }
666
755
  function formatBundlePrice(bundle, currencySymbol) {
667
756
  const value = bundle.bundle_selling_price ?? bundle.bundle_sum_price ?? bundle.price ?? 0;
668
757
  const amount = new _decimal.default(toMoneyNumber(value));
@@ -678,7 +767,8 @@ function buildFees(params) {
678
767
  locale,
679
768
  products,
680
769
  summary,
681
- currencySymbol
770
+ currencySymbol,
771
+ financials
682
772
  } = params;
683
773
  const fees = [];
684
774
  for (const surcharge of normalizeArray(order.surcharges || summary.surcharges)) {
@@ -689,64 +779,101 @@ function buildFees(params) {
689
779
  value: formatMoney(value, currencySymbol)
690
780
  });
691
781
  }
692
- const discountAmount = order.shop_discount ?? summary.discount_amount ?? order.discount_amount;
782
+ const discountAmount = firstPresentValue(order.shop_discount, summary.discount_amount, order.discount_amount);
693
783
  if (isNonZero(discountAmount)) {
694
784
  fees.push({
695
785
  item: label(locale, 'orderDiscount'),
696
786
  value: formatNegativeMoney(discountAmount, currencySymbol)
697
787
  });
698
788
  }
699
- const taxFee = summary.tax_fee || order.tax_fee;
700
- if (isNonZero(taxFee)) {
701
- fees.push({
702
- item: stringify(summary.tax_title || order.tax_title || shopInfo.tax_title),
703
- value: formatMoney(taxFee, currencySymbol)
704
- });
705
- }
706
- const roundingAmount = summary.rounding_amount || order.rounding_amount;
789
+ const taxFee = firstPresentValue(summary.tax_fee, order.tax_fee);
790
+ const taxTitle = resolveTaxTitle({
791
+ summary,
792
+ order,
793
+ shopInfo,
794
+ locale
795
+ });
796
+ const isPriceIncludeTax = firstPresentValue(summary.is_price_include_tax, order.is_price_include_tax, shopInfo.is_price_include_tax);
797
+ const roundingAmount = firstPresentValue(summary.rounding_amount, order.rounding_amount);
707
798
  if (isNonZero(roundingAmount)) {
708
799
  fees.push({
709
800
  item: label(locale, 'rounding'),
710
801
  value: formatMoney(roundingAmount, currencySymbol)
711
802
  });
712
803
  }
713
- const payProcessingFee = summary.pay_service_charge_amount || order.pay_service_charge_amount;
804
+ const payProcessingFee = financials.payProcessingFee;
714
805
  if (isNonZero(payProcessingFee)) {
715
806
  fees.push({
716
807
  item: label(locale, 'payProcessingFee'),
717
808
  value: formatMoney(payProcessingFee, currencySymbol)
718
809
  });
719
810
  }
720
- const productExpectAmount = summary.product_expect_amount || summary.product_amount || order.product_expect_amount;
811
+ const productExpectAmount = firstPresentValue(summary.product_expect_amount, summary.product_amount, order.product_expect_amount);
721
812
  const productOriginalAmount = firstPresentValue(summary.product_original_amount, order.product_original_amount) ?? calculateProductOriginalAmount(order);
722
813
  const totalSavingsAmount = new _decimal.default(toMoneyNumber(productOriginalAmount)).minus(toMoneyNumber(productExpectAmount)).plus(toMoneyNumber(discountAmount));
723
814
  return {
724
815
  fees,
725
816
  countFee: {
726
- total_amount: formatMoney(summary.total_amount || order.total_amount, currencySymbol),
817
+ total_amount: formatMoney(firstPresentValue(summary.total_amount, order.total_amount) ?? 0, currencySymbol),
727
818
  original_item_amount: formatMoney(productOriginalAmount, currencySymbol),
728
- product_expect_amount: formatMoney(productExpectAmount, currencySymbol),
729
- expect_amount: formatMoney(summary.expect_amount || order.expect_amount || summary.total_amount || order.total_amount, currencySymbol),
730
- product_quantity: toNumber(summary.product_quantity || products.reduce((sum, product) => sum + product.product_quantity, 0), 0),
731
- has_pay: formatMoney(calculateReceiptPaidAmount(order, summary), currencySymbol),
819
+ product_expect_amount: formatMoney(productExpectAmount ?? 0, currencySymbol),
820
+ expect_amount: formatMoney(financials.totalAmount, currencySymbol),
821
+ product_quantity: toNumber(firstPresentValue(summary.product_quantity, products.reduce((sum, product) => sum + product.product_quantity, 0)), 0),
822
+ has_pay: formatMoney(financials.orderPaidAmount, currencySymbol),
732
823
  payment_method: '',
733
- tax_title: stringify(summary.tax_title || order.tax_title || shopInfo.tax_title),
734
- total_refund_amount: formatMoney(summary.total_refund_amount || order.total_refund_amount, currencySymbol),
735
- ...(isNonZero(roundingAmount) ? {
824
+ tax_title: taxTitle,
825
+ total_refund_amount: formatMoney(financials.totalRefundAmount, currencySymbol),
826
+ customer_paid_amount: formatMoney(financials.customerPaidAmount, currencySymbol),
827
+ net_payment_applied: formatMoney(financials.netPaymentApplied, currencySymbol),
828
+ ...(isPresentId(roundingAmount) ? {
736
829
  rounding_amount: formatMoney(roundingAmount, currencySymbol)
737
830
  } : {}),
738
831
  ...(isNonZero(totalSavingsAmount) ? {
739
832
  order_total_discount: formatMoney(totalSavingsAmount, currencySymbol)
740
833
  } : {}),
741
- ...(isNonZero(payProcessingFee) ? {
834
+ ...(financials.hasPayProcessingFee ? {
742
835
  pay_processing_fee: formatMoney(payProcessingFee, currencySymbol)
743
836
  } : {}),
744
- ...(isNonZero(taxFee) ? {
837
+ ...(isPresentId(taxFee) ? {
745
838
  tax_fee: formatMoney(taxFee, currencySymbol)
839
+ } : {}),
840
+ ...(isPresentId(isPriceIncludeTax) ? {
841
+ is_price_include_tax: normalizeBooleanFlag(isPriceIncludeTax)
746
842
  } : {})
747
843
  }
748
844
  };
749
845
  }
846
+ function resolveReceiptFinancials(order, summary) {
847
+ const totalAmount = firstPresentValue(summary.expect_amount, order.expect_amount, summary.total_amount, order.total_amount) ?? 0;
848
+ const rawPayProcessingFee = firstPresentValue(summary.pay_service_charge_amount, order.pay_service_charge_amount);
849
+ const payProcessingFee = rawPayProcessingFee ?? 0;
850
+ const orderPaidAmount = firstPresentValue(summary.order_paid_amount, order.order_paid_amount, sumAppliedPayments(order.payments)) ?? 0;
851
+ const totalRefundAmount = firstPresentValue(summary.total_refund_amount, order.total_refund_amount) ?? 0;
852
+ const netPaymentApplied = _decimal.default.max(new _decimal.default(toMoneyNumber(orderPaidAmount)).minus(toMoneyNumber(totalRefundAmount)), 0);
853
+ const fallbackCustomerPaidAmount = _decimal.default.max(sumCustomerPaidPayments(order.payments), new _decimal.default(toMoneyNumber(orderPaidAmount)).plus(toMoneyNumber(payProcessingFee)));
854
+ const customerPaidAmount = firstPresentValue(summary.customer_paid_amount, order.customer_paid_amount, fallbackCustomerPaidAmount) ?? 0;
855
+ const amountGap = firstPresentValue(summary.amount_gap, order.amount_gap);
856
+ return {
857
+ totalAmount,
858
+ orderPaidAmount,
859
+ payProcessingFee,
860
+ customerPaidAmount,
861
+ totalRefundAmount,
862
+ netPaymentApplied,
863
+ amountGap,
864
+ paymentStatus: resolveReceiptPaymentStatus({
865
+ order,
866
+ summary
867
+ }),
868
+ hasPayProcessingFee: isPresentId(rawPayProcessingFee)
869
+ };
870
+ }
871
+ function resolveReceiptPaymentStatus(params) {
872
+ return [params.order.payment_status, params.summary.payment_status, params.order.original_payment_status].map(status => stringify(status).trim()).find(Boolean) || '';
873
+ }
874
+ function resolveTaxTitle(params) {
875
+ return [params.summary.tax_title, params.order.tax_title, params.shopInfo.tax_title].map(title => getLocalizedValue(title, params.locale).trim()).find(Boolean) || 'Tax';
876
+ }
750
877
  function calculateProductOriginalAmount(order) {
751
878
  return normalizeArray(order.products).reduce((total, product) => {
752
879
  const quantity = toNumber(product.product_quantity ?? product.quantity ?? product.num ?? 1, 1);
@@ -773,25 +900,27 @@ function normalizeCustomerDisplayValue(value) {
773
900
  return text;
774
901
  }
775
902
  function buildDelivery(order, locale) {
776
- const serviceType = stringify(order.metadata?.service_type || order.service_type || order.delivery_type);
777
- if (!serviceType) return [];
778
- const serviceTypeLabelKey = serviceTypeToLabelKey(serviceType);
903
+ const deliveryType = stringify(order.delivery_type).trim();
904
+ const serviceType = deliveryType || stringify(firstPresentValue(order.metadata?.service_type, order.service_type)).trim();
905
+ const serviceTypeLabelKey = resolveServiceTypeLabelKey(serviceType, order);
906
+ if (!serviceTypeLabelKey) return [];
779
907
  const items = [{
780
908
  item: '',
781
909
  value: label(locale, serviceTypeLabelKey),
782
910
  size: 2,
783
911
  align: 'left'
784
912
  }];
785
- if (serviceType === 'shop_server' || serviceType === 'shop_service') {
913
+ const handoverTime = firstPresentValue(order.handover_time, order.handover_at, order.pickup_time, order.pickup_at, order.scheduled_pickup_time, order.delivery_time, order.delivery_at, order.scheduled_delivery_time, order.fulfillment_time, order.fulfillment_at, order.metadata?.handover_time, order.metadata?.handover_at, order.metadata?.pickup_time, order.metadata?.pickup_at, order.metadata?.scheduled_pickup_time, order.metadata?.delivery_time, order.metadata?.delivery_at, order.metadata?.scheduled_delivery_time, order.metadata?.fulfillment_time, order.metadata?.fulfillment_at);
914
+ if (isPresentId(handoverTime)) {
786
915
  items.push({
787
- item: label(locale, 'pickUpTime'),
788
- value: label(locale, 'asap')
916
+ item: label(locale, 'handoverTime'),
917
+ value: formatDateTime(handoverTime, locale)
789
918
  });
790
919
  }
791
920
  return items;
792
921
  }
793
922
  function buildAppointment(order, locale) {
794
- const bookings = normalizeArray(order.bookings);
923
+ const bookings = sortBookings(normalizeArray(order.bookings));
795
924
  if (bookings.length) {
796
925
  return bookings.map(booking => {
797
926
  const snapshot = {
@@ -819,6 +948,43 @@ function buildAppointment(order, locale) {
819
948
  value: getLocalizedValue(tableName, locale)
820
949
  }];
821
950
  }
951
+ function sortBookings(bookings) {
952
+ return bookings.map((booking, index) => ({
953
+ booking,
954
+ index
955
+ })).sort((left, right) => {
956
+ const leftStart = bookingStartTimestamp(left.booking);
957
+ const rightStart = bookingStartTimestamp(right.booking);
958
+ if (leftStart !== rightStart) return leftStart < rightStart ? -1 : 1;
959
+ for (const field of ['booking_id', 'schedule_event_id']) {
960
+ const fieldOrder = compareOptionalValues(left.booking?.[field], right.booking?.[field]);
961
+ if (fieldOrder !== 0) return fieldOrder;
962
+ }
963
+ const bookingUidOrder = compareOptionalValues(firstPresentValue(left.booking?.metadata?.unique_identification_number, left.booking?.booking_uid), firstPresentValue(right.booking?.metadata?.unique_identification_number, right.booking?.booking_uid));
964
+ return bookingUidOrder || left.index - right.index;
965
+ }).map(({
966
+ booking
967
+ }) => booking);
968
+ }
969
+ function bookingStartTimestamp(booking) {
970
+ const startValues = [booking?.start_at, booking?.start_datetime, booking?.booking_time, isPresentId(booking?.start_date) ? `${booking.start_date} ${stringify(booking.start_time)}`.trim() : undefined];
971
+ for (const startValue of startValues) {
972
+ if (!isPresentId(startValue)) continue;
973
+ const timestamp = (0, _dayjs.default)(startValue).valueOf();
974
+ if (Number.isFinite(timestamp)) return timestamp;
975
+ }
976
+ return Number.POSITIVE_INFINITY;
977
+ }
978
+ function compareOptionalValues(left, right) {
979
+ const hasLeft = isPresentId(left);
980
+ const hasRight = isPresentId(right);
981
+ if (!hasLeft && !hasRight) return 0;
982
+ if (!hasLeft) return 1;
983
+ if (!hasRight) return -1;
984
+ return String(left).localeCompare(String(right), undefined, {
985
+ numeric: true
986
+ });
987
+ }
822
988
  function buildResources(order, locale) {
823
989
  return normalizeArray(order.resources || order.resource_list).map(resource => ({
824
990
  id: resource.id || resource.resource_id || '',
@@ -836,13 +1002,151 @@ function buildPaymentData(params) {
836
1002
  includeFundRecordBalance: false
837
1003
  }));
838
1004
  }
1005
+ function buildRefundData(params) {
1006
+ const payments = normalizeArray(params.order.payments);
1007
+ const refunds = Array.from(normalizeArray(params.order.refunds).reduce((result, refund, index) => {
1008
+ const identity = refundIdentity(refund, index);
1009
+ const candidate = {
1010
+ refund,
1011
+ index
1012
+ };
1013
+ const existing = result.get(identity);
1014
+ if (!existing || shouldPreferRefundCandidate(candidate, existing)) {
1015
+ result.set(identity, candidate);
1016
+ }
1017
+ return result;
1018
+ }, new Map()).values()).filter(({
1019
+ refund
1020
+ }) => isPrintableRefund(refund)).sort((left, right) => {
1021
+ const leftTime = refundTimestamp(left.refund);
1022
+ const rightTime = refundTimestamp(right.refund);
1023
+ if (leftTime !== rightTime) return leftTime < rightTime ? -1 : 1;
1024
+ return left.index - right.index;
1025
+ });
1026
+ return refunds.map(({
1027
+ refund
1028
+ }) => {
1029
+ const payment = resolveRefundPayment(refund, payments);
1030
+ const methodName = paymentMethodName(payment, params.locale) || label(params.locale, 'refund');
1031
+ const amount = firstPresentValue(refund.amount, refund.refund_amount, refund.total_amount) ?? 0;
1032
+ const items = [{
1033
+ item: methodName,
1034
+ value: formatNegativeMoney(amount, params.currencySymbol)
1035
+ }];
1036
+ const occurredAt = firstPresentValue(refund.refund_time, refund.refunded_at, refund.created_at, refund.updated_at);
1037
+ if (isPresentId(occurredAt)) {
1038
+ items.push({
1039
+ item: formatDateTime(occurredAt, params.locale),
1040
+ value: ''
1041
+ });
1042
+ }
1043
+ return items;
1044
+ });
1045
+ }
1046
+ function refundIdentity(refund, index) {
1047
+ if (isPresentId(refund.order_refund_id)) return `refund-id:${refund.order_refund_id}`;
1048
+ if (isPresentId(refund.refund_number)) return `refund-number:${refund.refund_number}`;
1049
+ return `refund-index:${index}`;
1050
+ }
1051
+ function shouldPreferRefundCandidate(candidate, existing) {
1052
+ const candidatePrintable = isPrintableRefund(candidate.refund);
1053
+ const existingPrintable = isPrintableRefund(existing.refund);
1054
+ if (candidatePrintable !== existingPrintable) return candidatePrintable;
1055
+ const candidateTime = refundFreshnessTimestamp(candidate.refund);
1056
+ const existingTime = refundFreshnessTimestamp(existing.refund);
1057
+ if (candidateTime !== existingTime) return candidateTime > existingTime;
1058
+ return candidate.index > existing.index;
1059
+ }
1060
+ function refundFreshnessTimestamp(refund) {
1061
+ const timestampValue = firstPresentValue(refund.updated_at, refund.refunded_at, refund.refund_time, refund.created_at);
1062
+ if (!isPresentId(timestampValue)) return Number.NEGATIVE_INFINITY;
1063
+ const timestamp = (0, _dayjs.default)(timestampValue).valueOf();
1064
+ return Number.isFinite(timestamp) ? timestamp : Number.NEGATIVE_INFINITY;
1065
+ }
1066
+ function refundTimestamp(refund) {
1067
+ const occurredAt = firstPresentValue(refund.refund_time, refund.refunded_at, refund.created_at, refund.updated_at);
1068
+ if (!isPresentId(occurredAt)) return Number.POSITIVE_INFINITY;
1069
+ const timestamp = (0, _dayjs.default)(occurredAt).valueOf();
1070
+ return Number.isFinite(timestamp) ? timestamp : Number.POSITIVE_INFINITY;
1071
+ }
1072
+ function isPrintableRefund(refund) {
1073
+ const status = stringify(refund.status).trim().toLowerCase();
1074
+ if (!status) return true;
1075
+ return !['pending', 'payment_pending', 'payment_processing', 'refund_processing', 'processing', 'failed', 'error', 'cancelled', 'canceled', 'voided'].includes(status);
1076
+ }
1077
+ function resolveRefundPayment(refund, payments) {
1078
+ if (refund.payment && typeof refund.payment === 'object' && !Array.isArray(refund.payment)) {
1079
+ return refund.payment;
1080
+ }
1081
+ const orderPaymentId = firstPresentValue(refund.order_payment_id, refund.payment_id);
1082
+ const matchedPayment = payments.find(payment => isSameId(firstPresentValue(payment.order_payment_id, payment.id), orderPaymentId));
1083
+ return matchedPayment || refund;
1084
+ }
839
1085
  function buildWallets(params) {
840
- return normalizeArray(params.order.payments).filter(payment => isPrintablePayment(payment) && !!getFundRecord(payment)).map(payment => buildPaymentItems({
1086
+ const paymentWallets = normalizeArray(params.order.payments).filter(payment => isPrintablePayment(payment) && !!getFundRecord(payment)).map(payment => buildPaymentItems({
841
1087
  payment,
842
1088
  locale: params.locale,
843
1089
  currencySymbol: params.currencySymbol,
844
1090
  includeFundRecordBalance: true
845
1091
  }));
1092
+ return [...paymentWallets, ...buildVoucherAssets(params)];
1093
+ }
1094
+ function buildVoucherAssets(params) {
1095
+ const seenVoucherKeys = new Set();
1096
+ return normalizeArray(params.order.vouchers).flatMap((voucher, index) => {
1097
+ if (!voucher || typeof voucher !== 'object' || Array.isArray(voucher)) return [];
1098
+ const voucherKey = getVoucherAssetKey(voucher, index);
1099
+ if (seenVoucherKeys.has(voucherKey)) return [];
1100
+ seenVoucherKeys.add(voucherKey);
1101
+ const name = getVoucherAssetName(voucher, params.locale);
1102
+ const percent = getVoucherDiscountPercent(voucher);
1103
+ if (percent) {
1104
+ return [[{
1105
+ item: appendPercentToVoucherName(name, percent),
1106
+ value: formatVoucherDiscount(percent, params.locale)
1107
+ }]];
1108
+ }
1109
+ const balance = getVoucherBalance(voucher);
1110
+ return [[{
1111
+ item: name,
1112
+ value: ''
1113
+ }, {
1114
+ item: label(params.locale, 'balance'),
1115
+ value: formatMoney(balance, params.currencySymbol)
1116
+ }]];
1117
+ });
1118
+ }
1119
+ function getVoucherAssetKey(voucher, index) {
1120
+ const identity = firstPresentValue(voucher.voucher_id, voucher.id, voucher.code, voucher.encoded);
1121
+ return identity === undefined ? `voucher-index:${index}` : `voucher:${String(identity)}`;
1122
+ }
1123
+ function getVoucherAssetName(voucher, locale) {
1124
+ return getLocalizedValue(voucher.product_name || voucher.name || voucher.title, locale) || stringify(voucher.encoded || voucher.code || label(locale, 'giftCard'));
1125
+ }
1126
+ function getVoucherDiscountPercent(voucher) {
1127
+ const discountType = stringify(voucher.metadata?.discount_card_type || voucher.discount_card_type).toLowerCase();
1128
+ if (discountType !== 'percent' && discountType !== 'percentage') return null;
1129
+ const percent = new _decimal.default(toMoneyNumber(voucher.par_value));
1130
+ if (!percent.isFinite() || percent.lte(0) || percent.gt(100)) return null;
1131
+ return percent;
1132
+ }
1133
+ function appendPercentToVoucherName(name, percent) {
1134
+ if (/\d+(?:\.\d+)?\s*(?:%|折)|\boff\b/i.test(name)) return name;
1135
+ const separator = /^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u.test(name) ? '' : ' ';
1136
+ return `${trimDecimal(percent)}%${separator}${name}`;
1137
+ }
1138
+ function formatVoucherDiscount(percent, locale) {
1139
+ const normalizedLocale = normalizeLocaleKey(locale);
1140
+ if (normalizedLocale === 'zh_CN' || normalizedLocale === 'zh_HK') {
1141
+ return `${trimDecimal(percent)}% OFF`;
1142
+ }
1143
+ if (normalizedLocale === 'pt') return `Desconto ${trimDecimal(percent)}%`;
1144
+ return normalizedLocale === 'en' ? `Discount ${trimDecimal(percent)}% OFF` : `${trimDecimal(percent)}% OFF`;
1145
+ }
1146
+ function getVoucherBalance(voucher) {
1147
+ const parValue = new _decimal.default(toMoneyNumber(voucher.par_value));
1148
+ const usedParValue = new _decimal.default(toMoneyNumber(voucher.used_par_value));
1149
+ return _decimal.default.max(parValue.minus(usedParValue), 0);
846
1150
  }
847
1151
  function buildPaymentItems(params) {
848
1152
  const {
@@ -851,10 +1155,22 @@ function buildPaymentItems(params) {
851
1155
  currencySymbol,
852
1156
  includeFundRecordBalance
853
1157
  } = params;
1158
+ const serviceFee = getPaymentServiceFee(payment);
854
1159
  const items = [{
855
1160
  item: paymentMethodName(payment, locale),
856
- value: formatMoney(payment.amount ?? payment.origin_amount, currencySymbol)
1161
+ value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), currencySymbol)
857
1162
  }];
1163
+ items.push(...buildCashChangePaymentItems({
1164
+ payment,
1165
+ locale,
1166
+ currencySymbol
1167
+ }));
1168
+ if (serviceFee.gt(0)) {
1169
+ items.push({
1170
+ item: label(locale, 'surchargeIncluded'),
1171
+ value: formatMoney(serviceFee, currencySymbol)
1172
+ });
1173
+ }
858
1174
  const fundRecord = getFundRecord(payment);
859
1175
  if (fundRecord) {
860
1176
  items.push(...buildFundRecordPaymentItems({
@@ -879,6 +1195,47 @@ function buildPaymentItems(params) {
879
1195
  });
880
1196
  return items;
881
1197
  }
1198
+ function getPaymentServiceFee(payment) {
1199
+ return new _decimal.default(toMoneyNumber(payment.service_fee));
1200
+ }
1201
+ function resolveReceiptPaymentAmount(payment, serviceFee) {
1202
+ const amount = new _decimal.default(toMoneyNumber(payment.amount ?? payment.origin_amount));
1203
+ const hasAmount = payment.amount !== undefined && payment.amount !== null && payment.amount !== '';
1204
+ const hasOriginAmount = payment.origin_amount !== undefined && payment.origin_amount !== null && payment.origin_amount !== '';
1205
+ if (!hasAmount || !hasOriginAmount || serviceFee.lte(0)) return amount;
1206
+ const originAmount = new _decimal.default(toMoneyNumber(payment.origin_amount));
1207
+ return amount.eq(originAmount) ? amount.plus(serviceFee) : amount;
1208
+ }
1209
+ function buildCashChangePaymentItems(params) {
1210
+ const {
1211
+ payment,
1212
+ locale,
1213
+ currencySymbol
1214
+ } = params;
1215
+ if (!shouldDisplayCashChange(payment)) return [];
1216
+ return [{
1217
+ item: label(locale, 'cashReceived'),
1218
+ value: formatMoney(payment.metadata.actual_paid_amount, currencySymbol)
1219
+ }, {
1220
+ item: label(locale, 'changeDue'),
1221
+ value: formatMoney(payment.metadata.change_given_amount, currencySymbol)
1222
+ }];
1223
+ }
1224
+ function shouldDisplayCashChange(payment) {
1225
+ if (stringify(payment.status).toLowerCase() !== 'paid') return false;
1226
+ const paymentMethod = stringify(payment.code ?? payment.payment_method).toUpperCase();
1227
+ if (paymentMethod !== 'CASHMANUAL') return false;
1228
+ const actualPaidAmount = payment.metadata?.actual_paid_amount;
1229
+ const changeGivenAmount = payment.metadata?.change_given_amount;
1230
+ if (!isNumericAmount(actualPaidAmount) || !isNumericAmount(changeGivenAmount)) return false;
1231
+ return new _decimal.default(changeGivenAmount).toDecimalPlaces(2).gt(0);
1232
+ }
1233
+ function isNumericAmount(value) {
1234
+ if (typeof value === 'number') return Number.isFinite(value);
1235
+ if (typeof value !== 'string') return false;
1236
+ const normalized = value.trim();
1237
+ return normalized !== '' && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(normalized);
1238
+ }
882
1239
  function buildFundRecordPaymentItems(params) {
883
1240
  const {
884
1241
  payment,
@@ -981,13 +1338,29 @@ function getLocalizedValue(value, locale) {
981
1338
  const underscoredLocale = locale.replace('-', '_');
982
1339
  return stringify(value[locale] ?? value[dashedLocale] ?? value[underscoredLocale] ?? value.original ?? value.auto ?? value.default ?? value.en ?? '');
983
1340
  }
984
- function serviceTypeToLabelKey(serviceType) {
985
- const normalized = serviceType.toLowerCase();
986
- if (normalized.includes('take')) return 'takeAway';
987
- if (normalized.includes('delivery')) return 'delivery';
988
- if (normalized.includes('pick')) return 'pickUp';
989
- if (normalized.includes('shop')) return 'shopService';
990
- return 'dineIn';
1341
+ function resolveServiceTypeLabelKey(serviceType, order) {
1342
+ const normalized = serviceType.trim().toLowerCase().replace(/[\s-]+/g, '_');
1343
+ if (['', 'nil', 'none', 'unknown'].includes(normalized)) return null;
1344
+ if (['pickup', 'pick_up', 'self_pickup'].includes(normalized)) return 'pickUp';
1345
+ if (['delivery', 'shipping', 'local_delivery'].includes(normalized)) return 'delivery';
1346
+ if (['takeaway', 'take_away'].includes(normalized)) return 'takeAway';
1347
+ if (['dine_in', 'dinein'].includes(normalized)) return 'dineIn';
1348
+ if (['shop_service', 'shop_server'].includes(normalized)) {
1349
+ return resolveShopServiceLabelKey(order);
1350
+ }
1351
+ return null;
1352
+ }
1353
+ function resolveShopServiceLabelKey(order) {
1354
+ const rawShopServiceType = firstPresentValue(order.metadata?.shop_service_type?.server_type, order.shop_service_type?.server_type, typeof order.shop_service_type === 'string' ? order.shop_service_type : undefined);
1355
+ if (!isPresentId(rawShopServiceType)) return 'dineIn';
1356
+ const normalized = stringify(rawShopServiceType).trim().toLowerCase().replace(/[\s-]+/g, '_');
1357
+ if (['takeaway', 'take_away'].includes(normalized)) return 'takeAway';
1358
+ if (['dine_in', 'dinein'].includes(normalized)) return 'dineIn';
1359
+ return null;
1360
+ }
1361
+ function normalizeBooleanFlag(value) {
1362
+ if (value === true || value === 1 || stringify(value).trim() === '1') return 1;
1363
+ return 0;
991
1364
  }
992
1365
  function buildShopAddress(shopInfo) {
993
1366
  return [shopInfo.address_street, shopInfo.address_detail, shopInfo.city, shopInfo.province, shopInfo.country, shopInfo.zip].filter(Boolean).join(', ');
@@ -1008,17 +1381,17 @@ function formatNegativeMoney(value, currencySymbol) {
1008
1381
  const amount = new _decimal.default(toMoneyNumber(value)).abs();
1009
1382
  return `-${currencySymbol}${amount.toFixed(2)}`;
1010
1383
  }
1011
- function calculateReceiptPaidAmount(order, summary) {
1012
- const paidAmount = sumPayments(order.payments);
1013
- const payProcessingFee = new _decimal.default(toMoneyNumber(summary.pay_service_charge_amount ?? order.pay_service_charge_amount));
1014
- if (payProcessingFee.lte(0)) return paidAmount;
1015
- const totalAmount = new _decimal.default(toMoneyNumber(summary.total_amount ?? order.total_amount));
1016
- if (totalAmount.gt(0) && paidAmount.gte(totalAmount)) return paidAmount;
1017
- const paidAmountWithFee = paidAmount.plus(payProcessingFee);
1018
- if (totalAmount.gt(0) && paidAmountWithFee.gt(totalAmount)) return totalAmount;
1019
- return paidAmountWithFee;
1020
- }
1021
- function sumPayments(payments) {
1384
+ function sumAppliedPayments(payments) {
1385
+ return normalizeArray(payments).filter(payment => isPrintablePayment(payment)).reduce((sum, payment) => {
1386
+ if (isPresentId(payment.origin_amount)) {
1387
+ return sum.plus(toMoneyNumber(payment.origin_amount));
1388
+ }
1389
+ const amount = new _decimal.default(toMoneyNumber(payment.amount));
1390
+ const serviceFee = _decimal.default.max(toMoneyNumber(payment.service_fee), 0);
1391
+ return sum.plus(_decimal.default.max(amount.minus(serviceFee), 0));
1392
+ }, new _decimal.default(0));
1393
+ }
1394
+ function sumCustomerPaidPayments(payments) {
1022
1395
  return normalizeArray(payments).filter(payment => isPrintablePayment(payment)).reduce((sum, payment) => {
1023
1396
  return sum.plus(toMoneyNumber(payment.amount ?? payment.origin_amount));
1024
1397
  }, new _decimal.default(0));
@@ -1026,7 +1399,7 @@ function sumPayments(payments) {
1026
1399
  function isPrintablePayment(payment) {
1027
1400
  const status = stringify(payment.status).toLowerCase();
1028
1401
  if (!status) return true;
1029
- return ['paid', 'success', 'succeeded', 'completed'].includes(status);
1402
+ return ['paid', 'success', 'succeeded', 'completed', 'partially_refunded', 'refunded'].includes(status);
1030
1403
  }
1031
1404
  function normalizeArray(value) {
1032
1405
  return Array.isArray(value) ? value : [];