@pisell/pisellos 2.3.96 → 2.3.98

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.
@@ -35,6 +35,8 @@ export interface SmallTicketProduct {
35
35
  original_price: string;
36
36
  total_original_price: string;
37
37
  extension_list: any[];
38
+ product_uid?: string | number;
39
+ booking_uid?: string | number;
38
40
  options?: Array<{
39
41
  name: string;
40
42
  num?: number;
@@ -44,6 +46,11 @@ export interface SmallTicketProduct {
44
46
  variant?: string;
45
47
  combinations?: any[];
46
48
  }
49
+ export interface SmallTicketBookingSnapshot extends Record<string, any> {
50
+ product_uid?: string | number;
51
+ booking_uid?: string | number;
52
+ }
53
+ export type SmallTicketAppointment = SmallTicketItem[] | SmallTicketBookingSnapshot[];
47
54
  export interface SmallTicketLocaleData {
48
55
  base_data: Record<string, any>;
49
56
  products: SmallTicketProduct[];
@@ -52,7 +59,7 @@ export interface SmallTicketLocaleData {
52
59
  countFee: Record<string, any>;
53
60
  };
54
61
  customer: SmallTicketItem[];
55
- appointment: SmallTicketItem[];
62
+ appointment: SmallTicketAppointment;
56
63
  delivery?: SmallTicketItem[];
57
64
  resources: Array<{
58
65
  id: string | number;
@@ -61,6 +68,7 @@ export interface SmallTicketLocaleData {
61
68
  form_title: string;
62
69
  }>;
63
70
  payment_data: SmallTicketItem[][];
71
+ wallets: SmallTicketItem[][];
64
72
  tickets: any[];
65
73
  source_shop: any[];
66
74
  refund_data: any[];
@@ -150,6 +150,11 @@ function buildLocaleData(params) {
150
150
  locale: locale,
151
151
  currencySymbol: currencySymbol
152
152
  }),
153
+ wallets: buildWallets({
154
+ order: order,
155
+ locale: locale,
156
+ currencySymbol: currencySymbol
157
+ }),
153
158
  tickets: Array.isArray(order.tickets) ? order.tickets : [],
154
159
  source_shop: [],
155
160
  refund_data: [],
@@ -162,7 +167,7 @@ function buildBaseData(params) {
162
167
  shopInfo = params.shopInfo,
163
168
  locale = params.locale;
164
169
  var orderNumber = stringify(order.buzzer || order.shop_full_order_number);
165
- return {
170
+ return _objectSpread({
166
171
  shop_name: stringify(shopInfo.name || order.shop_name),
167
172
  note: stringify(order.note),
168
173
  shop_order_number: stringify(order.shop_order_number),
@@ -175,12 +180,14 @@ function buildBaseData(params) {
175
180
  buzzer: stringify(order.buzzer || order.pickup_number || ((_order$metadata = order.metadata) === null || _order$metadata === void 0 ? void 0 : _order$metadata.buzzer)),
176
181
  order_no: orderNumber,
177
182
  order_time: formatDateTime(order.created_at || order.sales_time || new Date(), locale)
178
- };
183
+ }, isPresentId(order.updated_at) ? {
184
+ updated_at: formatDateTime(order.updated_at, locale)
185
+ } : {});
179
186
  }
180
187
  function buildProducts(order, locale, productMap) {
181
188
  var products = Array.isArray(order.products) ? order.products : [];
182
189
  return products.map(function (product) {
183
- var _ref, _ref2, _product$product_quan, _ref3, _ref4, _ref5, _product$original_pri, _ref6, _ref7, _product$selling_pric, _product$product_id;
190
+ var _ref, _ref2, _product$product_quan, _ref3, _ref4, _ref5, _product$original_pri, _ref6, _ref7, _product$selling_pric, _product$product_id, _product$metadata, _product$metadata2;
184
191
  var quantity = toNumber((_ref = (_ref2 = (_product$product_quan = product.product_quantity) !== null && _product$product_quan !== void 0 ? _product$product_quan : product.quantity) !== null && _ref2 !== void 0 ? _ref2 : product.num) !== null && _ref !== void 0 ? _ref : 1, 1);
185
192
  var originalPrice = (_ref3 = (_ref4 = (_ref5 = (_product$original_pri = product.original_price) !== null && _product$original_pri !== void 0 ? _product$original_pri : product.selling_price) !== null && _ref5 !== void 0 ? _ref5 : product.payment_price) !== null && _ref4 !== void 0 ? _ref4 : product.price) !== null && _ref3 !== void 0 ? _ref3 : 0;
186
193
  var sellingPrice = (_ref6 = (_ref7 = (_product$selling_pric = product.selling_price) !== null && _product$selling_pric !== void 0 ? _product$selling_pric : product.payment_price) !== null && _ref7 !== void 0 ? _ref7 : product.price) !== null && _ref6 !== void 0 ? _ref6 : originalPrice;
@@ -209,6 +216,8 @@ function buildProducts(order, locale, productMap) {
209
216
  parentProduct: parentProduct,
210
217
  locale: locale
211
218
  });
219
+ var productUid = firstPresentValue((_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata.unique_identification_number, product.unique_identification_number);
220
+ var bookingUid = firstPresentValue(product.booking_uid, (_product$metadata2 = product.metadata) === null || _product$metadata2 === void 0 ? void 0 : _product$metadata2.booking_uid);
212
221
  var extensionList = buildProductExtensionList({
213
222
  product: product,
214
223
  locale: locale,
@@ -216,14 +225,18 @@ function buildProducts(order, locale, productMap) {
216
225
  quantity: quantity,
217
226
  originalPrice: originalPrice
218
227
  });
219
- return _objectSpread(_objectSpread(_objectSpread({
228
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
220
229
  product_title: productTitle,
221
230
  product_quantity: quantity,
222
231
  selling_price: formatMoney(sellingPrice, currencySymbol),
223
232
  original_price: formatMoney(originalPrice, currencySymbol),
224
233
  total_original_price: formatMoney(new Decimal(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
225
234
  extension_list: extensionList
226
- }, options.length ? {
235
+ }, isPresentId(productUid) ? {
236
+ product_uid: productUid
237
+ } : {}), isPresentId(bookingUid) ? {
238
+ booking_uid: bookingUid
239
+ } : {}), options.length ? {
227
240
  options: options
228
241
  } : {}), resolvedVariant ? {
229
242
  variant: resolvedVariant
@@ -604,6 +617,14 @@ function isNonZeroId(value) {
604
617
  function isPresentId(value) {
605
618
  return value !== undefined && value !== null && value !== '';
606
619
  }
620
+ function firstPresentValue() {
621
+ for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {
622
+ values[_key] = arguments[_key];
623
+ }
624
+ return values.find(function (value) {
625
+ return isPresentId(value);
626
+ });
627
+ }
607
628
  function isSameId(left, right) {
608
629
  if (!isPresentId(left) || !isPresentId(right)) return false;
609
630
  return String(left) === String(right);
@@ -628,7 +649,7 @@ function formatBundlePrice(bundle, currencySymbol) {
628
649
  return formatMoney(amount, currencySymbol);
629
650
  }
630
651
  function buildFees(params) {
631
- var _ref36, _order$shop_discount, _ref37, _summary$product_orig;
652
+ var _ref36, _order$shop_discount, _firstPresentValue;
632
653
  var order = params.order,
633
654
  shopInfo = params.shopInfo,
634
655
  locale = params.locale,
@@ -675,12 +696,13 @@ function buildFees(params) {
675
696
  });
676
697
  }
677
698
  var productExpectAmount = summary.product_expect_amount || summary.product_amount || order.product_expect_amount;
678
- var productOriginalAmount = (_ref37 = (_summary$product_orig = summary.product_original_amount) !== null && _summary$product_orig !== void 0 ? _summary$product_orig : order.product_original_amount) !== null && _ref37 !== void 0 ? _ref37 : productExpectAmount;
699
+ var productOriginalAmount = (_firstPresentValue = firstPresentValue(summary.product_original_amount, order.product_original_amount)) !== null && _firstPresentValue !== void 0 ? _firstPresentValue : calculateProductOriginalAmount(order);
679
700
  var totalSavingsAmount = new Decimal(toMoneyNumber(productOriginalAmount)).minus(toMoneyNumber(productExpectAmount)).plus(toMoneyNumber(discountAmount));
680
701
  return {
681
702
  fees: fees,
682
703
  countFee: _objectSpread(_objectSpread(_objectSpread(_objectSpread({
683
704
  total_amount: formatMoney(summary.total_amount || order.total_amount, currencySymbol),
705
+ original_item_amount: formatMoney(productOriginalAmount, currencySymbol),
684
706
  product_expect_amount: formatMoney(productExpectAmount, currencySymbol),
685
707
  expect_amount: formatMoney(summary.expect_amount || order.expect_amount || summary.total_amount || order.total_amount, currencySymbol),
686
708
  product_quantity: toNumber(summary.product_quantity || products.reduce(function (sum, product) {
@@ -701,6 +723,14 @@ function buildFees(params) {
701
723
  } : {})
702
724
  };
703
725
  }
726
+ function calculateProductOriginalAmount(order) {
727
+ return normalizeArray(order.products).reduce(function (total, product) {
728
+ var _ref37, _ref38, _product$product_quan2, _ref39, _ref40, _ref41, _product$original_pri2;
729
+ var quantity = toNumber((_ref37 = (_ref38 = (_product$product_quan2 = product.product_quantity) !== null && _product$product_quan2 !== void 0 ? _product$product_quan2 : product.quantity) !== null && _ref38 !== void 0 ? _ref38 : product.num) !== null && _ref37 !== void 0 ? _ref37 : 1, 1);
730
+ var originalPrice = (_ref39 = (_ref40 = (_ref41 = (_product$original_pri2 = product.original_price) !== null && _product$original_pri2 !== void 0 ? _product$original_pri2 : product.selling_price) !== null && _ref41 !== void 0 ? _ref41 : product.payment_price) !== null && _ref40 !== void 0 ? _ref40 : product.price) !== null && _ref39 !== void 0 ? _ref39 : 0;
731
+ return total.plus(new Decimal(toMoneyNumber(originalPrice)).mul(quantity));
732
+ }, new Decimal(0));
733
+ }
704
734
  function buildCustomer(order, locale) {
705
735
  var _order$customer, _order$customer2, _order$customer3, _order$customer4;
706
736
  return [{
@@ -741,6 +771,22 @@ function buildDelivery(order, locale) {
741
771
  }
742
772
  function buildAppointment(order, locale) {
743
773
  var _order$metadata3, _order$metadata4, _order$form_data;
774
+ var bookings = normalizeArray(order.bookings);
775
+ if (bookings.length) {
776
+ return bookings.map(function (booking) {
777
+ var _booking$metadata, _booking$metadata2;
778
+ var snapshot = _objectSpread({}, booking);
779
+ delete snapshot.product_uid;
780
+ delete snapshot.booking_uid;
781
+ var productUid = firstPresentValue(booking.product_uid, (_booking$metadata = booking.metadata) === null || _booking$metadata === void 0 ? void 0 : _booking$metadata.product_uid);
782
+ var bookingUid = firstPresentValue((_booking$metadata2 = booking.metadata) === null || _booking$metadata2 === void 0 ? void 0 : _booking$metadata2.unique_identification_number, booking.booking_uid);
783
+ return _objectSpread(_objectSpread(_objectSpread({}, snapshot), isPresentId(productUid) ? {
784
+ product_uid: productUid
785
+ } : {}), isPresentId(bookingUid) ? {
786
+ booking_uid: bookingUid
787
+ } : {});
788
+ });
789
+ }
744
790
  var tableName = order.table_name || ((_order$metadata3 = order.metadata) === null || _order$metadata3 === void 0 ? void 0 : _order$metadata3.table_name) || ((_order$metadata4 = order.metadata) === null || _order$metadata4 === void 0 || (_order$metadata4 = _order$metadata4.table) === null || _order$metadata4 === void 0 ? void 0 : _order$metadata4.name) || ((_order$form_data = order.form_data) === null || _order$form_data === void 0 ? void 0 : _order$form_data.table_name);
745
791
  if (!tableName) return [];
746
792
  return [{
@@ -763,41 +809,66 @@ function buildPaymentData(params) {
763
809
  return payments.filter(function (payment) {
764
810
  return isPrintablePayment(payment);
765
811
  }).map(function (payment) {
766
- var serviceFee = getPaymentServiceFee(payment);
767
- var items = [{
768
- item: paymentMethodName(payment, params.locale),
769
- value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), params.currencySymbol)
770
- }];
771
- if (serviceFee.gt(0)) {
812
+ return buildPaymentItems({
813
+ payment: payment,
814
+ locale: params.locale,
815
+ currencySymbol: params.currencySymbol,
816
+ includeFundRecordBalance: false
817
+ });
818
+ });
819
+ }
820
+ function buildWallets(params) {
821
+ return normalizeArray(params.order.payments).filter(function (payment) {
822
+ return isPrintablePayment(payment) && !!getFundRecord(payment);
823
+ }).map(function (payment) {
824
+ return buildPaymentItems({
825
+ payment: payment,
826
+ locale: params.locale,
827
+ currencySymbol: params.currencySymbol,
828
+ includeFundRecordBalance: true
829
+ });
830
+ });
831
+ }
832
+ function buildPaymentItems(params) {
833
+ var payment = params.payment,
834
+ locale = params.locale,
835
+ currencySymbol = params.currencySymbol,
836
+ includeFundRecordBalance = params.includeFundRecordBalance;
837
+ var serviceFee = getPaymentServiceFee(payment);
838
+ var items = [{
839
+ item: paymentMethodName(payment, locale),
840
+ value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), currencySymbol)
841
+ }];
842
+ if (serviceFee.gt(0)) {
843
+ items.push({
844
+ item: label(locale, 'surchargeIncluded'),
845
+ value: formatMoney(serviceFee, currencySymbol)
846
+ });
847
+ }
848
+ var fundRecord = getFundRecord(payment);
849
+ if (fundRecord) {
850
+ items.push.apply(items, _toConsumableArray(buildFundRecordPaymentItems({
851
+ payment: payment,
852
+ fundRecord: fundRecord,
853
+ locale: locale,
854
+ currencySymbol: currencySymbol,
855
+ includeBalance: includeFundRecordBalance
856
+ })));
857
+ } else {
858
+ var _ref42, _payment$remaining_am, _payment$metadata;
859
+ var remainingAmount = (_ref42 = (_payment$remaining_am = payment.remaining_amount) !== null && _payment$remaining_am !== void 0 ? _payment$remaining_am : payment.balance) !== null && _ref42 !== void 0 ? _ref42 : (_payment$metadata = payment.metadata) === null || _payment$metadata === void 0 ? void 0 : _payment$metadata.remaining_amount;
860
+ if (remainingAmount !== undefined && remainingAmount !== null) {
772
861
  items.push({
773
- item: label(params.locale, 'surchargeIncluded'),
774
- value: formatMoney(serviceFee, params.currencySymbol)
862
+ item: label(locale, 'remainingAmount'),
863
+ value: formatMoney(remainingAmount, currencySymbol)
775
864
  });
776
865
  }
777
- var fundRecord = getFundRecord(payment);
778
- if (fundRecord) {
779
- items.push.apply(items, _toConsumableArray(buildFundRecordPaymentItems({
780
- payment: payment,
781
- fundRecord: fundRecord,
782
- locale: params.locale,
783
- currencySymbol: params.currencySymbol
784
- })));
785
- } else {
786
- var _ref38, _payment$remaining_am, _payment$metadata;
787
- var remainingAmount = (_ref38 = (_payment$remaining_am = payment.remaining_amount) !== null && _payment$remaining_am !== void 0 ? _payment$remaining_am : payment.balance) !== null && _ref38 !== void 0 ? _ref38 : (_payment$metadata = payment.metadata) === null || _payment$metadata === void 0 ? void 0 : _payment$metadata.remaining_amount;
788
- if (remainingAmount !== undefined && remainingAmount !== null) {
789
- items.push({
790
- item: label(params.locale, 'remainingAmount'),
791
- value: formatMoney(remainingAmount, params.currencySymbol)
792
- });
793
- }
794
- }
795
- items.push({
796
- item: formatDateTime(payment.paid_at || payment.created_at || payment.updated_at || new Date(), params.locale),
797
- value: ''
798
- });
799
- return items;
866
+ }
867
+ items.push({
868
+ item: formatDateTime(payment.paid_at || payment.created_at || payment.updated_at || new Date(), locale),
869
+ value: ''
800
870
  });
871
+ return items;
801
872
  }
802
873
  function getPaymentServiceFee(payment) {
803
874
  return new Decimal(toMoneyNumber(payment.service_fee));
@@ -815,7 +886,8 @@ function buildFundRecordPaymentItems(params) {
815
886
  var payment = params.payment,
816
887
  fundRecord = params.fundRecord,
817
888
  locale = params.locale,
818
- currencySymbol = params.currencySymbol;
889
+ currencySymbol = params.currencySymbol,
890
+ includeBalance = params.includeBalance;
819
891
  var items = [];
820
892
  var usingBeforeValue = fundRecord.using_before_value;
821
893
  var usingAfterValue = fundRecord.using_after_value;
@@ -825,13 +897,15 @@ function buildFundRecordPaymentItems(params) {
825
897
  item: label(locale, 'redeemPoints'),
826
898
  value: trimDecimal(usedPoints)
827
899
  });
828
- items.push({
829
- item: label(locale, 'remainingPoints'),
830
- value: trimDecimal(new Decimal(toMoneyNumber(usingAfterValue)))
831
- });
900
+ if (includeBalance) {
901
+ items.push({
902
+ item: label(locale, 'remainingPoints'),
903
+ value: trimDecimal(new Decimal(toMoneyNumber(usingAfterValue)))
904
+ });
905
+ }
832
906
  return items;
833
907
  }
834
- if (usingAfterValue !== undefined && usingAfterValue !== null) {
908
+ if (includeBalance && usingAfterValue !== undefined && usingAfterValue !== null) {
835
909
  items.push({
836
910
  item: label(locale, 'remainingAmount'),
837
911
  value: formatMoney(usingAfterValue, currencySymbol)
@@ -904,12 +978,12 @@ function label(locale, key) {
904
978
  return ((_LABELS$locale = LABELS[locale]) === null || _LABELS$locale === void 0 ? void 0 : _LABELS$locale[key]) || LABELS.en[key] || key;
905
979
  }
906
980
  function getLocalizedValue(value, locale) {
907
- var _ref39, _ref40, _ref41, _ref42, _ref43, _ref44, _value$locale2;
981
+ var _ref43, _ref44, _ref45, _ref46, _ref47, _ref48, _value$locale2;
908
982
  if (value === undefined || value === null) return '';
909
983
  if (_typeof(value) !== 'object') return stringify(value);
910
984
  var dashedLocale = locale.replace('_', '-');
911
985
  var underscoredLocale = locale.replace('-', '_');
912
- return stringify((_ref39 = (_ref40 = (_ref41 = (_ref42 = (_ref43 = (_ref44 = (_value$locale2 = value[locale]) !== null && _value$locale2 !== void 0 ? _value$locale2 : value[dashedLocale]) !== null && _ref44 !== void 0 ? _ref44 : value[underscoredLocale]) !== null && _ref43 !== void 0 ? _ref43 : value.original) !== null && _ref42 !== void 0 ? _ref42 : value.auto) !== null && _ref41 !== void 0 ? _ref41 : value.default) !== null && _ref40 !== void 0 ? _ref40 : value.en) !== null && _ref39 !== void 0 ? _ref39 : '');
986
+ return stringify((_ref43 = (_ref44 = (_ref45 = (_ref46 = (_ref47 = (_ref48 = (_value$locale2 = value[locale]) !== null && _value$locale2 !== void 0 ? _value$locale2 : value[dashedLocale]) !== null && _ref48 !== void 0 ? _ref48 : value[underscoredLocale]) !== null && _ref47 !== void 0 ? _ref47 : value.original) !== null && _ref46 !== void 0 ? _ref46 : value.auto) !== null && _ref45 !== void 0 ? _ref45 : value.default) !== null && _ref44 !== void 0 ? _ref44 : value.en) !== null && _ref43 !== void 0 ? _ref43 : '');
913
987
  }
914
988
  function serviceTypeToLabelKey(serviceType) {
915
989
  var normalized = serviceType.toLowerCase();
@@ -90,6 +90,13 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
90
90
  private groupBookingsByResource;
91
91
  private isBookingMatchedResource;
92
92
  private sortMatchedBookings;
93
+ /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
94
+ private sortUnpaidBookings;
95
+ /**
96
+ * 构造资源详情的 Unpaid 列表:复用旧版当前/未来订单的展示计算,再补齐被预约状态/时间漏掉的欠款订单。
97
+ * Unpaid 的成员资格由调用方按付款状态筛好;这里仅负责展示字段与顺序。
98
+ */
99
+ private buildUnpaidBookings;
93
100
  /**
94
101
  * 资源下 bookings 的返回裁剪策略:
95
102
  * 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
@@ -485,6 +485,64 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
485
485
  });
486
486
  }
487
487
 
488
+ /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
489
+ }, {
490
+ key: "sortUnpaidBookings",
491
+ value: function sortUnpaidBookings(bookings, currentBookings) {
492
+ var _this4 = this;
493
+ var currentOrderIndexes = new Map(currentBookings.map(function (booking, index) {
494
+ return [String(booking.order.order_id), index];
495
+ }));
496
+ return _toConsumableArray(bookings).sort(function (left, right) {
497
+ var leftIndex = currentOrderIndexes.get(String(left.order.order_id));
498
+ var rightIndex = currentOrderIndexes.get(String(right.order.order_id));
499
+ if (leftIndex !== undefined || rightIndex !== undefined) {
500
+ if (leftIndex === undefined) return 1;
501
+ if (rightIndex === undefined) return -1;
502
+ return leftIndex - rightIndex;
503
+ }
504
+ var leftStartAt = _this4.toBookingDateTime(left.start_date, left.start_time).valueOf();
505
+ var rightStartAt = _this4.toBookingDateTime(right.start_date, right.start_time).valueOf();
506
+ return rightStartAt - leftStartAt;
507
+ });
508
+ }
509
+
510
+ /**
511
+ * 构造资源详情的 Unpaid 列表:复用旧版当前/未来订单的展示计算,再补齐被预约状态/时间漏掉的欠款订单。
512
+ * Unpaid 的成员资格由调用方按付款状态筛好;这里仅负责展示字段与顺序。
513
+ */
514
+ }, {
515
+ key: "buildUnpaidBookings",
516
+ value: function buildUnpaidBookings(current, deviceCurrent, unpaidBookingList, currentBookings) {
517
+ var _this5 = this;
518
+ var legacyPrioritizedBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList), {
519
+ includeAllFuture: true
520
+ });
521
+ var allBookings = this.sortMatchedBookings(unpaidBookingList.map(function (booking) {
522
+ var normalized = _this5.normalizeMatchedBooking(current, deviceCurrent, booking, {
523
+ includeCompleted: true
524
+ });
525
+ if (normalized) return normalized;
526
+ var appointmentStatus = _this5.getBookingAppointmentStatus(booking);
527
+ var status = appointmentStatus === 'started' ? 'occupied' : appointmentStatus === 'completed' ? 'completed' : 'reserved';
528
+ return _objectSpread(_objectSpread({}, booking), {}, {
529
+ status: status,
530
+ isTimeout: false,
531
+ timeoutTime: undefined,
532
+ progressPercent: undefined,
533
+ lateTime: undefined,
534
+ reserved_status: undefined,
535
+ remainingReserveTime: undefined
536
+ });
537
+ }));
538
+ var legacyOrderIds = new Set(legacyPrioritizedBookings.map(function (booking) {
539
+ return String(booking.order.order_id);
540
+ }));
541
+ return this.sortUnpaidBookings([].concat(_toConsumableArray(legacyPrioritizedBookings), _toConsumableArray(allBookings.filter(function (booking) {
542
+ return !legacyOrderIds.has(String(booking.order.order_id));
543
+ }))), currentBookings);
544
+ }
545
+
488
546
  /**
489
547
  * 资源下 bookings 的返回裁剪策略:
490
548
  * 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
@@ -496,7 +554,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
496
554
  }, {
497
555
  key: "pickBookingsForCurrentPoint",
498
556
  value: function pickBookingsForCurrentPoint(current, bookings) {
499
- var _this4 = this;
557
+ var _this6 = this;
500
558
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
501
559
  if (bookings.length === 0) return [];
502
560
  var _this$getOperatingDay = this.getOperatingDayRange(current),
@@ -505,17 +563,17 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
505
563
 
506
564
  // 仅保留与 current 所属营业日窗口有时间交集的预约,避免跨营业日误命中
507
565
  var dayScopedBookings = bookings.filter(function (booking) {
508
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
509
- var endAt = _this4.toBookingDateTime(booking.end_date, booking.end_time);
566
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
567
+ var endAt = _this6.toBookingDateTime(booking.end_date, booking.end_time);
510
568
  if (!startAt.isValid() || !endAt.isValid()) return false;
511
- return startAt.isBefore(operatingDayEndExclusive) && _this4.isSameOrAfter(endAt, operatingDayStart);
569
+ return startAt.isBefore(operatingDayEndExclusive) && _this6.isSameOrAfter(endAt, operatingDayStart);
512
570
  });
513
571
  if (dayScopedBookings.length === 0) return [];
514
572
  var appendNextStartGroupIfNeeded = function appendNextStartGroupIfNeeded(selectedBookings) {
515
573
  if (selectedBookings.length === 0) return selectedBookings;
516
574
  if (options.includeAllFuture) {
517
575
  var allFutureBookings = dayScopedBookings.filter(function (booking) {
518
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
576
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
519
577
  return startAt.isValid() && startAt.isAfter(current);
520
578
  });
521
579
  return [].concat(_toConsumableArray(selectedBookings), _toConsumableArray(allFutureBookings));
@@ -525,21 +583,21 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
525
583
  });
526
584
  if (!shouldAppendNextGroup) return selectedBookings;
527
585
  var selectedStartValues = new Set(selectedBookings.map(function (booking) {
528
- return _this4.toBookingDateTime(booking.start_date, booking.start_time);
586
+ return _this6.toBookingDateTime(booking.start_date, booking.start_time);
529
587
  }).filter(function (startAt) {
530
588
  return startAt.isValid();
531
589
  }).map(function (startAt) {
532
590
  return startAt.valueOf();
533
591
  }));
534
592
  var futureCandidates = dayScopedBookings.filter(function (booking) {
535
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
593
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
536
594
  if (!startAt.isValid()) return false;
537
595
  return startAt.isAfter(current) && !selectedStartValues.has(startAt.valueOf());
538
596
  });
539
597
  if (futureCandidates.length === 0) return selectedBookings;
540
- var nextStartAt = _this4.toBookingDateTime(futureCandidates[0].start_date, futureCandidates[0].start_time).valueOf();
598
+ var nextStartAt = _this6.toBookingDateTime(futureCandidates[0].start_date, futureCandidates[0].start_time).valueOf();
541
599
  var nextStartGroup = futureCandidates.filter(function (booking) {
542
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
600
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
543
601
  return startAt.isValid() && startAt.valueOf() === nextStartAt;
544
602
  });
545
603
  if (nextStartGroup.length === 0) return selectedBookings;
@@ -551,10 +609,10 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
551
609
 
552
610
  // active: current 处于 [startAt, endAt] 区间
553
611
  var activeBookings = dayScopedBookings.filter(function (booking) {
554
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
555
- var endAt = _this4.toBookingDateTime(booking.end_date, booking.end_time);
612
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
613
+ var endAt = _this6.toBookingDateTime(booking.end_date, booking.end_time);
556
614
  if (!startAt.isValid() || !endAt.isValid()) return false;
557
- return _this4.isSameOrAfter(current, startAt) && _this4.isSameOrBefore(current, endAt);
615
+ return _this6.isSameOrAfter(current, startAt) && _this6.isSameOrBefore(current, endAt);
558
616
  });
559
617
  if (activeBookings.length > 0) return appendNextStartGroupIfNeeded(activeBookings);
560
618
 
@@ -566,14 +624,14 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
566
624
 
567
625
  // upcoming: 从未来预约里只取最早那一组(同 start_time)
568
626
  var upcoming = dayScopedBookings.filter(function (booking) {
569
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
627
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
570
628
  return startAt.isValid() && startAt.isAfter(current);
571
629
  });
572
630
  if (upcoming.length > 0) {
573
631
  if (options.includeAllFuture) return upcoming;
574
632
  var firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
575
633
  var upcomingStartGroup = upcoming.filter(function (booking) {
576
- var startAt = _this4.toBookingDateTime(booking.start_date, booking.start_time);
634
+ var startAt = _this6.toBookingDateTime(booking.start_date, booking.start_time);
577
635
  return startAt.valueOf() === firstStartAt;
578
636
  });
579
637
  return appendNextStartGroupIfNeeded(upcomingStartGroup);
@@ -626,10 +684,10 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
626
684
  }, {
627
685
  key: "normalizeResourceBookings",
628
686
  value: function normalizeResourceBookings(current, deviceCurrent, bookingList) {
629
- var _this5 = this;
687
+ var _this7 = this;
630
688
  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
631
689
  var normalizedBookings = bookingList.map(function (booking) {
632
- return _this5.normalizeMatchedBooking(current, deviceCurrent, booking, options);
690
+ return _this7.normalizeMatchedBooking(current, deviceCurrent, booking, options);
633
691
  }).filter(function (booking) {
634
692
  return Boolean(booking);
635
693
  }).filter(function (booking) {
@@ -759,7 +817,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
759
817
  var _getResourceBookingList = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(currentTime) {
760
818
  var _resourceResponse$dat,
761
819
  _resourceResponse$dat2,
762
- _this6 = this;
820
+ _this8 = this;
763
821
  var bookingList,
764
822
  deviceTime,
765
823
  current,
@@ -815,16 +873,16 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
815
873
  rawBookingMap = this.groupBookingsByResource(bookingList);
816
874
  bookingMap = this.groupBookingsByResource(normalizedBookings); // 输出:每个资源都返回;bookings 可能是 0 / 1 / 多条(并发场景)
817
875
  list = resourceList.map(function (resource) {
818
- var resourceId = _this6.getResourceId(resource);
876
+ var resourceId = _this8.getResourceId(resource);
819
877
  var rawMatchedBookings = rawBookingMap.get(String(resourceId)) || [];
820
878
  var matchedBookings = bookingMap.get(String(resourceId)) || [];
821
879
  var statsBookings = rawMatchedBookings.filter(function (booking) {
822
- return _this6.isBookingIncludedInStats(booking);
880
+ return _this8.isBookingIncludedInStats(booking);
823
881
  });
824
- var orderCount = _this6.countBookingOrders(statsBookings);
882
+ var orderCount = _this8.countBookingOrders(statsBookings);
825
883
  var bookingCount = statsBookings.length;
826
- var compeleteBookingCount = _this6.countCompletedBookings(statsBookings);
827
- var bookings = _this6.pickBookingsForCurrentPoint(current, matchedBookings);
884
+ var compeleteBookingCount = _this8.countCompletedBookings(statsBookings);
885
+ var bookings = _this8.pickBookingsForCurrentPoint(current, matchedBookings);
828
886
  return _objectSpread(_objectSpread({}, resource), {}, {
829
887
  resource_id: resourceId,
830
888
  orderCount: orderCount,
@@ -861,7 +919,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
861
919
  var _getResourceBookingItem = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(params) {
862
920
  var _resourceResponse$dat3,
863
921
  _resourceResponse$dat4,
864
- _this7 = this,
922
+ _this9 = this,
865
923
  _params$bookingList;
866
924
  var current, deviceCurrent, resourceResponse, resourceList, targetResource, resourceId, matchedBookingList, statsBookingList, completedBookingList, unpaidBookingList, bookings, completedBookings, unpaidBookings, orderCount, bookingCount, compeleteBookingCount;
867
925
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
@@ -901,7 +959,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
901
959
  return _context6.abrupt("return", null);
902
960
  case 12:
903
961
  targetResource = resourceList.find(function (resource) {
904
- return String(_this7.getResourceId(resource)) === String(params.resourceId);
962
+ return String(_this9.getResourceId(resource)) === String(params.resourceId);
905
963
  });
906
964
  if (targetResource) {
907
965
  _context6.next = 15;
@@ -911,18 +969,18 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
911
969
  case 15:
912
970
  resourceId = this.getResourceId(targetResource);
913
971
  matchedBookingList = params.bookingList.filter(function (booking) {
914
- return _this7.isBookingMatchedResource(booking, resourceId);
972
+ return _this9.isBookingMatchedResource(booking, resourceId);
915
973
  });
916
974
  statsBookingList = matchedBookingList.filter(function (booking) {
917
- return _this7.isBookingIncludedInStats(booking);
975
+ return _this9.isBookingIncludedInStats(booking);
918
976
  });
919
977
  completedBookingList = matchedBookingList.filter(function (booking) {
920
- return _this7.getBookingAppointmentStatus(booking) === 'completed';
978
+ return _this9.getBookingAppointmentStatus(booking) === 'completed';
921
979
  }); // const unpaidBookingList = matchedBookingList.filter(
922
980
  // (booking) => this.getBookingOrderPaymentStatus(booking) === 'unpaid' || this.getBookingOrderPaymentStatus(booking) === 'payment_processing',
923
981
  // );
924
982
  unpaidBookingList = matchedBookingList.filter(function (booking) {
925
- return _this7.isUnpaidBooking(booking);
983
+ return _this9.isUnpaidBooking(booking);
926
984
  });
927
985
  bookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList), {
928
986
  includeAllFuture: true
@@ -938,9 +996,7 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
938
996
  remainingReserveTime: undefined
939
997
  });
940
998
  });
941
- unpaidBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList), {
942
- includeAllFuture: true
943
- });
999
+ unpaidBookings = this.buildUnpaidBookings(current, deviceCurrent, unpaidBookingList, bookings);
944
1000
  orderCount = this.countBookingOrders(statsBookingList);
945
1001
  bookingCount = statsBookingList.length;
946
1002
  compeleteBookingCount = this.countCompletedBookings(statsBookingList);
@@ -1 +1,46 @@
1
- "use strict";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _examples.BUY_X_GET_Y_FREE_STRATEGY;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _examples.ITEM_REWARD_STRATEGY;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "PromotionAdapter", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _adapter.PromotionAdapter;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "PromotionEvaluator", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _evaluator.PromotionEvaluator;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "default", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _adapter.default;
40
+ }
41
+ });
42
+ var _evaluator = require("./evaluator");
43
+ var _adapter = _interopRequireWildcard(require("./adapter"));
44
+ var _examples = require("./examples");
45
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
46
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -35,6 +35,8 @@ export interface SmallTicketProduct {
35
35
  original_price: string;
36
36
  total_original_price: string;
37
37
  extension_list: any[];
38
+ product_uid?: string | number;
39
+ booking_uid?: string | number;
38
40
  options?: Array<{
39
41
  name: string;
40
42
  num?: number;
@@ -44,6 +46,11 @@ export interface SmallTicketProduct {
44
46
  variant?: string;
45
47
  combinations?: any[];
46
48
  }
49
+ export interface SmallTicketBookingSnapshot extends Record<string, any> {
50
+ product_uid?: string | number;
51
+ booking_uid?: string | number;
52
+ }
53
+ export type SmallTicketAppointment = SmallTicketItem[] | SmallTicketBookingSnapshot[];
47
54
  export interface SmallTicketLocaleData {
48
55
  base_data: Record<string, any>;
49
56
  products: SmallTicketProduct[];
@@ -52,7 +59,7 @@ export interface SmallTicketLocaleData {
52
59
  countFee: Record<string, any>;
53
60
  };
54
61
  customer: SmallTicketItem[];
55
- appointment: SmallTicketItem[];
62
+ appointment: SmallTicketAppointment;
56
63
  delivery?: SmallTicketItem[];
57
64
  resources: Array<{
58
65
  id: string | number;
@@ -61,6 +68,7 @@ export interface SmallTicketLocaleData {
61
68
  form_title: string;
62
69
  }>;
63
70
  payment_data: SmallTicketItem[][];
71
+ wallets: SmallTicketItem[][];
64
72
  tickets: any[];
65
73
  source_shop: any[];
66
74
  refund_data: any[];
@@ -144,6 +144,11 @@ function buildLocaleData(params) {
144
144
  locale,
145
145
  currencySymbol
146
146
  }),
147
+ wallets: buildWallets({
148
+ order,
149
+ locale,
150
+ currencySymbol
151
+ }),
147
152
  tickets: Array.isArray(order.tickets) ? order.tickets : [],
148
153
  source_shop: [],
149
154
  refund_data: [],
@@ -169,7 +174,10 @@ function buildBaseData(params) {
169
174
  is_repeat: 0,
170
175
  buzzer: stringify(order.buzzer || order.pickup_number || order.metadata?.buzzer),
171
176
  order_no: orderNumber,
172
- order_time: formatDateTime(order.created_at || order.sales_time || new Date(), locale)
177
+ order_time: formatDateTime(order.created_at || order.sales_time || new Date(), locale),
178
+ ...(isPresentId(order.updated_at) ? {
179
+ updated_at: formatDateTime(order.updated_at, locale)
180
+ } : {})
173
181
  };
174
182
  }
175
183
  function buildProducts(order, locale, productMap) {
@@ -203,6 +211,8 @@ function buildProducts(order, locale, productMap) {
203
211
  parentProduct,
204
212
  locale
205
213
  });
214
+ const productUid = firstPresentValue(product.metadata?.unique_identification_number, product.unique_identification_number);
215
+ const bookingUid = firstPresentValue(product.booking_uid, product.metadata?.booking_uid);
206
216
  const extensionList = buildProductExtensionList({
207
217
  product,
208
218
  locale,
@@ -217,6 +227,12 @@ function buildProducts(order, locale, productMap) {
217
227
  original_price: formatMoney(originalPrice, currencySymbol),
218
228
  total_original_price: formatMoney(new _decimal.default(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
219
229
  extension_list: extensionList,
230
+ ...(isPresentId(productUid) ? {
231
+ product_uid: productUid
232
+ } : {}),
233
+ ...(isPresentId(bookingUid) ? {
234
+ booking_uid: bookingUid
235
+ } : {}),
220
236
  ...(options.length ? {
221
237
  options
222
238
  } : {}),
@@ -582,6 +598,9 @@ function isNonZeroId(value) {
582
598
  function isPresentId(value) {
583
599
  return value !== undefined && value !== null && value !== '';
584
600
  }
601
+ function firstPresentValue(...values) {
602
+ return values.find(value => isPresentId(value));
603
+ }
585
604
  function isSameId(left, right) {
586
605
  if (!isPresentId(left) || !isPresentId(right)) return false;
587
606
  return String(left) === String(right);
@@ -650,12 +669,13 @@ function buildFees(params) {
650
669
  });
651
670
  }
652
671
  const productExpectAmount = summary.product_expect_amount || summary.product_amount || order.product_expect_amount;
653
- const productOriginalAmount = summary.product_original_amount ?? order.product_original_amount ?? productExpectAmount;
672
+ const productOriginalAmount = firstPresentValue(summary.product_original_amount, order.product_original_amount) ?? calculateProductOriginalAmount(order);
654
673
  const totalSavingsAmount = new _decimal.default(toMoneyNumber(productOriginalAmount)).minus(toMoneyNumber(productExpectAmount)).plus(toMoneyNumber(discountAmount));
655
674
  return {
656
675
  fees,
657
676
  countFee: {
658
677
  total_amount: formatMoney(summary.total_amount || order.total_amount, currencySymbol),
678
+ original_item_amount: formatMoney(productOriginalAmount, currencySymbol),
659
679
  product_expect_amount: formatMoney(productExpectAmount, currencySymbol),
660
680
  expect_amount: formatMoney(summary.expect_amount || order.expect_amount || summary.total_amount || order.total_amount, currencySymbol),
661
681
  product_quantity: toNumber(summary.product_quantity || products.reduce((sum, product) => sum + product.product_quantity, 0), 0),
@@ -678,6 +698,13 @@ function buildFees(params) {
678
698
  }
679
699
  };
680
700
  }
701
+ function calculateProductOriginalAmount(order) {
702
+ return normalizeArray(order.products).reduce((total, product) => {
703
+ const quantity = toNumber(product.product_quantity ?? product.quantity ?? product.num ?? 1, 1);
704
+ const originalPrice = product.original_price ?? product.selling_price ?? product.payment_price ?? product.price ?? 0;
705
+ return total.plus(new _decimal.default(toMoneyNumber(originalPrice)).mul(quantity));
706
+ }, new _decimal.default(0));
707
+ }
681
708
  function buildCustomer(order, locale) {
682
709
  return [{
683
710
  item: label(locale, 'contactName'),
@@ -715,6 +742,27 @@ function buildDelivery(order, locale) {
715
742
  return items;
716
743
  }
717
744
  function buildAppointment(order, locale) {
745
+ const bookings = normalizeArray(order.bookings);
746
+ if (bookings.length) {
747
+ return bookings.map(booking => {
748
+ const snapshot = {
749
+ ...booking
750
+ };
751
+ delete snapshot.product_uid;
752
+ delete snapshot.booking_uid;
753
+ const productUid = firstPresentValue(booking.product_uid, booking.metadata?.product_uid);
754
+ const bookingUid = firstPresentValue(booking.metadata?.unique_identification_number, booking.booking_uid);
755
+ return {
756
+ ...snapshot,
757
+ ...(isPresentId(productUid) ? {
758
+ product_uid: productUid
759
+ } : {}),
760
+ ...(isPresentId(bookingUid) ? {
761
+ booking_uid: bookingUid
762
+ } : {})
763
+ };
764
+ });
765
+ }
718
766
  const tableName = order.table_name || order.metadata?.table_name || order.metadata?.table?.name || order.form_data?.table_name;
719
767
  if (!tableName) return [];
720
768
  return [{
@@ -732,41 +780,62 @@ function buildResources(order, locale) {
732
780
  }
733
781
  function buildPaymentData(params) {
734
782
  const payments = normalizeArray(params.order.payments);
735
- return payments.filter(payment => isPrintablePayment(payment)).map(payment => {
736
- const serviceFee = getPaymentServiceFee(payment);
737
- const items = [{
738
- item: paymentMethodName(payment, params.locale),
739
- value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), params.currencySymbol)
740
- }];
741
- if (serviceFee.gt(0)) {
783
+ return payments.filter(payment => isPrintablePayment(payment)).map(payment => buildPaymentItems({
784
+ payment,
785
+ locale: params.locale,
786
+ currencySymbol: params.currencySymbol,
787
+ includeFundRecordBalance: false
788
+ }));
789
+ }
790
+ function buildWallets(params) {
791
+ return normalizeArray(params.order.payments).filter(payment => isPrintablePayment(payment) && !!getFundRecord(payment)).map(payment => buildPaymentItems({
792
+ payment,
793
+ locale: params.locale,
794
+ currencySymbol: params.currencySymbol,
795
+ includeFundRecordBalance: true
796
+ }));
797
+ }
798
+ function buildPaymentItems(params) {
799
+ const {
800
+ payment,
801
+ locale,
802
+ currencySymbol,
803
+ includeFundRecordBalance
804
+ } = params;
805
+ const serviceFee = getPaymentServiceFee(payment);
806
+ const items = [{
807
+ item: paymentMethodName(payment, locale),
808
+ value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), currencySymbol)
809
+ }];
810
+ if (serviceFee.gt(0)) {
811
+ items.push({
812
+ item: label(locale, 'surchargeIncluded'),
813
+ value: formatMoney(serviceFee, currencySymbol)
814
+ });
815
+ }
816
+ const fundRecord = getFundRecord(payment);
817
+ if (fundRecord) {
818
+ items.push(...buildFundRecordPaymentItems({
819
+ payment,
820
+ fundRecord,
821
+ locale,
822
+ currencySymbol,
823
+ includeBalance: includeFundRecordBalance
824
+ }));
825
+ } else {
826
+ const remainingAmount = payment.remaining_amount ?? payment.balance ?? payment.metadata?.remaining_amount;
827
+ if (remainingAmount !== undefined && remainingAmount !== null) {
742
828
  items.push({
743
- item: label(params.locale, 'surchargeIncluded'),
744
- value: formatMoney(serviceFee, params.currencySymbol)
829
+ item: label(locale, 'remainingAmount'),
830
+ value: formatMoney(remainingAmount, currencySymbol)
745
831
  });
746
832
  }
747
- const fundRecord = getFundRecord(payment);
748
- if (fundRecord) {
749
- items.push(...buildFundRecordPaymentItems({
750
- payment,
751
- fundRecord,
752
- locale: params.locale,
753
- currencySymbol: params.currencySymbol
754
- }));
755
- } else {
756
- const remainingAmount = payment.remaining_amount ?? payment.balance ?? payment.metadata?.remaining_amount;
757
- if (remainingAmount !== undefined && remainingAmount !== null) {
758
- items.push({
759
- item: label(params.locale, 'remainingAmount'),
760
- value: formatMoney(remainingAmount, params.currencySymbol)
761
- });
762
- }
763
- }
764
- items.push({
765
- item: formatDateTime(payment.paid_at || payment.created_at || payment.updated_at || new Date(), params.locale),
766
- value: ''
767
- });
768
- return items;
833
+ }
834
+ items.push({
835
+ item: formatDateTime(payment.paid_at || payment.created_at || payment.updated_at || new Date(), locale),
836
+ value: ''
769
837
  });
838
+ return items;
770
839
  }
771
840
  function getPaymentServiceFee(payment) {
772
841
  return new _decimal.default(toMoneyNumber(payment.service_fee));
@@ -784,7 +853,8 @@ function buildFundRecordPaymentItems(params) {
784
853
  payment,
785
854
  fundRecord,
786
855
  locale,
787
- currencySymbol
856
+ currencySymbol,
857
+ includeBalance
788
858
  } = params;
789
859
  const items = [];
790
860
  const usingBeforeValue = fundRecord.using_before_value;
@@ -795,13 +865,15 @@ function buildFundRecordPaymentItems(params) {
795
865
  item: label(locale, 'redeemPoints'),
796
866
  value: trimDecimal(usedPoints)
797
867
  });
798
- items.push({
799
- item: label(locale, 'remainingPoints'),
800
- value: trimDecimal(new _decimal.default(toMoneyNumber(usingAfterValue)))
801
- });
868
+ if (includeBalance) {
869
+ items.push({
870
+ item: label(locale, 'remainingPoints'),
871
+ value: trimDecimal(new _decimal.default(toMoneyNumber(usingAfterValue)))
872
+ });
873
+ }
802
874
  return items;
803
875
  }
804
- if (usingAfterValue !== undefined && usingAfterValue !== null) {
876
+ if (includeBalance && usingAfterValue !== undefined && usingAfterValue !== null) {
805
877
  items.push({
806
878
  item: label(locale, 'remainingAmount'),
807
879
  value: formatMoney(usingAfterValue, currencySymbol)
@@ -90,6 +90,13 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
90
90
  private groupBookingsByResource;
91
91
  private isBookingMatchedResource;
92
92
  private sortMatchedBookings;
93
+ /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
94
+ private sortUnpaidBookings;
95
+ /**
96
+ * 构造资源详情的 Unpaid 列表:复用旧版当前/未来订单的展示计算,再补齐被预约状态/时间漏掉的欠款订单。
97
+ * Unpaid 的成员资格由调用方按付款状态筛好;这里仅负责展示字段与顺序。
98
+ */
99
+ private buildUnpaidBookings;
93
100
  /**
94
101
  * 资源下 bookings 的返回裁剪策略:
95
102
  * 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
@@ -340,6 +340,53 @@ class SalesImpl extends _BaseModule.BaseModule {
340
340
  });
341
341
  }
342
342
 
343
+ /** Unpaid:与 Current 重合的订单沿用 Current 顺序,其余欠款订单按开始时间降序追加。 */
344
+ sortUnpaidBookings(bookings, currentBookings) {
345
+ const currentOrderIndexes = new Map(currentBookings.map((booking, index) => [String(booking.order.order_id), index]));
346
+ return [...bookings].sort((left, right) => {
347
+ const leftIndex = currentOrderIndexes.get(String(left.order.order_id));
348
+ const rightIndex = currentOrderIndexes.get(String(right.order.order_id));
349
+ if (leftIndex !== undefined || rightIndex !== undefined) {
350
+ if (leftIndex === undefined) return 1;
351
+ if (rightIndex === undefined) return -1;
352
+ return leftIndex - rightIndex;
353
+ }
354
+ const leftStartAt = this.toBookingDateTime(left.start_date, left.start_time).valueOf();
355
+ const rightStartAt = this.toBookingDateTime(right.start_date, right.start_time).valueOf();
356
+ return rightStartAt - leftStartAt;
357
+ });
358
+ }
359
+
360
+ /**
361
+ * 构造资源详情的 Unpaid 列表:复用旧版当前/未来订单的展示计算,再补齐被预约状态/时间漏掉的欠款订单。
362
+ * Unpaid 的成员资格由调用方按付款状态筛好;这里仅负责展示字段与顺序。
363
+ */
364
+ buildUnpaidBookings(current, deviceCurrent, unpaidBookingList, currentBookings) {
365
+ const legacyPrioritizedBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList), {
366
+ includeAllFuture: true
367
+ });
368
+ const allBookings = this.sortMatchedBookings(unpaidBookingList.map(booking => {
369
+ const normalized = this.normalizeMatchedBooking(current, deviceCurrent, booking, {
370
+ includeCompleted: true
371
+ });
372
+ if (normalized) return normalized;
373
+ const appointmentStatus = this.getBookingAppointmentStatus(booking);
374
+ const status = appointmentStatus === 'started' ? 'occupied' : appointmentStatus === 'completed' ? 'completed' : 'reserved';
375
+ return {
376
+ ...booking,
377
+ status,
378
+ isTimeout: false,
379
+ timeoutTime: undefined,
380
+ progressPercent: undefined,
381
+ lateTime: undefined,
382
+ reserved_status: undefined,
383
+ remainingReserveTime: undefined
384
+ };
385
+ }));
386
+ const legacyOrderIds = new Set(legacyPrioritizedBookings.map(booking => String(booking.order.order_id)));
387
+ return this.sortUnpaidBookings([...legacyPrioritizedBookings, ...allBookings.filter(booking => !legacyOrderIds.has(String(booking.order.order_id)))], currentBookings);
388
+ }
389
+
343
390
  /**
344
391
  * 资源下 bookings 的返回裁剪策略:
345
392
  * 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
@@ -679,9 +726,7 @@ class SalesImpl extends _BaseModule.BaseModule {
679
726
  remainingReserveTime: undefined
680
727
  };
681
728
  });
682
- const unpaidBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList), {
683
- includeAllFuture: true
684
- });
729
+ const unpaidBookings = this.buildUnpaidBookings(current, deviceCurrent, unpaidBookingList, bookings);
685
730
  const orderCount = this.countBookingOrders(statsBookingList);
686
731
  const bookingCount = statsBookingList.length;
687
732
  const compeleteBookingCount = this.countCompletedBookings(statsBookingList);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.96",
4
+ "version": "2.3.98",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",