@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
@@ -82,13 +82,12 @@ function useInvoiceReceiptPreview(context) {
82
82
  setState(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, LOADING_STATE), {}, { scope }));
83
83
  (function() {
84
84
  var _ref3 = require_asyncToGenerator._asyncToGenerator(function* () {
85
- var _bookingTicket$getFor;
86
85
  const { appLocale, bookingTicket, engineContext, orderId, platform, previewCreatedAt, salesDetail, salesModule, tempOrder } = scope;
87
- const layout = yield require_receipt.resolveInvoiceLayoutConfig(salesModule);
86
+ const { layout, locales } = yield require_receipt.resolveInvoicePreviewConfig(salesModule);
88
87
  if (cancelled) return null;
89
88
  const mustFilter = require_invoiceVisibility.requiresInvoiceDataFiltering(layout);
90
89
  const needsPaymentTimeKeys = require_invoiceVisibility.requiresInvoicePaymentTimeKeys(layout);
91
- const useSharedConfig = require_invoiceVisibility.hasInvoiceDetailSettings(layout) || mustFilter;
90
+ const useSharedConfig = require_invoiceVisibility.hasInvoiceDetailSettings(layout) || mustFilter || Boolean(locales);
92
91
  const isVirtualOrder = require_index.isVirtualSettlementTempOrder(tempOrder) || require_index.isVirtualSettlementTempOrder(salesDetail === null || salesDetail === void 0 ? void 0 : salesDetail.raw);
93
92
  const legacyVirtualResult = {
94
93
  receipt: null,
@@ -98,11 +97,12 @@ function useInvoiceReceiptPreview(context) {
98
97
  };
99
98
  if (isVirtualOrder && !useSharedConfig) return legacyVirtualResult;
100
99
  const requiresSource = isVirtualOrder && useSharedConfig;
100
+ const requiresFreshSnapshot = mustFilter || needsPaymentTimeKeys || requiresSource || ((locales === null || locales === void 0 ? void 0 : locales.length) || 0) > 1;
101
101
  const embeddedSnapshot = require_receipt.resolveSmallTicketData(salesDetail, tempOrder);
102
102
  const { snapshot, source } = yield function() {
103
103
  var _ref2 = require_asyncToGenerator._asyncToGenerator(function* () {
104
104
  if (platform !== "h5" && orderId !== null && orderId !== void 0) try {
105
- const freshSnapshot = yield require_serve.getLocalOrderReceiptSnapshot(orderId, [appLocale], layout);
105
+ const freshSnapshot = yield require_serve.getLocalOrderReceiptSnapshot(orderId, locales || [appLocale], layout);
106
106
  if (!freshSnapshot || !require_receipt.isSmallTicketData(freshSnapshot.small_ticket_data)) throw new Error("Receipt snapshot is unavailable");
107
107
  if (mustFilter && freshSnapshot.template_visibility_applied !== true) throw new Error("Receipt snapshot does not support template filtering");
108
108
  if (needsPaymentTimeKeys && !require_invoiceVisibility.hasInvoicePaymentTimeKeys(freshSnapshot.small_ticket_data)) throw new Error("Receipt snapshot does not identify payment history times");
@@ -112,10 +112,10 @@ function useInvoiceReceiptPreview(context) {
112
112
  source: freshSnapshot.source || null
113
113
  };
114
114
  } catch (error) {
115
- if (mustFilter || needsPaymentTimeKeys || requiresSource) throw error;
115
+ if (requiresFreshSnapshot) throw error;
116
116
  console.warn("[SaleDetail.Invoice] Failed to rebuild local receipt snapshot", error);
117
117
  }
118
- if (mustFilter || needsPaymentTimeKeys || requiresSource) throw new Error("A template-aware local receipt snapshot is required");
118
+ if (requiresFreshSnapshot) throw new Error("A template-aware local receipt snapshot is required");
119
119
  return {
120
120
  snapshot: embeddedSnapshot || (orderId !== null && orderId !== void 0 ? yield require_serve.getOrderSmallTicketData(orderId) : null),
121
121
  source: null
@@ -129,17 +129,23 @@ function useInvoiceReceiptPreview(context) {
129
129
  const isVirtualSource = require_index.isVirtualSettlementTempOrder(source);
130
130
  if (isVirtualSource && !useSharedConfig) return legacyVirtualResult;
131
131
  const shopInfo = getShopInfo(engineContext);
132
- const selected = require_receipt.selectSmallTicketLocale(require_invoiceVisibility.isInvoiceResourceTitleVisible(layout) ? require_formTitleDisplay.withDisplayedReceiptFormTitles(snapshot, (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getFor = bookingTicket.getFormTitleMap) === null || _bookingTicket$getFor === void 0 ? void 0 : _bookingTicket$getFor.call(bookingTicket)) || {}, appLocale, (salesDetail === null || salesDetail === void 0 ? void 0 : salesDetail.bookings) || []) : snapshot, appLocale, shopInfo.primary_locale);
133
- if (!selected) throw new Error("Receipt language data is unavailable");
134
- return {
135
- receipt: require_receipt.buildInvoiceReceiptViewModel({
136
- data: selected.data,
132
+ const buildReceipt = (locale) => {
133
+ var _bookingTicket$getFor;
134
+ const selected = require_receipt.selectSmallTicketLocale(snapshot, locale, shopInfo.primary_locale, !locales);
135
+ if (!selected) throw new Error(`Receipt language data is unavailable: ${locale}`);
136
+ return require_receipt.buildInvoiceReceiptViewModel({
137
+ data: require_invoiceVisibility.isInvoiceResourceTitleVisible(layout) ? require_formTitleDisplay.withDisplayedReceiptFormTitles(selected.data, (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getFor = bookingTicket.getFormTitleMap) === null || _bookingTicket$getFor === void 0 ? void 0 : _bookingTicket$getFor.call(bookingTicket)) || {}, selected.locale, (salesDetail === null || salesDetail === void 0 ? void 0 : salesDetail.bookings) || []) : selected.data,
137
138
  layout,
138
139
  locale: selected.locale,
139
140
  previewTime: require_receipt.formatReceiptPreviewTime(previewCreatedAt, selected.locale),
140
141
  shopLogo: getShopLogo(shopInfo),
141
142
  taxNumberLabel: shopInfo.tax_number_title || (String(shopInfo.tax_country_code || "").toUpperCase() === "AU" ? "ABN" : void 0)
142
- }),
143
+ });
144
+ };
145
+ const receipt = buildReceipt((locales === null || locales === void 0 ? void 0 : locales[0]) || appLocale);
146
+ if (locales === null || locales === void 0 ? void 0 : locales[1]) receipt.secondary = buildReceipt(locales[1]);
147
+ return {
148
+ receipt,
143
149
  source,
144
150
  useLegacyVirtualCurrencyInvoice: false,
145
151
  useVirtualCurrencyReceipt: useSharedConfig && isVirtualSource
@@ -0,0 +1,172 @@
1
+ const require_objectSpread2 = require("../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
2
+ const require_holderConfig = require("./holderConfig.js");
3
+ const require_utils = require("../components/appointmentBooking/utils.js");
4
+ //#region src/utils/buildCartHolderParams.ts
5
+ const toHolderRecordId = (value) => {
6
+ if (value == null || value === "") return void 0;
7
+ const id = Number(value);
8
+ return Number.isNaN(id) ? void 0 : id;
9
+ };
10
+ /**
11
+ * 从 _origin.holder 解析 form_record_id。
12
+ * form_record 可能是 number、number[];不能假定一定是数组下标 [0]。
13
+ */
14
+ const resolveOriginHolderId = (holder) => {
15
+ const formRecord = holder === null || holder === void 0 ? void 0 : holder.form_record;
16
+ if (Array.isArray(formRecord)) for (const value of formRecord) {
17
+ const id = toHolderRecordId(value);
18
+ if (id != null) return id;
19
+ }
20
+ else {
21
+ const id = toHolderRecordId(formRecord);
22
+ if (id != null) return id;
23
+ }
24
+ return toHolderRecordId(holder === null || holder === void 0 ? void 0 : holder.form_record_id);
25
+ };
26
+ /**
27
+ * 从购物车行解析当前选中的 holder form_record_id。
28
+ *
29
+ * venueBooking:以 _origin.holder 为准(SDK 会原地更新 form_record);
30
+ * 顶层 item.holder_id 可能是上一轮 UI 注入或 SDK 回灌的滞后值,不能优先于 _origin.holder。
31
+ */
32
+ const resolveCartItemHolderId = (item) => {
33
+ var _item$_origin;
34
+ const originHolder = item === null || item === void 0 || (_item$_origin = item._origin) === null || _item$_origin === void 0 ? void 0 : _item$_origin.holder;
35
+ if (originHolder && typeof originHolder === "object") return resolveOriginHolderId(originHolder);
36
+ return toHolderRecordId(item === null || item === void 0 ? void 0 : item.holder_id);
37
+ };
38
+ const getCurrentCustomerId = (utils) => {
39
+ var _getCustomer;
40
+ return (_getCustomer = require_utils.getCustomer(utils)) === null || _getCustomer === void 0 ? void 0 : _getCustomer.id;
41
+ };
42
+ const createCartHolderOption = (holder, customerId) => {
43
+ const _id = (holder === null || holder === void 0 ? void 0 : holder.formRecordId) || (holder === null || holder === void 0 ? void 0 : holder.form_record_id);
44
+ return {
45
+ key: _id,
46
+ id: _id,
47
+ label: holder === null || holder === void 0 ? void 0 : holder.main_field,
48
+ name: holder === null || holder === void 0 ? void 0 : holder.main_field,
49
+ username: holder === null || holder === void 0 ? void 0 : holder.main_field,
50
+ type: "holder",
51
+ _origin: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, holder), {}, { customer_id: customerId })
52
+ };
53
+ };
54
+ /**
55
+ * 构建 ProductCard Holder 组件使用的单条 holder 数据。
56
+ * 输出字段需要与购物车 ProductCard 消费格式保持一致。
57
+ */
58
+ const buildCartHolderOption = (holder, utils) => {
59
+ if (!holder) return {};
60
+ return createCartHolderOption(holder, getCurrentCustomerId(utils));
61
+ };
62
+ const buildCartHolderOptions = (records, utils) => {
63
+ const customerId = getCurrentCustomerId(utils);
64
+ return records.map((record) => createCartHolderOption(record, customerId));
65
+ };
66
+ const getCartHolderTitle = (records, holderId) => {
67
+ var _records$find;
68
+ if (!holderId) return "";
69
+ return (_records$find = records.find((record) => Number(record === null || record === void 0 ? void 0 : record.form_record_id) === holderId)) === null || _records$find === void 0 ? void 0 : _records$find.main_field;
70
+ };
71
+ /**
72
+ * 根据 holderMap 与购物车行数据,构建 ProductCard 所需的 holder 展示字段。
73
+ * 供 appointmentBooking、venueBooking 等购物车场景复用。
74
+ */
75
+ const buildCartHolderParams = ({ item, holderConfig = {}, formData, translation, enabled = true, utils }) => {
76
+ var _formData$form;
77
+ if (!enabled || !require_holderConfig.isHolderConfigEnabled(holderConfig)) return {
78
+ isShowChangeHolder: false,
79
+ isErrorHolder: false,
80
+ holders: []
81
+ };
82
+ const records = (formData === null || formData === void 0 ? void 0 : formData.records) || [];
83
+ const holderId = resolveCartItemHolderId(item);
84
+ return {
85
+ holder_id: holderId,
86
+ isErrorHolder: !!(!holderId && require_holderConfig.isHolderConfigRequired(holderConfig)),
87
+ isShowChangeHolder: true,
88
+ addHolderButtonText: translation(formData === null || formData === void 0 || (_formData$form = formData.form) === null || _formData$form === void 0 || (_formData$form = _formData$form.form) === null || _formData$form === void 0 || (_formData$form = _formData$form.setting) === null || _formData$form === void 0 ? void 0 : _formData$form.title),
89
+ holder_title: getCartHolderTitle(records, holderId),
90
+ holders: buildCartHolderOptions(records, utils)
91
+ };
92
+ };
93
+ /**
94
+ * 从 appointmentBooking 购物车行读取 holder_config
95
+ */
96
+ const getAppointmentCartHolderConfig = (item) => {
97
+ var _item$_productInit;
98
+ return (item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.holder_config) || {};
99
+ };
100
+ /**
101
+ * 从 venueBooking 购物车行读取 holder_config
102
+ */
103
+ const getVenueCartHolderConfig = (item) => {
104
+ var _item$_origin2;
105
+ return (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.holder_config) || {};
106
+ };
107
+ /**
108
+ * 校验购物车中 holder_config.required 的行是否已选择 holder。
109
+ */
110
+ const validateRequiredCartHolders = ({ items = [], getHolderConfig = getVenueCartHolderConfig }) => {
111
+ const invalidItems = items.filter((item) => {
112
+ if (!require_holderConfig.isHolderConfigRequired(getHolderConfig(item))) return false;
113
+ return !resolveCartItemHolderId(item);
114
+ });
115
+ return {
116
+ hasError: invalidItems.length > 0,
117
+ invalidItems
118
+ };
119
+ };
120
+ /**
121
+ * 从 holderMap 解析 minors 表单关联的 sku 关系表单 ID(form_to_form 隐藏字段的 linkedTable)。
122
+ */
123
+ const getSkuRelationFormId = (holderMap, formId) => {
124
+ var _formData$form2, _formData$form3, _detail$setting;
125
+ if (!formId) return 0;
126
+ const formData = holderMap === null || holderMap === void 0 ? void 0 : holderMap[formId];
127
+ if ((formData === null || formData === void 0 || (_formData$form2 = formData.form) === null || _formData$form2 === void 0 || (_formData$form2 = _formData$form2.form) === null || _formData$form2 === void 0 ? void 0 : _formData$form2.form_type) !== "minors") return 0;
128
+ const detail = formData === null || formData === void 0 || (_formData$form3 = formData.form) === null || _formData$form3 === void 0 || (_formData$form3 = _formData$form3.field) === null || _formData$form3 === void 0 ? void 0 : _formData$form3.find((item) => (item === null || item === void 0 ? void 0 : item.filed_type) === "form_to_form" && (item === null || item === void 0 ? void 0 : item.status) === "hide");
129
+ return (detail === null || detail === void 0 || (_detail$setting = detail.setting) === null || _detail$setting === void 0 ? void 0 : _detail$setting.linkedTable) || 0;
130
+ };
131
+ /**
132
+ * 从 form_to_form_value 中取最新创建的 form_record_id。
133
+ */
134
+ const getSkuRelationFormRecordId = (res) => {
135
+ var _res$values;
136
+ const formToFormValue = res === null || res === void 0 || (_res$values = res.values) === null || _res$values === void 0 || (_res$values = _res$values.form_to_form_value) === null || _res$values === void 0 ? void 0 : _res$values[0];
137
+ const formDataValue = (formToFormValue === null || formToFormValue === void 0 ? void 0 : formToFormValue.form_data_value) || [];
138
+ return formDataValue[formDataValue.length - 1];
139
+ };
140
+ /**
141
+ * 处理购物车添加 holder 表单提交成功后的公共逻辑。
142
+ * - minors 关联表单:刷新 holder 列表,取 form_to_form_value 中的 record id
143
+ * - 普通表单:appendFormRecord 并直接使用 form_record_id
144
+ */
145
+ const handleCartHolderFormSuccess = ({ res, formId, skuRelationFormId, utils, module }) => {
146
+ var _res$values2, _res$values3, _res$values4;
147
+ let formRecordId = res === null || res === void 0 || (_res$values2 = res.values) === null || _res$values2 === void 0 ? void 0 : _res$values2.form_record_id;
148
+ let resolvedFormId = res === null || res === void 0 || (_res$values3 = res.values) === null || _res$values3 === void 0 ? void 0 : _res$values3.form_id;
149
+ if (formId && skuRelationFormId) {
150
+ var _module$refreshAllHol;
151
+ const customer = require_utils.getCustomer(utils);
152
+ module === null || module === void 0 || (_module$refreshAllHol = module.refreshAllHolderFormRecords) === null || _module$refreshAllHol === void 0 || _module$refreshAllHol.call(module, { customer_id: customer === null || customer === void 0 ? void 0 : customer.id });
153
+ formRecordId = getSkuRelationFormRecordId(res);
154
+ resolvedFormId = formId;
155
+ } else if (formId) {
156
+ var _module$appendFormRec;
157
+ module === null || module === void 0 || (_module$appendFormRec = module.appendFormRecord) === null || _module$appendFormRec === void 0 || _module$appendFormRec.call(module, { record: res === null || res === void 0 ? void 0 : res.values });
158
+ }
159
+ return {
160
+ formRecordId,
161
+ mainField: res === null || res === void 0 || (_res$values4 = res.values) === null || _res$values4 === void 0 ? void 0 : _res$values4.main_field,
162
+ formId: resolvedFormId
163
+ };
164
+ };
165
+ //#endregion
166
+ exports.buildCartHolderOption = buildCartHolderOption;
167
+ exports.buildCartHolderParams = buildCartHolderParams;
168
+ exports.getAppointmentCartHolderConfig = getAppointmentCartHolderConfig;
169
+ exports.getSkuRelationFormId = getSkuRelationFormId;
170
+ exports.getVenueCartHolderConfig = getVenueCartHolderConfig;
171
+ exports.handleCartHolderFormSuccess = handleCartHolderFormSuccess;
172
+ exports.validateRequiredCartHolders = validateRequiredCartHolders;
@@ -0,0 +1,7 @@
1
+ //#region src/utils/holderConfig.ts
2
+ /** Holder selection requires an enabled configuration and a valid form ID. */
3
+ const isHolderConfigEnabled = (config) => (config === null || config === void 0 ? void 0 : config.status) === "enable" && Number.isFinite(Number(config === null || config === void 0 ? void 0 : config.resource_id)) && Number(config === null || config === void 0 ? void 0 : config.resource_id) > 0;
4
+ const isHolderConfigRequired = (config) => isHolderConfigEnabled(config) && Number(config === null || config === void 0 ? void 0 : config.required) === 1;
5
+ //#endregion
6
+ exports.isHolderConfigEnabled = isHolderConfigEnabled;
7
+ exports.isHolderConfigRequired = isHolderConfigRequired;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pisell/private-materials",
3
- "version": "6.12.355",
3
+ "version": "6.12.357",
4
4
  "main": "./lib/index.js",
5
5
  "module": "./es/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -74,10 +74,10 @@
74
74
  "styled-components": "^6.0.0-rc.3",
75
75
  "use-sync-external-store": "^1.6.0",
76
76
  "@pisell/pi-payment-sdk": "0.0.4",
77
+ "@pisell/materials": "6.12.86",
77
78
  "@pisell/utils": "3.0.7",
78
79
  "@pisell/icon": "0.0.11",
79
- "@pisell/date-picker": "3.0.12",
80
- "@pisell/materials": "6.12.86"
80
+ "@pisell/date-picker": "3.0.12"
81
81
  },
82
82
  "peerDependencies": {
83
83
  "react": "^18.0.0",