@pisell/pisellos 2.3.138 → 2.3.139
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.
- package/dist/modules/Order/utils.js +1 -1
- package/dist/server/test.json +1 -1
- package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.js +46 -4
- package/dist/shared/receipt/small-ticket.d.ts +9 -0
- package/dist/shared/receipt/small-ticket.js +246 -186
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/OrderInvoicePreview/index.d.ts +10 -0
- package/dist/solution/OrderInvoicePreview/index.js +84 -14
- package/lib/model/strategy/adapter/promotion/index.js +1 -46
- package/lib/modules/Order/utils.js +1 -1
- package/lib/server/test.json +1 -1
- package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +5 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.js +42 -4
- package/lib/shared/receipt/small-ticket.d.ts +9 -0
- package/lib/shared/receipt/small-ticket.js +122 -9
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/OrderInvoicePreview/index.d.ts +10 -0
- package/lib/solution/OrderInvoicePreview/index.js +60 -7
- package/package.json +1 -1
|
@@ -10,6 +10,46 @@ var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
|
10
10
|
var _pickupTiming = require("../../modules/Order/pickupTiming");
|
|
11
11
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
12
|
const DEFAULT_LOCALES = ['en', 'zh_CN'];
|
|
13
|
+
|
|
14
|
+
// Attach provenance to a private copy BEFORE any locale-dependent filtering.
|
|
15
|
+
// Symbols survive the existing spread-based normalization, never enter JSON,
|
|
16
|
+
// and leave both the caller's snapshot and the default native contract intact.
|
|
17
|
+
const RECEIPT_SOURCE = Symbol('customerReceiptSource');
|
|
18
|
+
function copyReceiptSource(value, path = 'order') {
|
|
19
|
+
if (Array.isArray(value)) return value.map((item, index) => copyReceiptSource(item, `${path}/${index}`));
|
|
20
|
+
if (!value || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype) return value;
|
|
21
|
+
const id = value.metadata?.unique_identification_number ?? value.product_uid ?? value.booking_uid ?? value.order_payment_id ?? value.payment_number ?? value.order_refund_id ?? value.refund_number ?? value.id;
|
|
22
|
+
const source = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, copyReceiptSource(item, `${path}/${key}`)]));
|
|
23
|
+
// Retain the original occurrence even when a catalogue ID appears twice.
|
|
24
|
+
return {
|
|
25
|
+
...source,
|
|
26
|
+
[RECEIPT_SOURCE]: `${path}${id != null ? `@${encodeURIComponent(String(id))}` : ''}`
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function receiptKey(source, kind, valueKind = 'shared') {
|
|
30
|
+
const key = source?.[RECEIPT_SOURCE];
|
|
31
|
+
return typeof key === 'string' ? {
|
|
32
|
+
receipt_key: `${key}#${kind}`,
|
|
33
|
+
receipt_value_kind: valueKind
|
|
34
|
+
} : {};
|
|
35
|
+
}
|
|
36
|
+
function receiptSourceIndex(source, index) {
|
|
37
|
+
return source?.[RECEIPT_SOURCE] ? {
|
|
38
|
+
receipt_source_index: index
|
|
39
|
+
} : {};
|
|
40
|
+
}
|
|
41
|
+
function removePrivateReceiptSource(value) {
|
|
42
|
+
if (!value || typeof value !== 'object') return;
|
|
43
|
+
delete value[RECEIPT_SOURCE];
|
|
44
|
+
Object.values(value).forEach(removePrivateReceiptSource);
|
|
45
|
+
}
|
|
46
|
+
function receiptTimeKey(source, kind) {
|
|
47
|
+
const identity = receiptKey(source, kind);
|
|
48
|
+
return identity.receipt_key ? {
|
|
49
|
+
...identity,
|
|
50
|
+
receipt_item_kind: 'shared'
|
|
51
|
+
} : {};
|
|
52
|
+
}
|
|
13
53
|
const SERVICE_TYPE_LABEL_KEYS = {
|
|
14
54
|
takeaway: 'takeAway',
|
|
15
55
|
pick_up: 'pickUp',
|
|
@@ -247,11 +287,11 @@ const LABELS = {
|
|
|
247
287
|
}
|
|
248
288
|
};
|
|
249
289
|
function buildSmallTicketData(params) {
|
|
250
|
-
const order = params.order || {};
|
|
290
|
+
const order = params.includeReceiptKeys ? copyReceiptSource(params.order || {}) : params.order || {};
|
|
251
291
|
const shopInfo = params.shopInfo || {};
|
|
252
292
|
const locales = resolveLocales(shopInfo, params.locales);
|
|
253
293
|
const productMap = params.productMap || {};
|
|
254
|
-
|
|
294
|
+
const result = locales.reduce((data, locale) => {
|
|
255
295
|
data[locale] = buildLocaleData({
|
|
256
296
|
order,
|
|
257
297
|
shopInfo,
|
|
@@ -260,6 +300,8 @@ function buildSmallTicketData(params) {
|
|
|
260
300
|
});
|
|
261
301
|
return data;
|
|
262
302
|
}, {});
|
|
303
|
+
if (params.includeReceiptKeys) removePrivateReceiptSource(result);
|
|
304
|
+
return result;
|
|
263
305
|
}
|
|
264
306
|
function hasSmallTicketData(value) {
|
|
265
307
|
return !!value && typeof value === 'object' && Object.keys(value).length > 0;
|
|
@@ -310,7 +352,10 @@ function buildLocaleData(params) {
|
|
|
310
352
|
locale,
|
|
311
353
|
currencySymbol
|
|
312
354
|
}),
|
|
313
|
-
tickets: Array.isArray(order.tickets) ? order.tickets
|
|
355
|
+
tickets: Array.isArray(order.tickets) ? order.tickets.map(group => Array.isArray(group) ? group.map(row => row && typeof row === 'object' ? {
|
|
356
|
+
...row,
|
|
357
|
+
...receiptKey(row, 'ticket')
|
|
358
|
+
} : row) : group) : [],
|
|
314
359
|
source_shop: [],
|
|
315
360
|
refund_data: buildRefundData({
|
|
316
361
|
order,
|
|
@@ -354,7 +399,7 @@ function buildBaseData(params) {
|
|
|
354
399
|
function buildProducts(order, locale, productMap) {
|
|
355
400
|
const products = Array.isArray(order.products) ? order.products : [];
|
|
356
401
|
const allergyByProductUid = buildProductAllergyMap(order, locale);
|
|
357
|
-
return products.map(rawProduct => {
|
|
402
|
+
return products.map((rawProduct, sourceIndex) => {
|
|
358
403
|
const product = restoreReceiptDiscountHierarchy(rawProduct);
|
|
359
404
|
const quantity = toNumber(product.product_quantity ?? product.quantity ?? product.num ?? 1, 1);
|
|
360
405
|
const originalPrice = product.original_price ?? product.selling_price ?? product.payment_price ?? product.price ?? 0;
|
|
@@ -399,6 +444,10 @@ function buildProducts(order, locale, productMap) {
|
|
|
399
444
|
const resolvedCombinations = Array.isArray(product.combinations) && product.combinations.length ? normalizeExistingCombinations(product.combinations, locale, currencySymbol) : combinations;
|
|
400
445
|
const shouldIncludeBasePrice = options.length > 0 || resolvedCombinations.length > 0 || hasProductDiscount(product, extensionList);
|
|
401
446
|
return {
|
|
447
|
+
...receiptKey(rawProduct, 'product'),
|
|
448
|
+
...(rawProduct[RECEIPT_SOURCE] ? {
|
|
449
|
+
receipt_source_index: sourceIndex
|
|
450
|
+
} : {}),
|
|
402
451
|
product_title: productTitle,
|
|
403
452
|
product_quantity: quantity,
|
|
404
453
|
selling_price: formatMoney(sellingPrice, currencySymbol),
|
|
@@ -542,6 +591,7 @@ function normalizeProductDiscounts(params) {
|
|
|
542
591
|
const totalAmount = new _decimal.default(toMoneyNumber(amount)).mul(isAggregatedBundleDiscount || isEntitlementPass ? 1 : quantity);
|
|
543
592
|
const formattedAmount = isMarkup ? formatMoney(totalAmount.abs(), currencySymbol) : formatNegativeMoney(totalAmount, currencySymbol);
|
|
544
593
|
return {
|
|
594
|
+
...receiptKey(discount, 'discount'),
|
|
545
595
|
item: title,
|
|
546
596
|
value: formattedAmount,
|
|
547
597
|
isMarkup
|
|
@@ -581,6 +631,7 @@ function buildProductExtensionList(params) {
|
|
|
581
631
|
locale,
|
|
582
632
|
currencySymbol
|
|
583
633
|
}), ...(quantity > 1 ? [{
|
|
634
|
+
...receiptTimeKey(product, 'quantity-price'),
|
|
584
635
|
item: buildProductQuantityPriceText({
|
|
585
636
|
quantity,
|
|
586
637
|
currencySymbol,
|
|
@@ -588,7 +639,10 @@ function buildProductExtensionList(params) {
|
|
|
588
639
|
}),
|
|
589
640
|
value: ''
|
|
590
641
|
}] : [])];
|
|
591
|
-
const productExtensionList = extensionList.length ? extensionList : normalizeArray(product.extension_list)
|
|
642
|
+
const productExtensionList = extensionList.length ? extensionList : normalizeArray(product.extension_list).map(row => ({
|
|
643
|
+
...row,
|
|
644
|
+
...receiptKey(row, 'extension')
|
|
645
|
+
}));
|
|
592
646
|
return [...productExtensionList, ...discountList];
|
|
593
647
|
}
|
|
594
648
|
function buildProductOpenWeightRows(params) {
|
|
@@ -605,10 +659,12 @@ function buildProductOpenWeightRows(params) {
|
|
|
605
659
|
const rows = [];
|
|
606
660
|
if (hasTare) {
|
|
607
661
|
rows.push({
|
|
662
|
+
...receiptKey(product, 'gross'),
|
|
608
663
|
item: `${manualFlag}${label(locale, 'gross')}: ${productSku.weight ?? 0}${unit}`,
|
|
609
664
|
value: ''
|
|
610
665
|
});
|
|
611
666
|
rows.push({
|
|
667
|
+
...receiptKey(product, 'tare'),
|
|
612
668
|
item: `${label(locale, 'tare')}: ${productSku.tare_weight}${unit}`,
|
|
613
669
|
value: ''
|
|
614
670
|
});
|
|
@@ -617,6 +673,7 @@ function buildProductOpenWeightRows(params) {
|
|
|
617
673
|
const unitPrice = productSku.unit_price ?? 0;
|
|
618
674
|
const netItem = `${netWeight} ${unit} NET @ ${currencySymbol}${unitPrice}/${unit}`;
|
|
619
675
|
rows.push({
|
|
676
|
+
...receiptTimeKey(product, 'net-weight'),
|
|
620
677
|
item: hasTare ? netItem : `${manualFlag}${netItem}`,
|
|
621
678
|
value: ''
|
|
622
679
|
});
|
|
@@ -672,7 +729,7 @@ function normalizeProductOptions(params) {
|
|
|
672
729
|
parentProduct
|
|
673
730
|
} = params;
|
|
674
731
|
const rawOptions = Array.isArray(params.options) ? params.options : Array.isArray(product.options) ? product.options : Array.isArray(product.product_sku?.option) ? product.product_sku.option : [];
|
|
675
|
-
return rawOptions.map(option => {
|
|
732
|
+
return rawOptions.map((option, sourceIndex) => {
|
|
676
733
|
const price = option.original_price ?? option.add_price ?? option.price;
|
|
677
734
|
const quantity = toNumber(option.num ?? option.quantity ?? 1, 1);
|
|
678
735
|
const value = option.value ?? option.option ?? option.item;
|
|
@@ -682,6 +739,8 @@ function normalizeProductOptions(params) {
|
|
|
682
739
|
locale
|
|
683
740
|
});
|
|
684
741
|
return {
|
|
742
|
+
...receiptKey(option, 'option'),
|
|
743
|
+
...receiptSourceIndex(option, sourceIndex),
|
|
685
744
|
name,
|
|
686
745
|
...(option.num !== undefined || option.quantity !== undefined ? {
|
|
687
746
|
num: quantity
|
|
@@ -705,7 +764,7 @@ function normalizeProductCombinations(params) {
|
|
|
705
764
|
parentProduct
|
|
706
765
|
} = params;
|
|
707
766
|
const bundles = Array.isArray(product.product_bundle) ? product.product_bundle : [];
|
|
708
|
-
return bundles.map(bundle => {
|
|
767
|
+
return bundles.map((bundle, sourceIndex) => {
|
|
709
768
|
const combinationsOptions = normalizeProductOptions({
|
|
710
769
|
product: {},
|
|
711
770
|
locale,
|
|
@@ -735,6 +794,8 @@ function normalizeProductCombinations(params) {
|
|
|
735
794
|
});
|
|
736
795
|
const shouldIncludeBasePrice = combinationsOptions.length > 0 || nestedCombinations.length > 0 || hasProductDiscount(bundle, extensionList);
|
|
737
796
|
return {
|
|
797
|
+
...receiptKey(bundle, 'combination'),
|
|
798
|
+
...receiptSourceIndex(bundle, sourceIndex),
|
|
738
799
|
product_title: baseTitle,
|
|
739
800
|
product_quantity: quantity,
|
|
740
801
|
price: formattedPrice,
|
|
@@ -762,7 +823,7 @@ function normalizeProductCombinations(params) {
|
|
|
762
823
|
});
|
|
763
824
|
}
|
|
764
825
|
function normalizeExistingCombinations(combinations, locale, currencySymbol) {
|
|
765
|
-
return combinations.map(combination => {
|
|
826
|
+
return combinations.map((combination, sourceIndex) => {
|
|
766
827
|
if (!combination || typeof combination !== 'object' || Array.isArray(combination)) {
|
|
767
828
|
return combination;
|
|
768
829
|
}
|
|
@@ -799,6 +860,8 @@ function normalizeExistingCombinations(combinations, locale, currencySymbol) {
|
|
|
799
860
|
const shouldIncludeBasePrice = normalizedOptions.length > 0 || nestedCombinations.length > 0 || hasProductDiscount(combination, extensionList);
|
|
800
861
|
return {
|
|
801
862
|
...snapshot,
|
|
863
|
+
...receiptKey(combination, 'combination'),
|
|
864
|
+
...receiptSourceIndex(combination, sourceIndex),
|
|
802
865
|
...(productTitle ? {
|
|
803
866
|
product_title: productTitle
|
|
804
867
|
} : {}),
|
|
@@ -1072,6 +1135,7 @@ function buildFees(params) {
|
|
|
1072
1135
|
const value = surcharge.amount ?? surcharge.value ?? surcharge.total_amount;
|
|
1073
1136
|
if (!isNonZero(value)) continue;
|
|
1074
1137
|
fees.push({
|
|
1138
|
+
...receiptKey(surcharge, 'surcharge'),
|
|
1075
1139
|
item: getLocalizedValue(surcharge.name || surcharge.title || surcharge.item, locale),
|
|
1076
1140
|
value: formatMoney(value, currencySymbol)
|
|
1077
1141
|
});
|
|
@@ -1079,6 +1143,7 @@ function buildFees(params) {
|
|
|
1079
1143
|
const discountAmount = firstPresentValue(order.shop_discount, summary.discount_amount, order.discount_amount);
|
|
1080
1144
|
if (isNonZero(discountAmount)) {
|
|
1081
1145
|
fees.push({
|
|
1146
|
+
...receiptKey(order, 'order-discount'),
|
|
1082
1147
|
item: label(locale, 'orderDiscount'),
|
|
1083
1148
|
value: formatNegativeMoney(discountAmount, currencySymbol)
|
|
1084
1149
|
});
|
|
@@ -1095,6 +1160,7 @@ function buildFees(params) {
|
|
|
1095
1160
|
const payProcessingFee = financials.payProcessingFee;
|
|
1096
1161
|
if (isNonZero(payProcessingFee)) {
|
|
1097
1162
|
fees.push({
|
|
1163
|
+
...receiptKey(order, 'payment-processing-fee'),
|
|
1098
1164
|
item: label(locale, 'payProcessingFee'),
|
|
1099
1165
|
value: formatMoney(payProcessingFee, currencySymbol)
|
|
1100
1166
|
});
|
|
@@ -1176,12 +1242,15 @@ function calculateProductOriginalAmount(order) {
|
|
|
1176
1242
|
}
|
|
1177
1243
|
function buildCustomer(order, locale) {
|
|
1178
1244
|
return [{
|
|
1245
|
+
...receiptKey(order, 'customer.contactName'),
|
|
1179
1246
|
item: label(locale, 'contactName'),
|
|
1180
1247
|
value: normalizeCustomerDisplayValue(order.customer_name || order.customer?.name || order.customer?.display_name)
|
|
1181
1248
|
}, {
|
|
1249
|
+
...receiptKey(order, 'customer.contactMobile'),
|
|
1182
1250
|
item: label(locale, 'contactMobile'),
|
|
1183
1251
|
value: stringify(order.phone || order.customer?.phone)
|
|
1184
1252
|
}, {
|
|
1253
|
+
...receiptKey(order, 'customer.email'),
|
|
1185
1254
|
item: label(locale, 'email'),
|
|
1186
1255
|
value: stringify(order.email || order.customer?.email)
|
|
1187
1256
|
}];
|
|
@@ -1197,6 +1266,7 @@ function buildDelivery(order, locale) {
|
|
|
1197
1266
|
const serviceTypeLabelKey = resolveServiceTypeLabelKey(serviceType);
|
|
1198
1267
|
if (!serviceTypeLabelKey) return [];
|
|
1199
1268
|
const items = [{
|
|
1269
|
+
...receiptKey(order, 'service-type'),
|
|
1200
1270
|
item: label(locale, serviceTypeLabelKey),
|
|
1201
1271
|
value: '',
|
|
1202
1272
|
size: 2
|
|
@@ -1205,6 +1275,7 @@ function buildDelivery(order, locale) {
|
|
|
1205
1275
|
const pickupTime = formatPickupBookingStart(order.bookings, locale);
|
|
1206
1276
|
if (pickupTime) {
|
|
1207
1277
|
items.push({
|
|
1278
|
+
...receiptTimeKey(order, 'pickup-time'),
|
|
1208
1279
|
item: pickupTime,
|
|
1209
1280
|
value: '',
|
|
1210
1281
|
size: 2
|
|
@@ -1215,6 +1286,7 @@ function buildDelivery(order, locale) {
|
|
|
1215
1286
|
const handoverTime = firstPresentValue(order.handover_time, order.handover_at, order.pickup_time, order.pickup_at, order.scheduled_pickup_time, order.delivery_time, order.delivery_at, order.scheduled_delivery_time, order.fulfillment_time, order.fulfillment_at, order.metadata?.handover_time, order.metadata?.handover_at, order.metadata?.pickup_time, order.metadata?.pickup_at, order.metadata?.scheduled_pickup_time, order.metadata?.delivery_time, order.metadata?.delivery_at, order.metadata?.scheduled_delivery_time, order.metadata?.fulfillment_time, order.metadata?.fulfillment_at);
|
|
1216
1287
|
if (isPresentId(handoverTime)) {
|
|
1217
1288
|
items.push({
|
|
1289
|
+
...receiptKey(order, 'handover-time'),
|
|
1218
1290
|
item: label(locale, 'handoverTime'),
|
|
1219
1291
|
value: formatDateTime(handoverTime, locale)
|
|
1220
1292
|
});
|
|
@@ -1254,6 +1326,7 @@ function buildAppointment(order, locale) {
|
|
|
1254
1326
|
const tableName = order.table_name || order.metadata?.table_name || order.metadata?.table?.name || order.form_data?.table_name;
|
|
1255
1327
|
if (!tableName) return [];
|
|
1256
1328
|
return [{
|
|
1329
|
+
...receiptKey(order, 'table', 'text'),
|
|
1257
1330
|
item: label(locale, 'table'),
|
|
1258
1331
|
value: getLocalizedValue(tableName, locale)
|
|
1259
1332
|
}];
|
|
@@ -1289,18 +1362,22 @@ function buildAppointmentRows(params) {
|
|
|
1289
1362
|
const resourceText = formatBookingResources(resolveBookingResourcesForReceipt(booking, allResources, bookingCount), locale);
|
|
1290
1363
|
const holder = getLocalizedValue(booking.holder?.name ?? booking.metadata?.holder?.name, locale).trim();
|
|
1291
1364
|
return [{
|
|
1365
|
+
...receiptKey(booking, 'booking-id'),
|
|
1292
1366
|
item: label(locale, 'bookingId'),
|
|
1293
1367
|
value: bookingId,
|
|
1294
1368
|
...association
|
|
1295
1369
|
}, {
|
|
1370
|
+
...receiptKey(booking, 'booking-time', 'shared'),
|
|
1296
1371
|
item: label(locale, 'bookingDateTime'),
|
|
1297
1372
|
value: bookingTime,
|
|
1298
1373
|
...association
|
|
1299
1374
|
}, {
|
|
1375
|
+
...receiptKey(booking, 'booking-resource', 'text'),
|
|
1300
1376
|
item: label(locale, 'bookingResource'),
|
|
1301
1377
|
value: resourceText,
|
|
1302
1378
|
...association
|
|
1303
1379
|
}, {
|
|
1380
|
+
...receiptKey(booking, 'booking-holder', 'text'),
|
|
1304
1381
|
item: label(locale, 'bookingHolder'),
|
|
1305
1382
|
value: holder,
|
|
1306
1383
|
...association
|
|
@@ -1386,6 +1463,7 @@ function compareOptionalValues(left, right) {
|
|
|
1386
1463
|
}
|
|
1387
1464
|
function buildResources(order, locale) {
|
|
1388
1465
|
return normalizeArray(order.resources || order.resource_list).map(resource => ({
|
|
1466
|
+
...receiptKey(resource, 'resource', 'text'),
|
|
1389
1467
|
id: resource.id || resource.resource_id || '',
|
|
1390
1468
|
code: '',
|
|
1391
1469
|
title: getLocalizedValue(resource.title || resource.name, locale),
|
|
@@ -1431,12 +1509,14 @@ function buildRefundData(params) {
|
|
|
1431
1509
|
const methodName = paymentMethodName(payment, params.locale) || label(params.locale, 'refund');
|
|
1432
1510
|
const amount = firstPresentValue(refund.amount, refund.refund_amount, refund.total_amount) ?? 0;
|
|
1433
1511
|
const items = [{
|
|
1512
|
+
...receiptKey(refund, 'refund'),
|
|
1434
1513
|
item: methodName,
|
|
1435
1514
|
value: formatNegativeMoney(amount, params.currencySymbol)
|
|
1436
1515
|
}];
|
|
1437
1516
|
const occurredAt = firstPresentValue(refund.refund_time, refund.refunded_at, refund.created_at, refund.updated_at);
|
|
1438
1517
|
if (isPresentId(occurredAt)) {
|
|
1439
1518
|
items.push({
|
|
1519
|
+
...receiptTimeKey(refund, 'refund-time'),
|
|
1440
1520
|
item: formatDateTime(occurredAt, params.locale),
|
|
1441
1521
|
value: ''
|
|
1442
1522
|
});
|
|
@@ -1551,15 +1631,18 @@ function buildProductDiscountAssets(params) {
|
|
|
1551
1631
|
const name = getProductWalletDiscountName(asset, params.locale);
|
|
1552
1632
|
const assetTime = getProductWalletDiscountTime(asset) ?? fallbackAssetTime;
|
|
1553
1633
|
const timeRow = isPresentId(assetTime) ? {
|
|
1634
|
+
...receiptTimeKey(asset.records[0], 'asset-time'),
|
|
1554
1635
|
item: formatDateTime(assetTime, params.locale),
|
|
1555
1636
|
value: ''
|
|
1556
1637
|
} : null;
|
|
1557
1638
|
if (asset.type === 'entitlement_pass') {
|
|
1558
1639
|
const remaining = getProductEntitlementBalance(asset);
|
|
1559
1640
|
return [[{
|
|
1641
|
+
...receiptKey(asset.records[0], 'asset-name'),
|
|
1560
1642
|
item: name,
|
|
1561
1643
|
value: ''
|
|
1562
1644
|
}, ...(remaining ? [{
|
|
1645
|
+
...receiptKey(asset.records[0], 'entitlementRemaining'),
|
|
1563
1646
|
item: label(params.locale, 'entitlementRemaining'),
|
|
1564
1647
|
value: formatEntitlementUses(remaining, params.locale)
|
|
1565
1648
|
}] : []), ...(timeRow ? [timeRow] : [])]];
|
|
@@ -1567,15 +1650,18 @@ function buildProductDiscountAssets(params) {
|
|
|
1567
1650
|
const percent = getProductWalletDiscountPercent(asset);
|
|
1568
1651
|
if (percent) {
|
|
1569
1652
|
return [[{
|
|
1653
|
+
...receiptKey(asset.records[0], 'asset-discount'),
|
|
1570
1654
|
item: appendPercentToVoucherName(name, percent),
|
|
1571
1655
|
value: formatVoucherDiscount(percent, params.locale)
|
|
1572
1656
|
}, ...(timeRow ? [timeRow] : [])]];
|
|
1573
1657
|
}
|
|
1574
1658
|
const balance = getProductWalletMoneyBalance(asset);
|
|
1575
1659
|
return [[{
|
|
1660
|
+
...receiptKey(asset.records[0], 'asset-name'),
|
|
1576
1661
|
item: name,
|
|
1577
1662
|
value: ''
|
|
1578
1663
|
}, ...(balance ? [{
|
|
1664
|
+
...receiptKey(asset.records[0], 'balance'),
|
|
1579
1665
|
item: label(params.locale, 'balance'),
|
|
1580
1666
|
value: formatMoney(balance, params.currencySymbol)
|
|
1581
1667
|
}] : []), ...(timeRow ? [timeRow] : [])]];
|
|
@@ -1737,18 +1823,21 @@ function buildPointCardSnapshotAssets(params) {
|
|
|
1737
1823
|
codes: []
|
|
1738
1824
|
})) return [];
|
|
1739
1825
|
const rows = [{
|
|
1826
|
+
...receiptKey(pointCard, 'asset-name'),
|
|
1740
1827
|
item: appendMaskedCardCode(stringify(pointCard.product_name).trim() || label(params.locale, 'pointCard'), pointCard.code),
|
|
1741
1828
|
value: ''
|
|
1742
1829
|
}];
|
|
1743
1830
|
const remainingPoints = getPointCardSnapshotRemainingPoints(pointCard);
|
|
1744
1831
|
if (remainingPoints) {
|
|
1745
1832
|
rows.push({
|
|
1833
|
+
...receiptKey(pointCard, 'remainingPoints'),
|
|
1746
1834
|
item: label(params.locale, 'remainingPoints'),
|
|
1747
1835
|
value: trimDecimal(remainingPoints)
|
|
1748
1836
|
});
|
|
1749
1837
|
}
|
|
1750
1838
|
if (isPresentId(snapshotTime)) {
|
|
1751
1839
|
rows.push({
|
|
1840
|
+
...receiptTimeKey(pointCard, 'asset-time'),
|
|
1752
1841
|
item: formatDateTime(snapshotTime, params.locale),
|
|
1753
1842
|
value: ''
|
|
1754
1843
|
});
|
|
@@ -1797,18 +1886,21 @@ function buildVirtualCurrencySnapshotAssets(params) {
|
|
|
1797
1886
|
codes: []
|
|
1798
1887
|
})) return [];
|
|
1799
1888
|
const rows = [{
|
|
1889
|
+
...receiptKey(virtualCurrency, 'asset-name'),
|
|
1800
1890
|
item: stringify(virtualCurrency.product_name).trim(),
|
|
1801
1891
|
value: ''
|
|
1802
1892
|
}];
|
|
1803
1893
|
const balance = getVirtualCurrencySnapshotBalance(virtualCurrency);
|
|
1804
1894
|
if (balance) {
|
|
1805
1895
|
rows.push({
|
|
1896
|
+
...receiptKey(virtualCurrency, 'balance'),
|
|
1806
1897
|
item: label(params.locale, 'balance'),
|
|
1807
1898
|
value: formatVirtualCurrencyBalance(balance, getVirtualCurrencySnapshotUnit(virtualCurrency, params.locale))
|
|
1808
1899
|
});
|
|
1809
1900
|
}
|
|
1810
1901
|
if (isPresentId(snapshotTime)) {
|
|
1811
1902
|
rows.push({
|
|
1903
|
+
...receiptTimeKey(virtualCurrency, 'asset-time'),
|
|
1812
1904
|
item: formatDateTime(snapshotTime, params.locale),
|
|
1813
1905
|
value: ''
|
|
1814
1906
|
});
|
|
@@ -1903,15 +1995,18 @@ function buildVoucherAssets(params) {
|
|
|
1903
1995
|
const name = getVoucherAssetName(voucher, params.locale);
|
|
1904
1996
|
const assetTime = firstPresentValue(voucher.updated_at, voucher.created_at, voucher.collection_time, fallbackAssetTime);
|
|
1905
1997
|
const timeRow = isPresentId(assetTime) ? {
|
|
1998
|
+
...receiptTimeKey(voucher, 'asset-time'),
|
|
1906
1999
|
item: formatDateTime(assetTime, params.locale),
|
|
1907
2000
|
value: ''
|
|
1908
2001
|
} : null;
|
|
1909
2002
|
if (isEntitlementVoucher(voucher)) {
|
|
1910
2003
|
const remaining = getEntitlementBalance(voucher.metadata?.balance, voucher.balance);
|
|
1911
2004
|
return [[{
|
|
2005
|
+
...receiptKey(voucher, 'asset-name'),
|
|
1912
2006
|
item: name,
|
|
1913
2007
|
value: ''
|
|
1914
2008
|
}, ...(remaining ? [{
|
|
2009
|
+
...receiptKey(voucher, 'entitlementRemaining'),
|
|
1915
2010
|
item: label(params.locale, 'entitlementRemaining'),
|
|
1916
2011
|
value: formatEntitlementUses(remaining, params.locale)
|
|
1917
2012
|
}] : []), ...(timeRow ? [timeRow] : [])]];
|
|
@@ -1919,9 +2014,11 @@ function buildVoucherAssets(params) {
|
|
|
1919
2014
|
if (isTicketVoucher(voucher)) {
|
|
1920
2015
|
const validity = getVoucherValidity(voucher, params.locale);
|
|
1921
2016
|
return [[{
|
|
2017
|
+
...receiptKey(voucher, 'asset-name'),
|
|
1922
2018
|
item: name,
|
|
1923
2019
|
value: ''
|
|
1924
2020
|
}, ...(validity ? [{
|
|
2021
|
+
...receiptKey(voucher, 'validity'),
|
|
1925
2022
|
item: label(params.locale, 'validity'),
|
|
1926
2023
|
value: validity
|
|
1927
2024
|
}] : [])]];
|
|
@@ -1929,15 +2026,18 @@ function buildVoucherAssets(params) {
|
|
|
1929
2026
|
const percent = getVoucherDiscountPercent(voucher);
|
|
1930
2027
|
if (percent) {
|
|
1931
2028
|
return [[{
|
|
2029
|
+
...receiptKey(voucher, 'asset-discount'),
|
|
1932
2030
|
item: appendPercentToVoucherName(name, percent),
|
|
1933
2031
|
value: formatVoucherDiscount(percent, params.locale)
|
|
1934
2032
|
}, ...(timeRow ? [timeRow] : [])]];
|
|
1935
2033
|
}
|
|
1936
2034
|
const balance = getVoucherBalance(voucher);
|
|
1937
2035
|
return [[{
|
|
2036
|
+
...receiptKey(voucher, 'asset-name'),
|
|
1938
2037
|
item: name,
|
|
1939
2038
|
value: ''
|
|
1940
2039
|
}, {
|
|
2040
|
+
...receiptKey(voucher, 'balance'),
|
|
1941
2041
|
item: label(params.locale, 'balance'),
|
|
1942
2042
|
value: formatMoney(balance, params.currencySymbol)
|
|
1943
2043
|
}, ...(timeRow ? [timeRow] : [])]];
|
|
@@ -2071,6 +2171,7 @@ function buildPaymentItems(params) {
|
|
|
2071
2171
|
} = params;
|
|
2072
2172
|
const serviceFee = getPaymentServiceFee(payment);
|
|
2073
2173
|
const items = [{
|
|
2174
|
+
...receiptKey(payment, 'payment'),
|
|
2074
2175
|
item: paymentMethodName(payment, locale),
|
|
2075
2176
|
value: includePaymentAmount ? formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), currencySymbol) : ''
|
|
2076
2177
|
}];
|
|
@@ -2081,6 +2182,7 @@ function buildPaymentItems(params) {
|
|
|
2081
2182
|
}));
|
|
2082
2183
|
if (serviceFee.gt(0)) {
|
|
2083
2184
|
items.push({
|
|
2185
|
+
...receiptKey(payment, 'surchargeIncluded'),
|
|
2084
2186
|
item: label(locale, 'surchargeIncluded'),
|
|
2085
2187
|
value: formatMoney(serviceFee, currencySymbol)
|
|
2086
2188
|
});
|
|
@@ -2100,16 +2202,21 @@ function buildPaymentItems(params) {
|
|
|
2100
2202
|
const remainingAmount = payment.remaining_amount ?? payment.balance ?? payment.metadata?.remaining_amount;
|
|
2101
2203
|
if (remainingAmount !== undefined && remainingAmount !== null) {
|
|
2102
2204
|
items.push({
|
|
2205
|
+
...receiptKey(payment, 'remainingAmount'),
|
|
2103
2206
|
item: label(locale, 'remainingAmount'),
|
|
2104
2207
|
value: formatMoney(remainingAmount, currencySymbol)
|
|
2105
2208
|
});
|
|
2106
2209
|
}
|
|
2107
2210
|
}
|
|
2108
2211
|
items.push({
|
|
2212
|
+
...receiptTimeKey(payment, 'payment-time'),
|
|
2109
2213
|
item: formatDateTime(payment.paid_at || payment.created_at || payment.updated_at || new Date(), locale),
|
|
2110
2214
|
value: ''
|
|
2111
2215
|
});
|
|
2112
|
-
return items
|
|
2216
|
+
return items.map(item => item.receipt_key ? {
|
|
2217
|
+
...item,
|
|
2218
|
+
receipt_key: `${item.receipt_key}/${includeFundRecordBalance ? 'wallet' : 'history'}`
|
|
2219
|
+
} : item);
|
|
2113
2220
|
}
|
|
2114
2221
|
function getPaymentServiceFee(payment) {
|
|
2115
2222
|
return new _decimal.default(toMoneyNumber(payment.service_fee));
|
|
@@ -2130,9 +2237,11 @@ function buildCashChangePaymentItems(params) {
|
|
|
2130
2237
|
} = params;
|
|
2131
2238
|
if (!shouldDisplayCashChange(payment)) return [];
|
|
2132
2239
|
return [{
|
|
2240
|
+
...receiptKey(payment, 'cashReceived'),
|
|
2133
2241
|
item: label(locale, 'cashReceived'),
|
|
2134
2242
|
value: formatMoney(payment.metadata.actual_paid_amount, currencySymbol)
|
|
2135
2243
|
}, {
|
|
2244
|
+
...receiptKey(payment, 'changeDue'),
|
|
2136
2245
|
item: label(locale, 'changeDue'),
|
|
2137
2246
|
value: formatMoney(payment.metadata.change_given_amount, currencySymbol)
|
|
2138
2247
|
}];
|
|
@@ -2169,12 +2278,14 @@ function buildFundRecordPaymentItems(params) {
|
|
|
2169
2278
|
const usedPoints = new _decimal.default(toMoneyNumber(usingBeforeValue)).minus(toMoneyNumber(usingAfterValue));
|
|
2170
2279
|
if (includeUsage) {
|
|
2171
2280
|
items.push({
|
|
2281
|
+
...receiptKey(payment, 'redeemPoints'),
|
|
2172
2282
|
item: label(locale, 'redeemPoints'),
|
|
2173
2283
|
value: trimDecimal(usedPoints)
|
|
2174
2284
|
});
|
|
2175
2285
|
}
|
|
2176
2286
|
if (includeBalance) {
|
|
2177
2287
|
items.push({
|
|
2288
|
+
...receiptKey(payment, 'remainingPoints'),
|
|
2178
2289
|
item: label(locale, 'remainingPoints'),
|
|
2179
2290
|
value: trimDecimal(new _decimal.default(toMoneyNumber(usingAfterValue)))
|
|
2180
2291
|
});
|
|
@@ -2185,12 +2296,14 @@ function buildFundRecordPaymentItems(params) {
|
|
|
2185
2296
|
if (virtualCurrencyUnit !== undefined) {
|
|
2186
2297
|
if (!isNumericAmount(usingAfterValue)) return items;
|
|
2187
2298
|
items.push({
|
|
2299
|
+
...receiptKey(payment, 'balance'),
|
|
2188
2300
|
item: label(locale, 'balance'),
|
|
2189
2301
|
value: formatVirtualCurrencyBalance(new _decimal.default(usingAfterValue), virtualCurrencyUnit)
|
|
2190
2302
|
});
|
|
2191
2303
|
return items;
|
|
2192
2304
|
}
|
|
2193
2305
|
items.push({
|
|
2306
|
+
...receiptKey(payment, 'balance'),
|
|
2194
2307
|
item: label(locale, 'balance'),
|
|
2195
2308
|
value: formatMoney(usingAfterValue, currencySymbol)
|
|
2196
2309
|
});
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 2 | 1 |
|
|
329
|
+
weekNum: 0 | 2 | 1 | 6 | 4 | 5 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Module, ModuleOptions, PisellCore } from '../../types';
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
|
+
import { type CustomerInvoiceLanguageCode, type CustomerInvoiceLanguageOption } from '../../shared/receipt/customerInvoiceLanguages';
|
|
4
|
+
export type { CustomerInvoiceLanguageCode, CustomerInvoiceLanguageOption, } from '../../shared/receipt/customerInvoiceLanguages';
|
|
3
5
|
import type { InvoiceLayoutConfig } from '../../modules/OpenData';
|
|
4
6
|
import { type SmallTicketData } from '../../shared/receipt/small-ticket';
|
|
5
7
|
export interface OrderInvoicePreviewInput {
|
|
@@ -19,6 +21,9 @@ export interface OrderInvoicePreviewResult {
|
|
|
19
21
|
sourceRevision: string;
|
|
20
22
|
generatedAt: string;
|
|
21
23
|
locale: string;
|
|
24
|
+
secondaryLocale?: string;
|
|
25
|
+
languageOptions: CustomerInvoiceLanguageOption[];
|
|
26
|
+
selectedLanguage: CustomerInvoiceLanguageCode;
|
|
22
27
|
orderId: string | number;
|
|
23
28
|
source: Record<string, any>;
|
|
24
29
|
shop: Record<string, any>;
|
|
@@ -40,6 +45,7 @@ export declare class OrderInvoicePreviewImpl extends BaseModule implements Modul
|
|
|
40
45
|
private disposed;
|
|
41
46
|
private input?;
|
|
42
47
|
private activeKey;
|
|
48
|
+
private languageSelection?;
|
|
43
49
|
private pending?;
|
|
44
50
|
private snapshotCache;
|
|
45
51
|
constructor(name?: string);
|
|
@@ -51,6 +57,10 @@ export declare class OrderInvoicePreviewImpl extends BaseModule implements Modul
|
|
|
51
57
|
private loadContext;
|
|
52
58
|
private loadSource;
|
|
53
59
|
prepare(input: OrderInvoicePreviewInput): Promise<OrderInvoicePreviewResult>;
|
|
60
|
+
private getSelectionScope;
|
|
61
|
+
private documentIdentity;
|
|
62
|
+
/** Switch only the ready receipt projection; no fetching or rebuilding data. */
|
|
63
|
+
selectLanguage(code: string): OrderInvoicePreviewResult;
|
|
54
64
|
retry(): Promise<OrderInvoicePreviewResult>;
|
|
55
65
|
destroy(): void;
|
|
56
66
|
}
|