@pisell/pisellos 2.3.93 → 2.3.95

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 (75) hide show
  1. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  2. package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
  3. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  4. package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
  5. package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
  6. package/dist/model/strategy/adapter/itemRule/type.js +19 -1
  7. package/dist/modules/Order/index.d.ts +18 -3
  8. package/dist/modules/Order/index.js +885 -485
  9. package/dist/modules/Order/salesNotes.d.ts +31 -0
  10. package/dist/modules/Order/salesNotes.js +492 -0
  11. package/dist/modules/Order/types.d.ts +91 -5
  12. package/dist/modules/Order/types.js +5 -0
  13. package/dist/modules/Order/utils.d.ts +12 -0
  14. package/dist/modules/Order/utils.js +75 -26
  15. package/dist/modules/ProductList/index.d.ts +2 -1
  16. package/dist/modules/ProductList/index.js +100 -20
  17. package/dist/modules/ProductList/types.d.ts +10 -0
  18. package/dist/modules/ResourcePlanner/planner.js +5 -3
  19. package/dist/modules/ResourcePlanner/types.d.ts +5 -0
  20. package/dist/server/index.d.ts +6 -0
  21. package/dist/server/index.js +43 -3
  22. package/dist/solution/BaseSales/index.d.ts +9 -1
  23. package/dist/solution/BaseSales/index.js +894 -706
  24. package/dist/solution/BookingByStep/index.d.ts +2 -2
  25. package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
  26. package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
  27. package/dist/solution/RegisterAndLogin/config.js +95 -40
  28. package/dist/solution/RegisterAndLogin/index.js +4 -1
  29. package/dist/solution/ScanOrder/index.d.ts +1 -0
  30. package/dist/solution/ScanOrder/index.js +31 -27
  31. package/dist/solution/ScanOrder/utils.d.ts +1 -0
  32. package/dist/solution/ScanOrder/utils.js +2 -0
  33. package/dist/solution/UnifiedBookingSales/index.d.ts +15 -2
  34. package/dist/solution/UnifiedBookingSales/index.js +767 -488
  35. package/dist/solution/UnifiedBookingSales/types.d.ts +14 -1
  36. package/dist/solution/VenueBooking/index.d.ts +1 -0
  37. package/dist/solution/VenueBooking/index.js +8 -4
  38. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  39. package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
  40. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  41. package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
  42. package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
  43. package/lib/model/strategy/adapter/itemRule/type.js +19 -1
  44. package/lib/modules/Order/index.d.ts +18 -3
  45. package/lib/modules/Order/index.js +325 -28
  46. package/lib/modules/Order/salesNotes.d.ts +31 -0
  47. package/lib/modules/Order/salesNotes.js +382 -0
  48. package/lib/modules/Order/types.d.ts +91 -5
  49. package/lib/modules/Order/types.js +4 -0
  50. package/lib/modules/Order/utils.d.ts +12 -0
  51. package/lib/modules/Order/utils.js +68 -16
  52. package/lib/modules/ProductList/index.d.ts +2 -1
  53. package/lib/modules/ProductList/index.js +47 -2
  54. package/lib/modules/ProductList/types.d.ts +10 -0
  55. package/lib/modules/ResourcePlanner/planner.js +5 -3
  56. package/lib/modules/ResourcePlanner/types.d.ts +5 -0
  57. package/lib/server/index.d.ts +6 -0
  58. package/lib/server/index.js +37 -3
  59. package/lib/solution/BaseSales/index.d.ts +9 -1
  60. package/lib/solution/BaseSales/index.js +105 -1
  61. package/lib/solution/BookingByStep/index.d.ts +2 -2
  62. package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
  63. package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
  64. package/lib/solution/RegisterAndLogin/config.js +49 -8
  65. package/lib/solution/RegisterAndLogin/index.js +4 -1
  66. package/lib/solution/ScanOrder/index.d.ts +1 -0
  67. package/lib/solution/ScanOrder/index.js +5 -1
  68. package/lib/solution/ScanOrder/utils.d.ts +1 -0
  69. package/lib/solution/ScanOrder/utils.js +1 -0
  70. package/lib/solution/UnifiedBookingSales/index.d.ts +15 -2
  71. package/lib/solution/UnifiedBookingSales/index.js +140 -6
  72. package/lib/solution/UnifiedBookingSales/types.d.ts +14 -1
  73. package/lib/solution/VenueBooking/index.d.ts +1 -0
  74. package/lib/solution/VenueBooking/index.js +5 -1
  75. package/package.json +1 -1
@@ -64,6 +64,11 @@ export var OrderHooks = /*#__PURE__*/function (OrderHooks) {
64
64
  * 清空时整个 payload 为 null。
65
65
  */
66
66
 
67
+ /**
68
+ * Sales Notes 乐观写入前的可恢复快照。
69
+ * 该对象应视为 opaque token,只用于原样传回 restoreSalesNotesMutationSnapshot。
70
+ */
71
+
67
72
  /**
68
73
  * 添加商品行时的顺序控制。
69
74
  * 默认追加到 products 尾部;预约数量同步可插入到既有预约组的最新行之后,
@@ -210,6 +210,18 @@ export interface SubmitPayloadEnhancerContext {
210
210
  now: Date;
211
211
  }
212
212
  export type SubmitPayloadEnhancer = (payload: OrderSubmitPayload, ctx: SubmitPayloadEnhancerContext) => OrderSubmitPayload;
213
+ /**
214
+ * 解析 checkout 的订单类型。
215
+ * dine_in 普通落库单在新增桌台资源后,即使原类型仍是 virtual,也必须按 table-order 提交。
216
+ */
217
+ export declare function resolveSubmitOrderType(params: {
218
+ requestedType?: string;
219
+ tempOrderType?: string;
220
+ orderId?: unknown;
221
+ businessCode?: string;
222
+ tempOrderBusinessCode?: string;
223
+ bookings?: unknown;
224
+ }): string;
213
225
  export declare function buildSubmitPayload(params: {
214
226
  tempOrder: OrderTempOrder;
215
227
  cacheId?: string;
@@ -1,7 +1,7 @@
1
1
  var _excluded = ["custom_product_bundle_map_id"],
2
2
  _excluded2 = ["unique_identification_number"],
3
3
  _excluded3 = ["num", "surcharge_fee", "discount_amount", "discount_type", "discountway", "product_discount_reason", "discount_per", "production_code"],
4
- _excluded4 = ["_extend", "relation_id", "table_form_id", "resource_id", "summary", "lastOrderInfo", "paid_amount", "shop_id", "shop_note", "shop_service_type", "start_time", "customer", "discount_list", "tax_fee", "total_amount", "total_refund_amount", "create_date", "holder_id"],
4
+ _excluded4 = ["_extend", "relation_id", "table_form_id", "resource_id", "summary", "lastOrderInfo", "paid_amount", "shop_id", "shop_note", "shop_service_type", "start_time", "customer", "discount_list", "tax_fee", "total_amount", "total_refund_amount", "create_date", "holder_id", "notes"],
5
5
  _excluded5 = ["collect_pax", "table_occupancy_duration"];
6
6
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
7
7
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
@@ -23,6 +23,7 @@ import Decimal from 'decimal.js';
23
23
  import { getProductHolderConfig } from "../Holder/utils";
24
24
  import { buildProductLineFingerprint, createEmptySummary } from "../../solution/ScanOrder/utils";
25
25
  import { createUuidV4 } from "./utils/orderCollectionIdentity";
26
+ import { encodeSalesNotes } from "./salesNotes";
26
27
  /**
27
28
  * 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
28
29
  *
@@ -1088,6 +1089,7 @@ export function createDefaultTempOrder(params) {
1088
1089
  request_unique_idempotency_token: '',
1089
1090
  vouchers: [],
1090
1091
  products: [],
1092
+ notes: [],
1091
1093
  bookings: [],
1092
1094
  payments: [],
1093
1095
  surcharges: [],
@@ -1097,12 +1099,59 @@ export function createDefaultTempOrder(params) {
1097
1099
  holder: null,
1098
1100
  metadata: {},
1099
1101
  _extend: {
1100
- productsByUid: {}
1102
+ productsByUid: {},
1103
+ salesNotesState: {
1104
+ loaded: true,
1105
+ dirty: false
1106
+ }
1101
1107
  }
1102
1108
  };
1103
1109
  }
1110
+ function hasBoundBookingResource(bookings) {
1111
+ if (!Array.isArray(bookings)) return false;
1112
+ return bookings.some(function (booking) {
1113
+ if (!booking || _typeof(booking) !== 'object') return false;
1114
+ if (Number(booking.parent_id) === 0) return false;
1115
+ var resources = booking.resources;
1116
+ if (!Array.isArray(resources)) return false;
1117
+ return resources.some(function (resource) {
1118
+ var _relation_id;
1119
+ if (!resource || _typeof(resource) !== 'object') return false;
1120
+ var relationId = String((_relation_id = resource.relation_id) !== null && _relation_id !== void 0 ? _relation_id : '').trim();
1121
+ return relationId !== '' && relationId !== '0';
1122
+ });
1123
+ });
1124
+ }
1125
+ function isPersistedSubmitOrderId(orderId) {
1126
+ if (orderId === undefined || orderId === null || orderId === '') return false;
1127
+ var normalizedOrderId = Number(orderId);
1128
+ return Number.isFinite(normalizedOrderId) && normalizedOrderId > 0;
1129
+ }
1130
+
1131
+ /**
1132
+ * 解析 checkout 的订单类型。
1133
+ * dine_in 普通落库单在新增桌台资源后,即使原类型仍是 virtual,也必须按 table-order 提交。
1134
+ */
1135
+ export function resolveSubmitOrderType(params) {
1136
+ var requestedType = params.requestedType,
1137
+ tempOrderType = params.tempOrderType,
1138
+ orderId = params.orderId,
1139
+ businessCode = params.businessCode,
1140
+ tempOrderBusinessCode = params.tempOrderBusinessCode,
1141
+ bookings = params.bookings;
1142
+ var currentType = requestedType !== null && requestedType !== void 0 ? requestedType : tempOrderType;
1143
+ var resolvedBusinessCode = businessCode !== null && businessCode !== void 0 ? businessCode : tempOrderBusinessCode;
1144
+ if (isPersistedSubmitOrderId(orderId) && resolvedBusinessCode === 'dine_in' && currentType === 'virtual' && hasBoundBookingResource(bookings)) {
1145
+ return 'table-order';
1146
+ }
1147
+ if (currentType) return currentType;
1148
+ if (Array.isArray(bookings) && bookings.length > 0) {
1149
+ return businessCode === 'dine_in' ? 'table-order' : 'appointment_booking';
1150
+ }
1151
+ return 'virtual';
1152
+ }
1104
1153
  export function buildSubmitPayload(params) {
1105
- var _tempOrder$customer_i, _tempOrder$country_ca, _tempOrder$phone, _tempOrder$email, _tempOrder$order_numb, _tempOrder$shop_order, _tempOrder$shop_full_, _ref31, _tempOrder$is_price_i, _tempOrder$is_deposit, _enhancedPayload$summ;
1154
+ var _tempOrder$customer_i, _tempOrder$country_ca, _tempOrder$phone, _tempOrder$email, _tempOrder$order_numb, _tempOrder$shop_order, _tempOrder$shop_full_, _ref31, _tempOrder$is_price_i, _tempOrder$is_deposit, _tempOrder$_extend, _enhancedPayload$summ;
1106
1155
  var tempOrder = params.tempOrder,
1107
1156
  cacheId = params.cacheId,
1108
1157
  _params$now = params.now,
@@ -1134,23 +1183,18 @@ export function buildSubmitPayload(params) {
1134
1183
  _totalRefundAmount = _ref30.total_refund_amount,
1135
1184
  _createDate = _ref30.create_date,
1136
1185
  _holderId = _ref30.holder_id,
1186
+ _notes = _ref30.notes,
1137
1187
  tempOrderRest = _objectWithoutProperties(_ref30, _excluded4);
1138
- var submitType = type !== null && type !== void 0 ? type : tempOrder.type;
1139
- if (!submitType) {
1140
- var _tempOrder$bookings;
1141
- // 如果外部没有传递 types,根据订单里当前是否有 bookings 来决定是 appointment_booking 还是 virtual
1142
- if (tempOrder !== null && tempOrder !== void 0 && (_tempOrder$bookings = tempOrder.bookings) !== null && _tempOrder$bookings !== void 0 && _tempOrder$bookings.length) {
1143
- // 260807 如果 biz 是堂食,type 使用table-order
1144
- if (businessCode === 'dine_in') {
1145
- submitType = 'table-order';
1146
- } else {
1147
- submitType = 'appointment_booking';
1148
- }
1149
- } else {
1150
- submitType = 'virtual';
1151
- }
1152
- }
1153
- var payload = _objectSpread(_objectSpread({}, tempOrderRest), {}, {
1188
+ var resolvedBusinessCode = businessCode !== null && businessCode !== void 0 ? businessCode : tempOrder.business_code;
1189
+ var submitType = resolveSubmitOrderType({
1190
+ requestedType: type,
1191
+ tempOrderType: tempOrder.type,
1192
+ orderId: tempOrder.order_id,
1193
+ businessCode: businessCode,
1194
+ tempOrderBusinessCode: tempOrder.business_code,
1195
+ bookings: tempOrder.bookings
1196
+ });
1197
+ var payload = _objectSpread(_objectSpread(_objectSpread({}, tempOrderRest), {}, {
1154
1198
  customer_id: (_tempOrder$customer_i = tempOrder.customer_id) !== null && _tempOrder$customer_i !== void 0 ? _tempOrder$customer_i : 1,
1155
1199
  customer_name: tempOrder.customer_name || 'Walk-In',
1156
1200
  country_calling_code: String((_tempOrder$country_ca = tempOrder.country_calling_code) !== null && _tempOrder$country_ca !== void 0 ? _tempOrder$country_ca : ''),
@@ -1162,7 +1206,7 @@ export function buildSubmitPayload(params) {
1162
1206
  platform: normalizeSubmitPlatform(platform),
1163
1207
  request_unique_idempotency_token: (params === null || params === void 0 ? void 0 : params.request_unique_idempotency_token) || tempOrder.request_unique_idempotency_token || "".concat(tempOrder.external_sale_number, "_").concat(now.getTime()),
1164
1208
  type: submitType,
1165
- business_code: businessCode !== null && businessCode !== void 0 ? businessCode : tempOrder.business_code,
1209
+ business_code: resolvedBusinessCode,
1166
1210
  sales_channel: tempOrder.sales_channel || 'my_pisel',
1167
1211
  order_sales_channel: (_ref31 = channel !== null && channel !== void 0 ? channel : tempOrder.order_sales_channel) !== null && _ref31 !== void 0 ? _ref31 : 'online_store',
1168
1212
  status: tempOrder.status || 'normal',
@@ -1195,7 +1239,12 @@ export function buildSubmitPayload(params) {
1195
1239
  _tableOccupancyDuration = _ref32.table_occupancy_duration,
1196
1240
  rest = _objectWithoutProperties(_ref32, _excluded5);
1197
1241
  return _objectSpread({}, rest);
1198
- }(),
1242
+ }()
1243
+ }, (_tempOrder$_extend = tempOrder._extend) !== null && _tempOrder$_extend !== void 0 && (_tempOrder$_extend = _tempOrder$_extend.salesNotesState) !== null && _tempOrder$_extend !== void 0 && _tempOrder$_extend.dirty ? {
1244
+ notes: encodeSalesNotes(tempOrder.notes || [], {
1245
+ allowUnresolvedOrderTarget: true
1246
+ })
1247
+ } : {}), {}, {
1199
1248
  products: (tempOrder.products || []).map(function (product) {
1200
1249
  return normalizeSubmitProduct(product);
1201
1250
  })
@@ -1323,7 +1372,7 @@ export function hasAssignedHolderId(value) {
1323
1372
  * clearTempOrderHolderAssignments(tempOrder);
1324
1373
  */
1325
1374
  export function clearTempOrderHolderAssignments(tempOrder) {
1326
- var _tempOrder$_extend;
1375
+ var _tempOrder$_extend2;
1327
1376
  var changed = false;
1328
1377
  var resetHolderField = function resetHolderField(target) {
1329
1378
  var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'holder_id';
@@ -1364,7 +1413,7 @@ export function clearTempOrderHolderAssignments(tempOrder) {
1364
1413
  } finally {
1365
1414
  _iterator9.f();
1366
1415
  }
1367
- var productsByUid = (_tempOrder$_extend = tempOrder._extend) === null || _tempOrder$_extend === void 0 ? void 0 : _tempOrder$_extend.productsByUid;
1416
+ var productsByUid = (_tempOrder$_extend2 = tempOrder._extend) === null || _tempOrder$_extend2 === void 0 ? void 0 : _tempOrder$_extend2.productsByUid;
1368
1417
  if (productsByUid && _typeof(productsByUid) === 'object') {
1369
1418
  for (var _i4 = 0, _Object$values = Object.values(productsByUid); _i4 < _Object$values.length; _i4++) {
1370
1419
  var entry = _Object$values[_i4];
@@ -1395,9 +1444,9 @@ export function getOrderProductLineUid(product) {
1395
1444
  return String(uid);
1396
1445
  }
1397
1446
  export function getRuntimeProductOrigin(tempOrder, product) {
1398
- var _tempOrder$_extend2, _tempOrder$_extend3;
1447
+ var _tempOrder$_extend3, _tempOrder$_extend4;
1399
1448
  var uid = getOrderProductLineUid(product);
1400
- if (uid && tempOrder !== null && tempOrder !== void 0 && (_tempOrder$_extend2 = tempOrder._extend) !== null && _tempOrder$_extend2 !== void 0 && (_tempOrder$_extend2 = _tempOrder$_extend2.productsByUid) !== null && _tempOrder$_extend2 !== void 0 && (_tempOrder$_extend2 = _tempOrder$_extend2[uid]) !== null && _tempOrder$_extend2 !== void 0 && _tempOrder$_extend2.origin) {
1449
+ if (uid && tempOrder !== null && tempOrder !== void 0 && (_tempOrder$_extend3 = tempOrder._extend) !== null && _tempOrder$_extend3 !== void 0 && (_tempOrder$_extend3 = _tempOrder$_extend3.productsByUid) !== null && _tempOrder$_extend3 !== void 0 && (_tempOrder$_extend3 = _tempOrder$_extend3[uid]) !== null && _tempOrder$_extend3 !== void 0 && _tempOrder$_extend3.origin) {
1401
1450
  return tempOrder._extend.productsByUid[uid].origin;
1402
1451
  }
1403
1452
  var matchedProduct = ((tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.products) || []).find(function (item) {
@@ -1405,7 +1454,7 @@ export function getRuntimeProductOrigin(tempOrder, product) {
1405
1454
  return item === product || getOrderProductLineUid(item) === uid || String((_ref33 = (_item$product_id = item === null || item === void 0 ? void 0 : item.product_id) !== null && _item$product_id !== void 0 ? _item$product_id : item === null || item === void 0 ? void 0 : item.id) !== null && _ref33 !== void 0 ? _ref33 : '') === String((_ref34 = (_product$product_id = product === null || product === void 0 ? void 0 : product.product_id) !== null && _product$product_id !== void 0 ? _product$product_id : product === null || product === void 0 ? void 0 : product.id) !== null && _ref34 !== void 0 ? _ref34 : '');
1406
1455
  });
1407
1456
  var matchedUid = matchedProduct ? getOrderProductLineUid(matchedProduct) : '';
1408
- return matchedUid ? (tempOrder === null || tempOrder === void 0 || (_tempOrder$_extend3 = tempOrder._extend) === null || _tempOrder$_extend3 === void 0 || (_tempOrder$_extend3 = _tempOrder$_extend3.productsByUid) === null || _tempOrder$_extend3 === void 0 || (_tempOrder$_extend3 = _tempOrder$_extend3[matchedUid]) === null || _tempOrder$_extend3 === void 0 ? void 0 : _tempOrder$_extend3.origin) || null : null;
1457
+ return matchedUid ? (tempOrder === null || tempOrder === void 0 || (_tempOrder$_extend4 = tempOrder._extend) === null || _tempOrder$_extend4 === void 0 || (_tempOrder$_extend4 = _tempOrder$_extend4.productsByUid) === null || _tempOrder$_extend4 === void 0 || (_tempOrder$_extend4 = _tempOrder$_extend4[matchedUid]) === null || _tempOrder$_extend4 === void 0 ? void 0 : _tempOrder$_extend4.origin) || null : null;
1409
1458
  }
1410
1459
  export function isHolderConfigRequired(holderConfig) {
1411
1460
  if (!holderConfig || _typeof(holderConfig) !== 'object') return false;
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { ProductListLoadProductsParams } from './types';
3
+ import { ProductListLoadProductsParams, ProductListStoreQueryParams } from './types';
4
4
  import { ProductData } from '../Product/types';
5
5
  export * from './types';
6
6
  export declare class ProductList extends BaseModule implements Module {
@@ -52,6 +52,7 @@ export declare class ProductList extends BaseModule implements Module {
52
52
  getRawProductPriceSources(ids: number[]): Map<number, ProductData>;
53
53
  getProducts(): Promise<ProductData[]>;
54
54
  getProduct(id: number): Promise<ProductData | undefined>;
55
+ queryProducts(params?: ProductListStoreQueryParams): Promise<ProductData[]>;
55
56
  getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
56
57
  addProduct(products: ProductData[]): Promise<void>;
57
58
  selectProducts(products: ProductData[]): Promise<void>;
@@ -29,6 +29,19 @@ import dayjs from 'dayjs';
29
29
  import { isProductQueryHandledByOsServer, PRODUCT_QUERY_DATA_VARIANT_RELATIONS, resolveClientDataVariants } from "./clientDataVariants";
30
30
  import { isCustomerUserPlatform } from "../../utils/platform";
31
31
  export * from "./types";
32
+ function normalizeQuerySet(values) {
33
+ if (!Array.isArray(values) || values.length === 0) return null;
34
+ var normalized = values.map(function (value) {
35
+ return String(value !== null && value !== void 0 ? value : '').trim();
36
+ }).filter(Boolean);
37
+ return normalized.length ? new Set(normalized) : null;
38
+ }
39
+ function matchesAny(values, querySet) {
40
+ if (!querySet) return true;
41
+ return values.some(function (value) {
42
+ return querySet.has(String(value !== null && value !== void 0 ? value : '').trim());
43
+ });
44
+ }
32
45
  export var ProductList = /*#__PURE__*/function (_BaseModule) {
33
46
  _inherits(ProductList, _BaseModule);
34
47
  var _super = _createSuper(ProductList);
@@ -468,26 +481,93 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
468
481
  return getProduct;
469
482
  }()
470
483
  }, {
471
- key: "getProductByIds",
484
+ key: "queryProducts",
472
485
  value: function () {
473
- var _getProductByIds = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(ids) {
474
- var products;
486
+ var _queryProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
487
+ var params,
488
+ includeIds,
489
+ excludeIds,
490
+ categoryIds,
491
+ collectionIds,
492
+ extensionTypes,
493
+ statuses,
494
+ channelApplications,
495
+ codeOrBarcode,
496
+ products,
497
+ _args9 = arguments;
475
498
  return _regeneratorRuntime().wrap(function _callee9$(_context9) {
476
499
  while (1) switch (_context9.prev = _context9.next) {
477
500
  case 0:
478
- _context9.next = 2;
479
- return this.core.effects.emit("".concat(this.name, ":onGetProductByIds"), this.store.list);
480
- case 2:
481
- products = this.store.list.filter(function (product) {
482
- return ids.includes(product.id);
501
+ params = _args9.length > 0 && _args9[0] !== undefined ? _args9[0] : {};
502
+ includeIds = normalizeQuerySet(params.includeIds);
503
+ excludeIds = normalizeQuerySet(params.excludeIds);
504
+ categoryIds = normalizeQuerySet(params.categoryIds);
505
+ collectionIds = normalizeQuerySet(params.collectionIds);
506
+ extensionTypes = normalizeQuerySet(params.extensionTypes);
507
+ statuses = normalizeQuerySet(params.statuses);
508
+ channelApplications = normalizeQuerySet(params.channelApplications);
509
+ codeOrBarcode = typeof params.codeOrBarcode === 'string' ? params.codeOrBarcode.trim() : '';
510
+ products = (this.store.list || []).filter(function (product) {
511
+ var _product$id, _product$extension_ty, _product$status;
512
+ var productId = String((_product$id = product.id) !== null && _product$id !== void 0 ? _product$id : '').trim();
513
+ if (includeIds && !includeIds.has(productId)) return false;
514
+ if (excludeIds && excludeIds.has(productId)) return false;
515
+ if (categoryIds) {
516
+ var productCategoryIds = (product.categories || []).flatMap(function (category) {
517
+ var _category$pivot;
518
+ return [category === null || category === void 0 ? void 0 : category.id, category === null || category === void 0 || (_category$pivot = category.pivot) === null || _category$pivot === void 0 ? void 0 : _category$pivot.product_category_id];
519
+ });
520
+ if (!matchesAny(productCategoryIds, categoryIds)) return false;
521
+ }
522
+ if (collectionIds) {
523
+ var productCollectionIds = (product.collection || []).map(function (collection) {
524
+ return collection === null || collection === void 0 ? void 0 : collection.id;
525
+ });
526
+ if (!matchesAny(productCollectionIds, collectionIds)) return false;
527
+ }
528
+ if (extensionTypes && !extensionTypes.has(String((_product$extension_ty = product.extension_type) !== null && _product$extension_ty !== void 0 ? _product$extension_ty : '').trim())) return false;
529
+ if (statuses && !statuses.has(String((_product$status = product.status) !== null && _product$status !== void 0 ? _product$status : '').trim())) return false;
530
+ if (channelApplications) {
531
+ if (!matchesAny(product.channel_application || [], channelApplications)) return false;
532
+ }
533
+ if (codeOrBarcode) {
534
+ var code = typeof product.code === 'string' ? product.code.trim() : '';
535
+ var barcode = typeof product.barcode === 'string' ? product.barcode.trim() : '';
536
+ if (code !== codeOrBarcode && barcode !== codeOrBarcode) return false;
537
+ }
538
+ return true;
483
539
  });
484
- return _context9.abrupt("return", products);
485
- case 4:
540
+ return _context9.abrupt("return", cloneDeep(products));
541
+ case 11:
486
542
  case "end":
487
543
  return _context9.stop();
488
544
  }
489
545
  }, _callee9, this);
490
546
  }));
547
+ function queryProducts() {
548
+ return _queryProducts.apply(this, arguments);
549
+ }
550
+ return queryProducts;
551
+ }()
552
+ }, {
553
+ key: "getProductByIds",
554
+ value: function () {
555
+ var _getProductByIds = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(ids) {
556
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
557
+ while (1) switch (_context10.prev = _context10.next) {
558
+ case 0:
559
+ _context10.next = 2;
560
+ return this.core.effects.emit("".concat(this.name, ":onGetProductByIds"), this.store.list);
561
+ case 2:
562
+ return _context10.abrupt("return", this.queryProducts({
563
+ includeIds: ids
564
+ }));
565
+ case 3:
566
+ case "end":
567
+ return _context10.stop();
568
+ }
569
+ }, _callee10, this);
570
+ }));
491
571
  function getProductByIds(_x8) {
492
572
  return _getProductByIds.apply(this, arguments);
493
573
  }
@@ -496,10 +576,10 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
496
576
  }, {
497
577
  key: "addProduct",
498
578
  value: function () {
499
- var _addProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(products) {
579
+ var _addProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(products) {
500
580
  var _this6 = this;
501
- return _regeneratorRuntime().wrap(function _callee10$(_context10) {
502
- while (1) switch (_context10.prev = _context10.next) {
581
+ return _regeneratorRuntime().wrap(function _callee11$(_context11) {
582
+ while (1) switch (_context11.prev = _context11.next) {
503
583
  case 0:
504
584
  // list 需要根据 id 去重
505
585
  if (!this.store.list) {
@@ -522,9 +602,9 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
522
602
  this.core.effects.emit("".concat(this.name, ":changed"), this.store.list);
523
603
  case 4:
524
604
  case "end":
525
- return _context10.stop();
605
+ return _context11.stop();
526
606
  }
527
- }, _callee10, this);
607
+ }, _callee11, this);
528
608
  }));
529
609
  function addProduct(_x9) {
530
610
  return _addProduct.apply(this, arguments);
@@ -534,16 +614,16 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
534
614
  }, {
535
615
  key: "selectProducts",
536
616
  value: function () {
537
- var _selectProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(products) {
538
- return _regeneratorRuntime().wrap(function _callee11$(_context11) {
539
- while (1) switch (_context11.prev = _context11.next) {
617
+ var _selectProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12(products) {
618
+ return _regeneratorRuntime().wrap(function _callee12$(_context12) {
619
+ while (1) switch (_context12.prev = _context12.next) {
540
620
  case 0:
541
621
  this.store.selectProducts = products;
542
622
  case 1:
543
623
  case "end":
544
- return _context11.stop();
624
+ return _context12.stop();
545
625
  }
546
- }, _callee11, this);
626
+ }, _callee12, this);
547
627
  }));
548
628
  function selectProducts(_x10) {
549
629
  return _selectProducts.apply(this, arguments);
@@ -15,6 +15,16 @@ export interface ProductListLoadProductsParams {
15
15
  /** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
16
16
  strategy_context?: Record<string, any>;
17
17
  }
18
+ export interface ProductListStoreQueryParams {
19
+ includeIds?: Array<number | string>;
20
+ excludeIds?: Array<number | string>;
21
+ categoryIds?: Array<number | string>;
22
+ collectionIds?: Array<number | string>;
23
+ extensionTypes?: string[];
24
+ statuses?: ProductData['status'][];
25
+ channelApplications?: string[];
26
+ codeOrBarcode?: string;
27
+ }
18
28
  export interface ProductListData {
19
29
  list: ProductData[];
20
30
  selectProducts: ProductData[];
@@ -14,8 +14,8 @@ import { AvailabilityError } from "./types";
14
14
  import { addLocalCalendarDays, addLocalHours, addLocalMinutes, captureRuntimeOffsetMinutes, ceilLocalScalarToTenMinutes, dateOrdinalFromLocalDate, extractFixedOffsetMinutes, formatLocalDate, formatLocalDateTime, formatLocalTime, localDateTimeToScalar, localDateToScalar, localDateToScalarStart, nextDate as getNextLocalDate, parseLocalDate, parseLocalDateTime, weekdayFromLocalDate } from "./localClock";
15
15
  var DEFAULT_SLOT_STEP_MINUTES = 30;
16
16
  var DEFAULT_BUSINESS_HOURS = {
17
- startTime: '09:00',
18
- endTime: '18:00'
17
+ startTime: '00:00',
18
+ endTime: '00:00'
19
19
  };
20
20
  function availabilityError(code, message, details) {
21
21
  return new AvailabilityError(code, message, details);
@@ -1072,7 +1072,9 @@ export function getProductTimeRanges(projection) {
1072
1072
  var startsInOperatingRange = operatingRanges.some(function (range) {
1073
1073
  return range.start <= start && start < range.end;
1074
1074
  });
1075
- if (!startsInOperatingRange) return;
1075
+ if (!startsInOperatingRange && !request.allowOutsideOperatingHoursForRequestedStartTimes) {
1076
+ return;
1077
+ }
1076
1078
  ranges.push(createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes));
1077
1079
  });
1078
1080
  }
@@ -234,6 +234,11 @@ export interface GetProductTimeRangesRequest {
234
234
  partySize?: number;
235
235
  durationMinutesByProductId?: Record<string, number>;
236
236
  durationStartTimesByProductId?: Record<string, string[]>;
237
+ /**
238
+ * POS 手工输入时间的兼容开关:只为明确请求的 start time 补候选,
239
+ * 不改变常规候选列表仍按营业时间生成的规则。
240
+ */
241
+ allowOutsideOperatingHoursForRequestedStartTimes?: boolean;
237
242
  }
238
243
  export interface QueryAvailabilityBaseRequest {
239
244
  productIds?: AvailabilityId[];
@@ -520,6 +520,12 @@ declare class Server {
520
520
  private stringifyCheckoutResourceIdentifier;
521
521
  private normalizeCheckoutSubmitData;
522
522
  private ensureCheckoutOrderNumbers;
523
+ /**
524
+ * Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
525
+ * shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
526
+ * 都使用同一份完整快照。
527
+ */
528
+ private finalizeCheckoutSalesNotes;
523
529
  private dispatchCheckoutSyncTask;
524
530
  private dispatchPrintOtherReceiptTask;
525
531
  private buildPrintOtherReceiptIdempotencyKey;
@@ -43,6 +43,7 @@ import { filterBookingsFromOrders, sortBookings } from "./modules/order/utils/fi
43
43
  import { buildSmallTicketData, hasSmallTicketData } from "./utils/small-ticket";
44
44
  import { BaseSalesImpl } from "../solution/BaseSales";
45
45
  import { getOrderPaymentIdentityKeys, isIdentifiedPendingOrderPayment, isPendingOrderPayment, mergeOrderPaymentListsByIdentity } from "../modules/Order/payment-utils";
46
+ import { finalizeSalesNotesForCheckout } from "../modules/Order/salesNotes";
46
47
  var OS_FULFILLMENT_REF_MODE_FIELD = '_os_fulfillment_ref_mode';
47
48
 
48
49
  // 重新导出类型供外部使用
@@ -5679,7 +5680,7 @@ var Server = /*#__PURE__*/function () {
5679
5680
  _context56.next = 7;
5680
5681
  break;
5681
5682
  }
5682
- return _context56.abrupt("return", next);
5683
+ return _context56.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5683
5684
  case 7:
5684
5685
  idGenerator = this.getIdGeneratorPlugin();
5685
5686
  if (idGenerator) {
@@ -5690,7 +5691,7 @@ var Server = /*#__PURE__*/function () {
5690
5691
  needsShopOrderNumber: needsShopOrderNumber,
5691
5692
  needsShopFullOrderNumber: needsShopFullOrderNumber
5692
5693
  });
5693
- return _context56.abrupt("return", next);
5694
+ return _context56.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5694
5695
  case 11:
5695
5696
  _context56.prev = 11;
5696
5697
  if (!(needsShopOrderNumber && idGenerator.generateShopOrderNumber)) {
@@ -5728,7 +5729,7 @@ var Server = /*#__PURE__*/function () {
5728
5729
  error: _context56.t0 instanceof Error ? _context56.t0.message : String(_context56.t0)
5729
5730
  });
5730
5731
  case 26:
5731
- return _context56.abrupt("return", next);
5732
+ return _context56.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5732
5733
  case 27:
5733
5734
  case "end":
5734
5735
  return _context56.stop();
@@ -5740,6 +5741,45 @@ var Server = /*#__PURE__*/function () {
5740
5741
  }
5741
5742
  return ensureCheckoutOrderNumbers;
5742
5743
  }()
5744
+ /**
5745
+ * Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
5746
+ * shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
5747
+ * 都使用同一份完整快照。
5748
+ */
5749
+ }, {
5750
+ key: "finalizeCheckoutSalesNotes",
5751
+ value: function finalizeCheckoutSalesNotes(data, title) {
5752
+ var _data$shop_order_numb;
5753
+ if (!data || _typeof(data) !== 'object') return data;
5754
+ if (!Object.prototype.hasOwnProperty.call(data, 'notes')) return data;
5755
+ if (data.notes === undefined || data.notes === null) return data;
5756
+ if (!Array.isArray(data.notes)) {
5757
+ throw new Error('[Order Notes] checkout notes 必须为数组');
5758
+ }
5759
+ if (data.notes.length === 0) return data;
5760
+ var productTargetUuids = (Array.isArray(data.products) ? data.products : []).map(function (product) {
5761
+ var _product$metadata$uni, _product$metadata;
5762
+ return (_product$metadata$uni = product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata.unique_identification_number) !== null && _product$metadata$uni !== void 0 ? _product$metadata$uni : product === null || product === void 0 ? void 0 : product.unique_identification_number;
5763
+ }).filter(function (targetUuid) {
5764
+ return targetUuid !== undefined && targetUuid !== null && String(targetUuid).trim().length > 0;
5765
+ }).map(function (targetUuid) {
5766
+ return String(targetUuid);
5767
+ });
5768
+ var shopOrderNumber = String((_data$shop_order_numb = data.shop_order_number) !== null && _data$shop_order_numb !== void 0 ? _data$shop_order_numb : '').trim();
5769
+ var notes = finalizeSalesNotesForCheckout({
5770
+ notes: data.notes,
5771
+ shopOrderNumber: shopOrderNumber,
5772
+ productTargetUuids: productTargetUuids
5773
+ });
5774
+ this.logInfo("".concat(title, ": checkout Notes \u5DF2\u7ED1\u5B9A\u8BA2\u5355\u53F7"), {
5775
+ shop_order_number: shopOrderNumber,
5776
+ note_count: notes.length
5777
+ });
5778
+ return _objectSpread(_objectSpread({}, data), {}, {
5779
+ shop_order_number: shopOrderNumber,
5780
+ notes: notes
5781
+ });
5782
+ }
5743
5783
  }, {
5744
5784
  key: "dispatchCheckoutSyncTask",
5745
5785
  value: function () {
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
3
  import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
4
4
  import { OrderModule } from '../../modules/Order';
5
- import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions } from '../../modules/Order/types';
5
+ import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions, SalesNote, SalesNotesMutationSnapshot, SetSalesNoteInput, PickupReferenceMode, ShopServiceData, ShopServiceType } from '../../modules/Order/types';
6
6
  import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
7
7
  import type { Discount } from '../../modules/Discount/types';
8
8
  import { RequestPlugin, WindowPlugin } from '../../plugins';
@@ -225,12 +225,20 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
225
225
  getOrderSyncState(): import("../../modules/Order/types").OrderSyncState;
226
226
  getOrderAmountSnapshot(): import("../../modules/Order/types").OrderAmountSnapshot | null;
227
227
  getTempOrderNote(): string;
228
+ getSalesNotes(): SalesNote[];
229
+ createSalesNotesMutationSnapshot(): SalesNotesMutationSnapshot;
230
+ restoreSalesNotesMutationSnapshot(snapshot: SalesNotesMutationSnapshot): void;
231
+ setSalesNote(input: SetSalesNoteInput): Promise<SalesNote>;
232
+ removeSalesNote(uuid: string): Promise<void>;
233
+ clearSalesNotes(): Promise<void>;
228
234
  updateTempOrderNote(note: string): string;
229
235
  updateTempOrderNote(note: string, sync: true): Promise<string>;
230
236
  updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
231
237
  updateRemoteOrderNote(orderId: number | string, note: string): void;
232
238
  updateTempOrderShopDiscount(amount: string | number): string;
233
239
  updateTempOrderDepositAmount(amount: string | number): OrderSummary;
240
+ setPickupReferenceMode(mode: PickupReferenceMode): ShopServiceData;
241
+ setServiceType(serviceType: ShopServiceType): ShopServiceData;
234
242
  updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
235
243
  /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
236
244
  setEnableTempOrderPersist(enabled: boolean): void;