@pisell/private-materials 6.12.355 → 6.12.357

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 (41) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.js +12 -12
  6. package/build/lowcode/view.js +12 -12
  7. package/es/components/appointmentBooking/components/Cart/Item/index.js +64 -12
  8. package/es/components/appointmentBooking/components/ConfirmInformation/index.js +7 -2
  9. package/es/components/appointmentBooking/components/Content/index.js +6 -4
  10. package/es/components/appointmentBooking/components/Voucher/index.js +11 -1
  11. package/es/components/appointmentBooking/hooks.js +33 -18
  12. package/es/components/appointmentBooking/utils.js +16 -5
  13. package/es/components/venueBooking/components/Cart/index.js +112 -18
  14. package/es/components/venueBooking/context.js +14 -3
  15. package/es/components/venueBooking/locales.js +10 -5
  16. package/es/plus/invoice/README.md +8 -2
  17. package/es/plus/invoice/ReceiptRenderer.js +1 -1
  18. package/es/plus/invoice/receipt.d.ts +2 -0
  19. package/es/plus/invoice/receipt.js +38 -8
  20. package/es/plus/invoice/receiptTranslations.js +8 -2
  21. package/es/plus/saleDetail/tmpl/B/components/Invoice/useInvoiceReceiptPreview.js +19 -13
  22. package/es/utils/buildCartHolderParams.js +166 -0
  23. package/es/utils/holderConfig.js +6 -0
  24. package/lib/components/appointmentBooking/components/Cart/Item/index.js +63 -11
  25. package/lib/components/appointmentBooking/components/ConfirmInformation/index.js +7 -2
  26. package/lib/components/appointmentBooking/components/Content/index.js +6 -4
  27. package/lib/components/appointmentBooking/components/Voucher/index.js +11 -1
  28. package/lib/components/appointmentBooking/hooks.js +33 -18
  29. package/lib/components/appointmentBooking/utils.js +16 -5
  30. package/lib/components/venueBooking/components/Cart/index.js +111 -17
  31. package/lib/components/venueBooking/context.js +14 -3
  32. package/lib/components/venueBooking/locales.js +10 -5
  33. package/lib/plus/invoice/README.md +8 -2
  34. package/lib/plus/invoice/ReceiptRenderer.js +1 -1
  35. package/lib/plus/invoice/receipt.d.ts +2 -0
  36. package/lib/plus/invoice/receipt.js +38 -8
  37. package/lib/plus/invoice/receiptTranslations.js +8 -2
  38. package/lib/plus/saleDetail/tmpl/B/components/Invoice/useInvoiceReceiptPreview.js +18 -12
  39. package/lib/utils/buildCartHolderParams.js +172 -0
  40. package/lib/utils/holderConfig.js +7 -0
  41. package/package.json +3 -3
@@ -3,6 +3,7 @@ const require_useEngineContext = require("../../../../hooks/useEngineContext.js"
3
3
  const require_objectSpread2 = require("../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
4
4
  const require_asyncToGenerator = require("../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
5
5
  const require_utils = require("../../../booking/utils.js");
6
+ const require_utils$1 = require("../../utils.js");
6
7
  const require_hooks = require("../../hooks.js");
7
8
  const require_context = require("../../context.js");
8
9
  let react = require("react");
@@ -200,7 +201,16 @@ const VoucherCard = (props) => {
200
201
  className: "login-btn",
201
202
  onClick: () => {
202
203
  if (!action) return;
203
- openLoginModal({ callback: (status) => {} });
204
+ openLoginModal({
205
+ data: { type: "plugin" },
206
+ callback: (status) => {
207
+ if (status === "success") {
208
+ var _appointmentBooking$r;
209
+ const customer = require_utils$1.getCustomer(utils);
210
+ appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r === void 0 || _appointmentBooking$r.call(appointmentBooking, { customer_id: customer === null || customer === void 0 ? void 0 : customer.id });
211
+ }
212
+ }
213
+ });
204
214
  }
205
215
  }, _pisell_utils.locales.getText("pisell2.text.goodpass.login")), /* @__PURE__ */ react.default.createElement("span", null, _pisell_utils.locales.getText("pisell2.text.goodpass.login-tip"))));
206
216
  };
@@ -185,15 +185,19 @@ const useAppointmentBookingStep = () => {
185
185
  const selectedResource = (currentSelectedResources === null || currentSelectedResources === void 0 || (_currentSelectedResou2 = currentSelectedResources[0]) === null || _currentSelectedResou2 === void 0 ? void 0 : _currentSelectedResou2.currentSelectedResource) || {};
186
186
  const renderItem = (selectedResource === null || selectedResource === void 0 ? void 0 : selectedResource.renderItem) || {};
187
187
  const checkHolder = function() {
188
- var _ref2 = require_asyncToGenerator._asyncToGenerator(function* () {
188
+ var _ref2 = require_asyncToGenerator._asyncToGenerator(function* (isLoginTrigger = false) {
189
189
  setLoading(false);
190
190
  if (isRetailTemplate || (appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isCartAllNormalProducts())) return appointmentBooking.next();
191
191
  let cartLists = carts || [];
192
192
  if (!(carts === null || carts === void 0 ? void 0 : carts.length)) cartLists = (yield appointmentBooking.getCart()) || [];
193
193
  else cartLists = carts || [];
194
- const { hasError } = require_utils.checkAndGoNext(isFormSubject, checkAccount, cartLists.filter((n) => !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isTargetCartIdNormalProduct(n._id))));
194
+ const { hasError, isEnableSkuHolderRule } = require_utils.checkAndGoNext(isFormSubject, checkAccount, cartLists.filter((n) => !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isTargetCartIdNormalProduct(n._id))));
195
195
  setIsErrorHolder(hasError);
196
- if (hasError) return;
196
+ if (hasError) {
197
+ require_utils$1.scrollToFirstErrorCard(".pisell-lowcode-product-card-select-holder-error");
198
+ return;
199
+ }
200
+ if (isLoginTrigger && isEnableSkuHolderRule) return;
197
201
  if (!!(renderItem === null || renderItem === void 0 ? void 0 : renderItem.policy_id)) openPolicy({ id: renderItem === null || renderItem === void 0 ? void 0 : renderItem.policy_id }, () => {
198
202
  return appointmentBooking.next();
199
203
  });
@@ -205,10 +209,17 @@ const useAppointmentBookingStep = () => {
205
209
  }();
206
210
  const checkLogin = function() {
207
211
  var _ref3 = require_asyncToGenerator._asyncToGenerator(function* () {
208
- if (!isLogin) {
212
+ if (!isLogin()) {
209
213
  const { pubsub } = utils;
210
214
  pubsub.once("pisell1.login.success", (res) => {
211
- if (res === "success") checkHolder();
215
+ if (res === "success") {
216
+ if (isFormSubject && !isRetailTemplate && !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isCartAllNormalProducts())) {
217
+ var _appointmentBooking$r;
218
+ const customer = require_utils.getCustomer(utils);
219
+ appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r === void 0 || _appointmentBooking$r.call(appointmentBooking, { customer_id: customer === null || customer === void 0 ? void 0 : customer.id });
220
+ }
221
+ checkHolder(true);
222
+ }
212
223
  if (res === "close") setLoading(false);
213
224
  });
214
225
  return openLoginModal({ callback: (status) => {} });
@@ -342,10 +353,10 @@ const useAppointmentBookingLogin = () => {
342
353
  return Boolean(utils === null || utils === void 0 || (_utils$token = utils.token) === null || _utils$token === void 0 || (_utils$token$get = _utils$token.get) === null || _utils$token$get === void 0 ? void 0 : _utils$token$get.call(_utils$token));
343
354
  }, [utils]);
344
355
  const openLoginModal = (params) => {
345
- const { callback } = params || {};
356
+ const { callback, data = {} } = params || {};
346
357
  utils.action({
347
358
  type: "pisell1.login",
348
- data: { type: "plugin" },
359
+ data: require_objectSpread2._objectSpread2({ type: "plugin" }, data),
349
360
  callback
350
361
  });
351
362
  };
@@ -390,19 +401,23 @@ const useAppointmentBookingAccount = () => {
390
401
  }, []);
391
402
  const getHolders = function() {
392
403
  var _ref9 = require_asyncToGenerator._asyncToGenerator(function* () {
393
- var _utils$getStore$getSt;
404
+ var _utils$getStore$getSt, _appointmentBooking$r2;
394
405
  const shop_id = (_utils$getStore$getSt = utils.getStore().getState()) === null || _utils$getStore$getSt === void 0 || (_utils$getStore$getSt = _utils$getStore$getSt.global) === null || _utils$getStore$getSt === void 0 || (_utils$getStore$getSt = _utils$getStore$getSt.shop) === null || _utils$getStore$getSt === void 0 ? void 0 : _utils$getStore$getSt.id;
395
406
  const customer = require_utils.getCustomer(utils);
396
- if (!shop_id || !form_id || !(customer === null || customer === void 0 ? void 0 : customer.id)) return [];
397
- const params = {
398
- url: "/form/data/v1",
399
- query: {
400
- customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
401
- form_id,
402
- shop_id
403
- }
404
- };
405
- const data = yield appointmentBooking.fetchHolderAccountsAsync(params);
407
+ if (!(customer === null || customer === void 0 ? void 0 : customer.id)) return [];
408
+ let data;
409
+ if (shop_id && form_id) {
410
+ const params = {
411
+ url: "/form/data/v1",
412
+ query: {
413
+ customer_id: customer.id,
414
+ form_id,
415
+ shop_id
416
+ }
417
+ };
418
+ data = yield appointmentBooking.fetchHolderAccountsAsync(params);
419
+ }
420
+ yield appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r2 = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r2 === void 0 ? void 0 : _appointmentBooking$r2.call(appointmentBooking, { customer_id: customer.id });
406
421
  return (data === null || data === void 0 ? void 0 : data.map((item) => {
407
422
  return {
408
423
  id: item === null || item === void 0 ? void 0 : item.form_record_id,
@@ -1,6 +1,7 @@
1
1
  require("../../_virtual/_rolldown/runtime.js");
2
2
  const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
3
3
  const require_asyncToGenerator = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
4
+ const require_holderConfig = require("../../utils/holderConfig.js");
4
5
  let _pisell_utils = require("@pisell/utils");
5
6
  let _pisell_materials = require("@pisell/materials");
6
7
  //#region src/components/appointmentBooking/utils.ts
@@ -339,10 +340,19 @@ const getFormInsertBeforeKey = (currentKey, stepList) => {
339
340
  * @Date: 2025-05-24 22:46
340
341
  */
341
342
  const checkAndGoNext = (isFormSubject, checkAccount, carts) => {
343
+ if (!isFormSubject) return {
344
+ hasError: false,
345
+ isEnableSkuHolderRule: false,
346
+ updatedCartList: carts
347
+ };
342
348
  let hasError = false;
349
+ let isEnableSkuHolderRule = false;
343
350
  let updatedCartList = [...carts];
344
- if (isFormSubject && !checkAccount("holder")) updatedCartList = carts === null || carts === void 0 ? void 0 : carts.map((item) => {
345
- if (!(item === null || item === void 0 ? void 0 : item.holder_id)) {
351
+ updatedCartList = carts === null || carts === void 0 ? void 0 : carts.map((item) => {
352
+ var _item$_productInit;
353
+ const holderConfig = (item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.holder_config) || {};
354
+ if (!(item === null || item === void 0 ? void 0 : item.holder_id) && require_holderConfig.isHolderConfigEnabled(holderConfig) && !require_holderConfig.isHolderConfigRequired(holderConfig)) isEnableSkuHolderRule = true;
355
+ if (!(item === null || item === void 0 ? void 0 : item.holder_id) && require_holderConfig.isHolderConfigRequired(holderConfig)) {
346
356
  hasError = true;
347
357
  return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, item), {}, { isErrorHolder: true });
348
358
  }
@@ -350,7 +360,8 @@ const checkAndGoNext = (isFormSubject, checkAccount, carts) => {
350
360
  });
351
361
  return {
352
362
  hasError,
353
- updatedCartList
363
+ updatedCartList,
364
+ isEnableSkuHolderRule
354
365
  };
355
366
  };
356
367
  const currentAppointmentBoard = (currentKey, resources, appointmentBooking) => {
@@ -412,8 +423,8 @@ const isSessionProduct = function() {
412
423
  var _ref2 = require_asyncToGenerator._asyncToGenerator(function* (appointmentBooking) {
413
424
  const carts = yield appointmentBooking.getCart();
414
425
  return carts === null || carts === void 0 ? void 0 : carts.some((item) => {
415
- var _item$_productInit;
416
- return (item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 || (_item$_productInit = _item$_productInit["schedule.ids"]) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.length) > 0;
426
+ var _item$_productInit2;
427
+ return (item === null || item === void 0 || (_item$_productInit2 = item._productInit) === null || _item$_productInit2 === void 0 || (_item$_productInit2 = _item$_productInit2["schedule.ids"]) === null || _item$_productInit2 === void 0 ? void 0 : _item$_productInit2.length) > 0;
417
428
  });
418
429
  });
419
430
  return function isSessionProduct(_x) {
@@ -3,7 +3,10 @@ const require_useEngineContext = require("../../../../hooks/useEngineContext.js"
3
3
  const require_objectSpread2 = require("../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
4
4
  const require_asyncToGenerator = require("../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
5
5
  const require_index = require("../../../shoppingCart/index.js");
6
+ const require_holderConfig = require("../../../../utils/holderConfig.js");
7
+ const require_utils = require("../../../appointmentBooking/utils.js");
6
8
  const require_index$1 = require("../../../subTotal/index.js");
9
+ const require_buildCartHolderParams = require("../../../../utils/buildCartHolderParams.js");
7
10
  const require_orderProductIdentity = require("../../utils/orderProductIdentity.js");
8
11
  const require_context = require("../../context.js");
9
12
  const require_index$2 = require("../Voucher/index.js");
@@ -21,24 +24,65 @@ require("./index.less");
21
24
  * 支持两种模式:embedded(桌面端内嵌)和 drawer(移动端抽屉弹出)
22
25
  */
23
26
  function Cart(props) {
24
- var _engineContext$appHel, _engineContext$appHel2, _engineContext$appHel3, _engineContext$engine, _businessUtils$getApp, _businessUtils$getApp2, _ref, _ref2, _ref3, _summary$total_amount, _summary$deposit3;
27
+ var _engineContext$appHel, _engineContext$appHel2, _engineContext$appHel3, _engineContext$engine, _engineContext$appHel4, _businessUtils$getApp, _businessUtils$getApp2, _ref, _ref2, _ref3, _summary$total_amount, _summary$deposit3;
25
28
  const { open, onCancel, onNext, items, summary, embedded = false, confirmLoading = false, extraContent } = props;
26
- const { currentStep, runModuleAction, refreshViewModel, refreshTimeSlotGrid, venueBookingModule, isAgreeDepositPolicy, setIsAgreeDepositPolicy } = require_context.useVenueBookingContext();
29
+ const { currentStep, runModuleAction, refreshViewModel, refreshTimeSlotGrid, venueBookingModule, isAgreeDepositPolicy, setIsAgreeDepositPolicy, isLoading, isLogin } = require_context.useVenueBookingContext();
27
30
  const engineContext = require_useEngineContext.default();
28
31
  const businessUtils = engineContext === null || engineContext === void 0 || (_engineContext$appHel = engineContext.appHelper) === null || _engineContext$appHel === void 0 || (_engineContext$appHel = _engineContext$appHel.utils) === null || _engineContext$appHel === void 0 ? void 0 : _engineContext$appHel.businessUtils;
29
32
  const symbol = String((engineContext === null || engineContext === void 0 || (_engineContext$appHel2 = engineContext.appHelper) === null || _engineContext$appHel2 === void 0 || (_engineContext$appHel2 = _engineContext$appHel2.utils) === null || _engineContext$appHel2 === void 0 || (_engineContext$appHel3 = _engineContext$appHel2.getSymbolic) === null || _engineContext$appHel3 === void 0 ? void 0 : _engineContext$appHel3.call(_engineContext$appHel2)) || "$");
30
33
  const locale = (engineContext === null || engineContext === void 0 || (_engineContext$engine = engineContext.engine) === null || _engineContext$engine === void 0 || (_engineContext$engine = _engineContext$engine.props) === null || _engineContext$engine === void 0 ? void 0 : _engineContext$engine.locale) || "en";
34
+ const [holderMap, setHolderMap] = (0, react.useState)({});
35
+ const { pisellos, translation } = (engineContext === null || engineContext === void 0 || (_engineContext$appHel4 = engineContext.appHelper) === null || _engineContext$appHel4 === void 0 ? void 0 : _engineContext$appHel4.utils) || {};
31
36
  const hasGoodPassApp = !!(businessUtils === null || businessUtils === void 0 || (_businessUtils$getApp = businessUtils.getAppByModal) === null || _businessUtils$getApp === void 0 ? void 0 : _businessUtils$getApp.call(businessUtils, "goodpass"));
32
37
  const hasDiscountCardApp = !!(businessUtils === null || businessUtils === void 0 || (_businessUtils$getApp2 = businessUtils.getAppByModal) === null || _businessUtils$getApp2 === void 0 ? void 0 : _businessUtils$getApp2.call(businessUtils, "discountcard"));
33
38
  const showVoucher = hasGoodPassApp || hasDiscountCardApp;
39
+ (0, react.useEffect)(() => {
40
+ var _pisellos$effects;
41
+ const onHolderChanged = (res) => {
42
+ if ((res === null || res === void 0 ? void 0 : res.path) === "holderMap") setHolderMap(res === null || res === void 0 ? void 0 : res.value);
43
+ };
44
+ pisellos === null || pisellos === void 0 || (_pisellos$effects = pisellos.effects) === null || _pisellos$effects === void 0 || _pisellos$effects.on("venueBooking_holder:changed", onHolderChanged);
45
+ return () => {
46
+ var _pisellos$effects2;
47
+ pisellos === null || pisellos === void 0 || (_pisellos$effects2 = pisellos.effects) === null || _pisellos$effects2 === void 0 || _pisellos$effects2.off("venueBooking_holder:changed", onHolderChanged);
48
+ };
49
+ }, [pisellos]);
50
+ (0, react.useEffect)(() => {
51
+ if (isLoading || !venueBookingModule) return;
52
+ try {
53
+ var _venueBookingModule$g;
54
+ setHolderMap(((_venueBookingModule$g = venueBookingModule.getHolderFormMap) === null || _venueBookingModule$g === void 0 ? void 0 : _venueBookingModule$g.call(venueBookingModule)) || {});
55
+ } catch (error) {
56
+ console.warn("[venueBooking] Holder data is not ready", error);
57
+ setHolderMap({});
58
+ }
59
+ }, [venueBookingModule, isLoading]);
34
60
  const isVisible = embedded || open;
35
61
  const totalAmount = (_ref = (_ref2 = (_ref3 = (_summary$total_amount = summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _summary$total_amount !== void 0 ? _summary$total_amount : summary === null || summary === void 0 ? void 0 : summary.expect_amount) !== null && _ref3 !== void 0 ? _ref3 : summary === null || summary === void 0 ? void 0 : summary.amount) !== null && _ref2 !== void 0 ? _ref2 : summary === null || summary === void 0 ? void 0 : summary.total) !== null && _ref !== void 0 ? _ref : "0.00";
36
62
  const cartProducts = (0, react.useMemo)(() => {
37
- return (items || []).map((item) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, item), {}, {
38
- symbol: (item === null || item === void 0 ? void 0 : item.symbol) || symbol,
39
- is_hide_like: true
40
- }));
41
- }, [items, symbol]);
63
+ return (items || []).map((item) => {
64
+ var _item$_origin, _engineContext$appHel5;
65
+ const holderConfig = require_buildCartHolderParams.getVenueCartHolderConfig(item);
66
+ const holderParams = require_buildCartHolderParams.buildCartHolderParams({
67
+ item,
68
+ holderConfig,
69
+ formData: require_holderConfig.isHolderConfigEnabled(holderConfig) ? holderMap === null || holderMap === void 0 ? void 0 : holderMap[holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id] : {},
70
+ translation,
71
+ enabled: !!(item === null || item === void 0 || (_item$_origin = item._origin) === null || _item$_origin === void 0 || (_item$_origin = _item$_origin.product) === null || _item$_origin === void 0 ? void 0 : _item$_origin.bookingUuid),
72
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel5 = engineContext.appHelper) === null || _engineContext$appHel5 === void 0 ? void 0 : _engineContext$appHel5.utils
73
+ });
74
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, item), {}, {
75
+ symbol: (item === null || item === void 0 ? void 0 : item.symbol) || symbol,
76
+ is_hide_like: true,
77
+ allowClearHolder: true
78
+ }, holderParams);
79
+ });
80
+ }, [
81
+ items,
82
+ symbol,
83
+ holderMap,
84
+ translation
85
+ ]);
42
86
  const confirmOrderText = currentStep === "checkout" ? String(_pisell_utils.locales.getText("pisell2.venue.action.pay.now") || "立即支付") : String(_pisell_utils.locales.getText("pisell2.venue.action.next") || "下一步");
43
87
  /**
44
88
  * SubTotal 金额明细列表
@@ -46,12 +90,12 @@ function Cart(props) {
46
90
  * surcharges 为服务费列表,label 支持多语言对象,按当前 locale 取值
47
91
  */
48
92
  const subTotalList = (0, react.useMemo)(() => {
49
- var _summary$product_amou, _summary$tax_fee, _ref4, _summary$total_amount2, _summary$deposit, _venueBookingModule$g, _tempSummary$is_price, _summary$deposit$tota, _summary$deposit2;
93
+ var _summary$product_amou, _summary$tax_fee, _ref4, _summary$total_amount2, _summary$deposit, _venueBookingModule$g2, _tempSummary$is_price, _summary$deposit$tota, _summary$deposit2;
50
94
  const subTotal = Number((_summary$product_amou = summary === null || summary === void 0 ? void 0 : summary.product_amount) !== null && _summary$product_amou !== void 0 ? _summary$product_amou : 0);
51
95
  const totalTaxFee = Number((_summary$tax_fee = summary === null || summary === void 0 ? void 0 : summary.tax_fee) !== null && _summary$tax_fee !== void 0 ? _summary$tax_fee : 0);
52
96
  const total = Number((_ref4 = (_summary$total_amount2 = summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _summary$total_amount2 !== void 0 ? _summary$total_amount2 : summary === null || summary === void 0 ? void 0 : summary.expect_amount) !== null && _ref4 !== void 0 ? _ref4 : 0);
53
97
  const hasDeposit = !!(summary === null || summary === void 0 || (_summary$deposit = summary.deposit) === null || _summary$deposit === void 0 ? void 0 : _summary$deposit.hasDeposit);
54
- const tempOrder = venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g = venueBookingModule.getTempOrder) === null || _venueBookingModule$g === void 0 ? void 0 : _venueBookingModule$g.call(venueBookingModule);
98
+ const tempOrder = venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g2 = venueBookingModule.getTempOrder) === null || _venueBookingModule$g2 === void 0 ? void 0 : _venueBookingModule$g2.call(venueBookingModule);
55
99
  const tempSummary = (tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.summary) || {};
56
100
  const taxTitle = String((tempSummary === null || tempSummary === void 0 ? void 0 : tempSummary.tax_title) || (summary === null || summary === void 0 ? void 0 : summary.tax_title) || "GST/Tax");
57
101
  const rawTaxRate = Number(tempSummary === null || tempSummary === void 0 ? void 0 : tempSummary.tax_rate);
@@ -113,7 +157,57 @@ function Cart(props) {
113
157
  return false;
114
158
  };
115
159
  const handleCartChange = function() {
116
- var _ref5 = require_asyncToGenerator._asyncToGenerator(function* (item, type, sourceItem) {
160
+ var _ref6 = require_asyncToGenerator._asyncToGenerator(function* (item, type, sourceItem) {
161
+ if (type === "add_holder") {
162
+ var _engineContext$appHel6;
163
+ const holderConfig = require_buildCartHolderParams.getVenueCartHolderConfig(item);
164
+ if (!require_holderConfig.isHolderConfigEnabled(holderConfig)) return;
165
+ const formId = holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id;
166
+ if (!formId) return;
167
+ const skuRelationFormId = require_buildCartHolderParams.getSkuRelationFormId(holderMap, formId);
168
+ return require_utils.openForm({
169
+ form_id: skuRelationFormId || formId,
170
+ title: _pisell_utils.locales.getText("pisell2.venue.create.form"),
171
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel6 = engineContext.appHelper) === null || _engineContext$appHel6 === void 0 ? void 0 : _engineContext$appHel6.utils,
172
+ callback: function() {
173
+ var _ref5 = require_asyncToGenerator._asyncToGenerator(function* (res) {
174
+ if ((res === null || res === void 0 ? void 0 : res.status) === "success") {
175
+ var _engineContext$appHel7, _engineContext$appHel8, _item$_origin2;
176
+ const { formRecordId, formId: holderFormId } = require_buildCartHolderParams.handleCartHolderFormSuccess({
177
+ res,
178
+ formId,
179
+ skuRelationFormId,
180
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel7 = engineContext.appHelper) === null || _engineContext$appHel7 === void 0 ? void 0 : _engineContext$appHel7.utils,
181
+ module: venueBookingModule
182
+ });
183
+ const customer = require_utils.getCustomer(engineContext === null || engineContext === void 0 || (_engineContext$appHel8 = engineContext.appHelper) === null || _engineContext$appHel8 === void 0 ? void 0 : _engineContext$appHel8.utils);
184
+ venueBookingModule.setBookingHolder(item === null || item === void 0 || (_item$_origin2 = item._origin) === null || _item$_origin2 === void 0 || (_item$_origin2 = _item$_origin2.product) === null || _item$_origin2 === void 0 ? void 0 : _item$_origin2.bookingUuid, {
185
+ customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
186
+ form_id: holderFormId,
187
+ form_record: [formRecordId]
188
+ });
189
+ yield refreshViewModel();
190
+ }
191
+ });
192
+ return function callback(_x) {
193
+ return _ref5.apply(this, arguments);
194
+ };
195
+ }()
196
+ });
197
+ }
198
+ if (type === "change_holder") {
199
+ var _engineContext$appHel9, _item$_origin3;
200
+ const customer = require_utils.getCustomer(engineContext === null || engineContext === void 0 || (_engineContext$appHel9 = engineContext.appHelper) === null || _engineContext$appHel9 === void 0 ? void 0 : _engineContext$appHel9.utils);
201
+ const holder = (sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem._origin) || sourceItem;
202
+ const params = !sourceItem ? null : {
203
+ customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
204
+ form_id: holder === null || holder === void 0 ? void 0 : holder.form_id,
205
+ form_record: [holder === null || holder === void 0 ? void 0 : holder.form_record_id]
206
+ };
207
+ venueBookingModule.setBookingHolder(item === null || item === void 0 || (_item$_origin3 = item._origin) === null || _item$_origin3 === void 0 || (_item$_origin3 = _item$_origin3.product) === null || _item$_origin3 === void 0 ? void 0 : _item$_origin3.bookingUuid, params);
208
+ yield refreshViewModel();
209
+ return;
210
+ }
117
211
  if (type !== "delete") return;
118
212
  const targetItem = sourceItem && typeof sourceItem === "object" ? sourceItem : item;
119
213
  if (currentStep !== "select-venue" && isVenueBookingCartItem(targetItem)) {
@@ -139,8 +233,8 @@ function Cart(props) {
139
233
  });
140
234
  }
141
235
  });
142
- return function handleCartChange(_x, _x2, _x3) {
143
- return _ref5.apply(this, arguments);
236
+ return function handleCartChange(_x2, _x3, _x4) {
237
+ return _ref6.apply(this, arguments);
144
238
  };
145
239
  }();
146
240
  (0, react.useEffect)(() => {
@@ -156,9 +250,9 @@ function Cart(props) {
156
250
  isShowNote: false,
157
251
  isShowDelete: true,
158
252
  isShowPackageNote: false,
159
- isShowChangeHolder: false,
160
- isShowHolder: false,
161
- isShowAddHolderButton: false
253
+ isShowChangeHolder: currentStep === "checkout" ? false : !!isLogin,
254
+ isShowHolder: true,
255
+ isShowAddHolderButton: true
162
256
  },
163
257
  platform: "h5",
164
258
  emptyText: _pisell_utils.locales.getText("pisell2.venue.cart.empty"),
@@ -174,8 +268,8 @@ function Cart(props) {
174
268
  isAgreePolicy: isAgreeDepositPolicy,
175
269
  onChange: setIsAgreeDepositPolicy,
176
270
  getProtocol: (id) => {
177
- var _venueBookingModule$g2;
178
- return venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g2 = venueBookingModule.getProtocol) === null || _venueBookingModule$g2 === void 0 ? void 0 : _venueBookingModule$g2.call(venueBookingModule, id);
271
+ var _venueBookingModule$g3;
272
+ return venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g3 = venueBookingModule.getProtocol) === null || _venueBookingModule$g3 === void 0 ? void 0 : _venueBookingModule$g3.call(venueBookingModule, id);
179
273
  }
180
274
  }) : null), extraContent ? /* @__PURE__ */ react.default.createElement("div", { className: "pisell-venue-booking-cart-extra-content" }, extraContent) : null);
181
275
  if (embedded) return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, cartListContent, /* @__PURE__ */ react.default.createElement("div", { className: "pisell-venue-booking-cart-embedded-footer" }, cartSummaryContent, /* @__PURE__ */ react.default.createElement(_pisell_materials.Button, {
@@ -2,6 +2,7 @@ const require_runtime = require("../../_virtual/_rolldown/runtime.js");
2
2
  const require_useEngineContext = require("../../hooks/useEngineContext.js");
3
3
  const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
4
4
  const require_asyncToGenerator = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
5
+ const require_buildCartHolderParams = require("../../utils/buildCartHolderParams.js");
5
6
  const require_hooks = require("./hooks.js");
6
7
  const require_utils = require("./utils.js");
7
8
  let dayjs = require("dayjs");
@@ -504,13 +505,23 @@ function VenueBookingProvider({ entryContext, children }) {
504
505
  } });
505
506
  return;
506
507
  }
508
+ if (currentStep === "addons") {
509
+ const { hasError } = require_buildCartHolderParams.validateRequiredCartHolders({
510
+ items: viewModel.cartItems,
511
+ getHolderConfig: require_buildCartHolderParams.getVenueCartHolderConfig
512
+ });
513
+ if (hasError) return;
514
+ }
507
515
  goToStep("checkout");
508
516
  }, [
509
517
  isLogin,
510
518
  openLoginModal,
511
519
  handleLoginSuccess,
512
520
  goToStep,
513
- venueBookingModule
521
+ venueBookingModule,
522
+ currentStep,
523
+ viewModel.cartItems,
524
+ require_buildCartHolderParams.getVenueCartHolderConfig
514
525
  ]);
515
526
  /** 主操作按钮行为(含登录门禁,自适应 2/3 步流程) */
516
527
  const handlePrimaryAction = (0, react.useCallback)(() => {
@@ -546,9 +557,9 @@ function VenueBookingProvider({ entryContext, children }) {
546
557
  isAgreeDepositPolicy,
547
558
  viewModel.summary,
548
559
  stepList,
549
- proceedToCheckout,
550
560
  goToStep,
551
- handleSubmitOrder
561
+ handleSubmitOrder,
562
+ proceedToCheckout
552
563
  ]);
553
564
  (0, react.useEffect)(() => {
554
565
  var _pubsub$subscribe;
@@ -126,7 +126,8 @@ var locales_default = {
126
126
  "pisell2.appointment.policy": "You have read and agreed to this policy",
127
127
  "pisell2.appointment.policy.confirm": "Confirm",
128
128
  "pisell2.appointment.booking.empty.data": "No data",
129
- "pisell2.product-select.search": "Search"
129
+ "pisell2.product-select.search": "Search",
130
+ "pisell2.venue.create.form": "Create form"
130
131
  },
131
132
  "zh-CN": {
132
133
  "pisell2.venue.step.select": "选择场地",
@@ -250,7 +251,8 @@ var locales_default = {
250
251
  "pisell2.appointment.policy": "您已仔细阅读并同意此协议",
251
252
  "pisell2.appointment.policy.confirm": "确定",
252
253
  "pisell2.appointment.booking.empty.data": "暂无数据",
253
- "pisell2.product-select.search": "搜索"
254
+ "pisell2.product-select.search": "搜索",
255
+ "pisell2.venue.create.form": "创建表单"
254
256
  },
255
257
  "zh-HK": {
256
258
  "pisell2.venue.step.select": "選擇場地",
@@ -374,7 +376,8 @@ var locales_default = {
374
376
  "pisell2.appointment.policy": "您已仔細閱讀並同意此協議",
375
377
  "pisell2.appointment.policy.confirm": "確定",
376
378
  "pisell2.appointment.booking.empty.data": "暫無數據",
377
- "pisell2.product-select.search": "搜索"
379
+ "pisell2.product-select.search": "搜索",
380
+ "pisell2.venue.create.form": "创建表单"
378
381
  },
379
382
  ja: {
380
383
  "pisell2.venue.step.select": "コートを選択",
@@ -498,7 +501,8 @@ var locales_default = {
498
501
  "pisell2.appointment.policy": "このポリシーを読み、同意しました",
499
502
  "pisell2.appointment.policy.confirm": "確認",
500
503
  "pisell2.appointment.booking.empty.data": "データなし",
501
- "pisell2.product-select.search": "検索"
504
+ "pisell2.product-select.search": "検索",
505
+ "pisell2.venue.create.form": "フォームを作成"
502
506
  },
503
507
  pt: {
504
508
  "pisell2.venue.step.select": "Escolher quadra",
@@ -622,7 +626,8 @@ var locales_default = {
622
626
  "pisell2.appointment.policy": "Você leu e concordou com esta política",
623
627
  "pisell2.appointment.policy.confirm": "Confirmar",
624
628
  "pisell2.appointment.booking.empty.data": "Sem dados",
625
- "pisell2.product-select.search": "Pesquisar"
629
+ "pisell2.product-select.search": "Pesquisar",
630
+ "pisell2.venue.create.form": "Criar formulário"
626
631
  }
627
632
  };
628
633
  //#endregion
@@ -77,8 +77,14 @@ type OrderInvoiceHandle = {
77
77
 
78
78
  OS `OrderInvoicePreview` 从模板 language 中提供 `languageOptions` 和
79
79
  `selectedLanguage`;宿主选择器调用实例 `selectLanguage(code)`,不重新准备订单或
80
- 加载低代码页面。`result.locale` 为主语言,`secondaryLocale` 仅在 `cn_en` 时为
81
- `zh_CN`。页面 UI 的 `locale` 不随此选择改变。
80
+ 加载低代码页面。`result.locale` 为主语言;`cn_en` 沿用英语在前、简体中文在后,
81
+ `ja_en` 为日语在前、英语在后,`secondaryLocale` 为对应的第二语言。
82
+ 页面 UI 的 `locale` 不随此选择改变。
83
+
84
+ POS Invoice 预览从同一份 `getInvoiceTemplateSettings()` 配置取得 modules 和
85
+ language,展示首个启用的语言模式(打印份数不重复预览),并请求该模式所需的所有
86
+ 语言快照。双语模式任一语言缺失时保留重试提示,不静默降级为单语。旧 OS 仅提供
87
+ layout 或 DEFAULT 模板未指定语言时,继续按界面语言选择。
82
88
 
83
89
  物料使用 `receipt_key` 关联来源相同的双语节点,保留仅次语言有内容的行。
84
90
  `receipt_item_kind` / `receipt_value_kind` 区分共享值和翻译文本,避免时间、编号和
@@ -29,7 +29,7 @@ function ReceiptRows({ locale, rows }) {
29
29
  return /* @__PURE__ */ react.default.createElement("div", {
30
30
  className: `${PREFIX}__receipt-row ${row.size === 2 ? `${PREFIX}__receipt-row--strong` : ""} ${singleValue ? `${PREFIX}__receipt-row--single` : ""} ${alignment ? `${PREFIX}__receipt-row--align-${alignment}` : ""}`,
31
31
  key: `${row.item}-${row.value}-${index}`
32
- }, row.item ? /* @__PURE__ */ react.default.createElement("span", null, label(String(row.item), locale)) : null, row.value ? /* @__PURE__ */ react.default.createElement("span", null, row.value) : null);
32
+ }, row.item ? /* @__PURE__ */ react.default.createElement("span", null, label(String(row.item), row.labelLocale || locale)) : null, row.value ? /* @__PURE__ */ react.default.createElement("span", null, row.value) : null);
33
33
  }));
34
34
  }
35
35
  function ReceiptSectionTitle({ children }) {
@@ -10,6 +10,8 @@ interface InvoiceLayoutConfig {
10
10
  module: InvoiceModuleConfig[];
11
11
  }
12
12
  interface SmallTicketItem {
13
+ /** View-only locale retained when primary and secondary rows are merged. */
14
+ labelLocale?: string;
13
15
  receipt_key?: string;
14
16
  receipt_value_kind?: 'shared' | 'text';
15
17
  receipt_item_kind?: 'shared' | 'text';
@@ -320,12 +320,8 @@ function findLocaleKey(data, candidate) {
320
320
  const lowerCandidate = candidate.toLowerCase().replace(/-/g, "_");
321
321
  return Object.keys(data).find((key) => key.toLowerCase().replace(/-/g, "_") === lowerCandidate);
322
322
  }
323
- function selectSmallTicketLocale(data, appLocale, primaryLocale) {
324
- const candidates = [
325
- ...localeCandidates(appLocale),
326
- "en",
327
- ...localeCandidates(primaryLocale || "")
328
- ];
323
+ function selectSmallTicketLocale(data, appLocale, primaryLocale, allowFallback = true) {
324
+ const candidates = [...localeCandidates(appLocale), ...allowFallback ? ["en", ...localeCandidates(primaryLocale || "")] : []];
329
325
  for (const candidate of candidates) {
330
326
  const key = findLocaleKey(data, candidate);
331
327
  if (key && hasLocalePayload(data[key])) return {
@@ -333,7 +329,7 @@ function selectSmallTicketLocale(data, appLocale, primaryLocale) {
333
329
  locale: key
334
330
  };
335
331
  }
336
- const first = Object.keys(data).find((key) => hasLocalePayload(data[key]));
332
+ const first = allowFallback ? Object.keys(data).find((key) => hasLocalePayload(data[key])) : void 0;
337
333
  return first ? {
338
334
  data: data[first],
339
335
  locale: first
@@ -365,6 +361,40 @@ function _resolveInvoiceLayoutConfig() {
365
361
  });
366
362
  return _resolveInvoiceLayoutConfig.apply(this, arguments);
367
363
  }
364
+ const INVOICE_PREVIEW_LANGUAGES = {
365
+ en: ["en"],
366
+ zh_cn: ["zh_CN"],
367
+ zh_hk: ["zh_HK"],
368
+ ja: ["ja"],
369
+ pt: ["pt"],
370
+ cn_en: ["en", "zh_CN"],
371
+ ja_en: ["ja", "en"]
372
+ };
373
+ /** Use the first enabled print mode once, regardless of its copy count. */
374
+ function resolveInvoicePreviewConfig(_x2) {
375
+ return _resolveInvoicePreviewConfig.apply(this, arguments);
376
+ }
377
+ function _resolveInvoicePreviewConfig() {
378
+ _resolveInvoicePreviewConfig = require_asyncToGenerator._asyncToGenerator(function* (salesModule) {
379
+ if (typeof (salesModule === null || salesModule === void 0 ? void 0 : salesModule.getInvoiceTemplateSettings) === "function") {
380
+ const settings = yield salesModule.getInvoiceTemplateSettings();
381
+ if (isRecord(settings)) {
382
+ const layout = normalizeInvoiceLayoutConfig({ module: settings.modules });
383
+ if (typeof settings.template === "string" && settings.template.trim() && settings.template.trim().toUpperCase() !== "DEFAULT" && isRecord(settings.language)) for (const [rawCode, count] of Object.entries(settings.language)) {
384
+ if (typeof count !== "number" || !Number.isFinite(count) || count <= 0) continue;
385
+ const locales = INVOICE_PREVIEW_LANGUAGES[rawCode.trim().toLowerCase().replace(/-/g, "_")];
386
+ if (Array.isArray(locales)) return {
387
+ layout,
388
+ locales: [...locales]
389
+ };
390
+ }
391
+ return { layout };
392
+ }
393
+ }
394
+ return { layout: yield resolveInvoiceLayoutConfig(salesModule) };
395
+ });
396
+ return _resolveInvoicePreviewConfig.apply(this, arguments);
397
+ }
368
398
  function text(value) {
369
399
  return value === void 0 || value === null ? "" : String(value).trim();
370
400
  }
@@ -906,7 +936,7 @@ exports.getReceiptProductTotal = getReceiptProductTotal;
906
936
  exports.isSmallTicketData = isSmallTicketData;
907
937
  exports.multiplyReceiptMoney = multiplyReceiptMoney;
908
938
  exports.receiptMoneyValuesDiffer = receiptMoneyValuesDiffer;
909
- exports.resolveInvoiceLayoutConfig = resolveInvoiceLayoutConfig;
939
+ exports.resolveInvoicePreviewConfig = resolveInvoicePreviewConfig;
910
940
  exports.resolveSmallTicketData = resolveSmallTicketData;
911
941
  exports.selectSmallTicketLocale = selectSmallTicketLocale;
912
942
  exports.subtractReceiptMoney = subtractReceiptMoney;
@@ -42,9 +42,14 @@ function receiptLabel(receipt, key) {
42
42
  return bilingualText(require_receipt.getReceiptLabel(receipt.locale, key), receipt.secondary && require_receipt.getReceiptLabel(receipt.secondary.locale, key));
43
43
  }
44
44
  function mergeTranslatedRows(primary, secondary, locale, secondaryLocale, sharedValues = false) {
45
+ const primaryRows = new Set(primary);
45
46
  return pairReceiptEntries(primary, secondary, (row) => row.receipt_key).flatMap(({ primary: row, secondary: other }) => {
46
- const item = require_receipt.getReceiptLabel(locale, row.item || "");
47
- const result = [require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, row), {}, { item })];
47
+ const labelLocale = primaryRows.has(row) ? locale : secondaryLocale;
48
+ const item = require_receipt.getReceiptLabel(labelLocale, row.item || "");
49
+ const result = [require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, row), {}, {
50
+ item,
51
+ labelLocale
52
+ })];
48
53
  if (!other) return result;
49
54
  let secondItem = require_receipt.getReceiptLabel(secondaryLocale, other.item || "");
50
55
  if (row.receipt_key === "settlement/tax-included") secondItem = secondItem.replace(/\s-?[^\s\d]*\d[\d,.]*\s(?=\()/, " ");
@@ -53,6 +58,7 @@ function mergeTranslatedRows(primary, secondary, locale, secondaryLocale, shared
53
58
  if (!secondItem && !secondValue) return result;
54
59
  result.push(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, other), {}, {
55
60
  item: secondItem,
61
+ labelLocale: secondaryLocale,
56
62
  value: secondValue,
57
63
  receipt_key: `${other.receipt_key}/secondary`
58
64
  }));