@pisell/pisellos 2.2.294 → 2.2.296
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/model/strategy/adapter/itemRule/adapter.d.ts +1 -4
- package/dist/model/strategy/adapter/itemRule/adapter.js +35 -135
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +1 -8
- package/dist/model/strategy/adapter/itemRule/evaluator.js +1 -25
- package/dist/model/strategy/adapter/itemRule/type.d.ts +0 -44
- package/dist/model/strategy/adapter/itemRule/type.js +1 -19
- package/dist/modules/Order/index.d.ts +3 -18
- package/dist/modules/Order/index.js +485 -885
- package/dist/modules/Order/types.d.ts +5 -91
- package/dist/modules/Order/types.js +0 -5
- package/dist/modules/Order/utils.js +10 -22
- package/dist/modules/ProductList/index.d.ts +1 -2
- package/dist/modules/ProductList/index.js +20 -100
- package/dist/modules/ProductList/types.d.ts +0 -10
- package/dist/server/index.d.ts +0 -6
- package/dist/server/index.js +3 -43
- package/dist/server/utils/small-ticket.js +49 -1
- package/dist/solution/BaseSales/index.d.ts +1 -9
- package/dist/solution/BaseSales/index.js +706 -894
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/utils/orderCustomer.js +2 -3
- package/dist/solution/RegisterAndLogin/config.d.ts +3 -9
- package/dist/solution/RegisterAndLogin/config.js +40 -95
- package/dist/solution/RegisterAndLogin/index.js +1 -4
- package/dist/solution/ScanOrder/index.d.ts +0 -1
- package/dist/solution/ScanOrder/index.js +27 -31
- package/dist/solution/ScanOrder/utils.d.ts +0 -1
- package/dist/solution/ScanOrder/utils.js +0 -2
- package/dist/solution/UnifiedBookingSales/index.d.ts +2 -15
- package/dist/solution/UnifiedBookingSales/index.js +484 -752
- package/dist/solution/UnifiedBookingSales/types.d.ts +1 -14
- package/dist/solution/VenueBooking/index.d.ts +0 -1
- package/dist/solution/VenueBooking/index.js +4 -8
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +1 -4
- package/lib/model/strategy/adapter/itemRule/adapter.js +4 -73
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +1 -8
- package/lib/model/strategy/adapter/itemRule/evaluator.js +1 -23
- package/lib/model/strategy/adapter/itemRule/type.d.ts +0 -44
- package/lib/model/strategy/adapter/itemRule/type.js +1 -19
- package/lib/model/strategy/adapter/promotion/index.js +1 -46
- package/lib/modules/Order/index.d.ts +3 -18
- package/lib/modules/Order/index.js +28 -325
- package/lib/modules/Order/types.d.ts +5 -91
- package/lib/modules/Order/types.js +0 -4
- package/lib/modules/Order/utils.js +1 -13
- package/lib/modules/ProductList/index.d.ts +1 -2
- package/lib/modules/ProductList/index.js +2 -47
- package/lib/modules/ProductList/types.d.ts +0 -10
- package/lib/server/index.d.ts +0 -6
- package/lib/server/index.js +3 -37
- package/lib/server/utils/small-ticket.js +50 -1
- package/lib/solution/BaseSales/index.d.ts +1 -9
- package/lib/solution/BaseSales/index.js +1 -105
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/utils/orderCustomer.js +1 -2
- package/lib/solution/RegisterAndLogin/config.d.ts +3 -9
- package/lib/solution/RegisterAndLogin/config.js +8 -49
- package/lib/solution/RegisterAndLogin/index.js +1 -4
- package/lib/solution/ScanOrder/index.d.ts +0 -1
- package/lib/solution/ScanOrder/index.js +1 -5
- package/lib/solution/ScanOrder/utils.d.ts +0 -1
- package/lib/solution/ScanOrder/utils.js +0 -1
- package/lib/solution/UnifiedBookingSales/index.d.ts +2 -15
- package/lib/solution/UnifiedBookingSales/index.js +1 -125
- package/lib/solution/UnifiedBookingSales/types.d.ts +1 -14
- package/lib/solution/VenueBooking/index.d.ts +0 -1
- package/lib/solution/VenueBooking/index.js +1 -5
- package/package.json +1 -1
- package/dist/modules/Order/salesNotes.d.ts +0 -31
- package/dist/modules/Order/salesNotes.js +0 -492
- package/lib/modules/Order/salesNotes.d.ts +0 -31
- package/lib/modules/Order/salesNotes.js +0 -382
|
@@ -126,7 +126,6 @@ var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
|
126
126
|
var _utils = require("../Holder/utils");
|
|
127
127
|
var _utils2 = require("../../solution/ScanOrder/utils");
|
|
128
128
|
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
129
|
-
var _salesNotes = require("./salesNotes");
|
|
130
129
|
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
131
130
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
132
131
|
/**
|
|
@@ -1129,7 +1128,6 @@ function createDefaultTempOrder(params) {
|
|
|
1129
1128
|
request_unique_idempotency_token: '',
|
|
1130
1129
|
vouchers: [],
|
|
1131
1130
|
products: [],
|
|
1132
|
-
notes: [],
|
|
1133
1131
|
bookings: [],
|
|
1134
1132
|
payments: [],
|
|
1135
1133
|
surcharges: [],
|
|
@@ -1139,11 +1137,7 @@ function createDefaultTempOrder(params) {
|
|
|
1139
1137
|
holder: null,
|
|
1140
1138
|
metadata: {},
|
|
1141
1139
|
_extend: {
|
|
1142
|
-
productsByUid: {}
|
|
1143
|
-
salesNotesState: {
|
|
1144
|
-
loaded: true,
|
|
1145
|
-
dirty: false
|
|
1146
|
-
}
|
|
1140
|
+
productsByUid: {}
|
|
1147
1141
|
}
|
|
1148
1142
|
};
|
|
1149
1143
|
}
|
|
@@ -1224,7 +1218,6 @@ function buildSubmitPayload(params) {
|
|
|
1224
1218
|
total_refund_amount: _totalRefundAmount,
|
|
1225
1219
|
create_date: _createDate,
|
|
1226
1220
|
holder_id: _holderId,
|
|
1227
|
-
notes: _notes,
|
|
1228
1221
|
...tempOrderRest
|
|
1229
1222
|
} = tempOrder;
|
|
1230
1223
|
const resolvedBusinessCode = businessCode ?? tempOrder.business_code;
|
|
@@ -1282,11 +1275,6 @@ function buildSubmitPayload(params) {
|
|
|
1282
1275
|
...rest
|
|
1283
1276
|
};
|
|
1284
1277
|
})(),
|
|
1285
|
-
...(tempOrder._extend?.salesNotesState?.dirty ? {
|
|
1286
|
-
notes: (0, _salesNotes.encodeSalesNotes)(tempOrder.notes || [], {
|
|
1287
|
-
allowUnresolvedOrderTarget: true
|
|
1288
|
-
})
|
|
1289
|
-
} : {}),
|
|
1290
1278
|
products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product))
|
|
1291
1279
|
};
|
|
1292
1280
|
if (!enhance) return payload;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, PisellCore } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { ProductListLoadProductsParams
|
|
3
|
+
import { ProductListLoadProductsParams } from './types';
|
|
4
4
|
import { ProductData } from '../Product/types';
|
|
5
5
|
export * from './types';
|
|
6
6
|
export declare class ProductList extends BaseModule implements Module {
|
|
@@ -52,7 +52,6 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
52
52
|
getRawProductPriceSources(ids: number[]): Map<number, ProductData>;
|
|
53
53
|
getProducts(): Promise<ProductData[]>;
|
|
54
54
|
getProduct(id: number): Promise<ProductData | undefined>;
|
|
55
|
-
queryProducts(params?: ProductListStoreQueryParams): Promise<ProductData[]>;
|
|
56
55
|
getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
|
|
57
56
|
addProduct(products: ProductData[]): Promise<void>;
|
|
58
57
|
selectProducts(products: ProductData[]): Promise<void>;
|
|
@@ -25,15 +25,6 @@ Object.keys(_types).forEach(function (key) {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
|
-
function normalizeQuerySet(values) {
|
|
29
|
-
if (!Array.isArray(values) || values.length === 0) return null;
|
|
30
|
-
const normalized = values.map(value => String(value ?? '').trim()).filter(Boolean);
|
|
31
|
-
return normalized.length ? new Set(normalized) : null;
|
|
32
|
-
}
|
|
33
|
-
function matchesAny(values, querySet) {
|
|
34
|
-
if (!querySet) return true;
|
|
35
|
-
return values.some(value => querySet.has(String(value ?? '').trim()));
|
|
36
|
-
}
|
|
37
28
|
class ProductList extends _BaseModule.BaseModule {
|
|
38
29
|
defaultName = 'productList';
|
|
39
30
|
defaultVersion = '1.0.0';
|
|
@@ -290,46 +281,10 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
290
281
|
const product = this.store.list.find(product => product.id === id);
|
|
291
282
|
return product ? (0, _lodashEs.cloneDeep)(product) : undefined;
|
|
292
283
|
}
|
|
293
|
-
async queryProducts(params = {}) {
|
|
294
|
-
const includeIds = normalizeQuerySet(params.includeIds);
|
|
295
|
-
const excludeIds = normalizeQuerySet(params.excludeIds);
|
|
296
|
-
const categoryIds = normalizeQuerySet(params.categoryIds);
|
|
297
|
-
const collectionIds = normalizeQuerySet(params.collectionIds);
|
|
298
|
-
const extensionTypes = normalizeQuerySet(params.extensionTypes);
|
|
299
|
-
const statuses = normalizeQuerySet(params.statuses);
|
|
300
|
-
const channelApplications = normalizeQuerySet(params.channelApplications);
|
|
301
|
-
const codeOrBarcode = typeof params.codeOrBarcode === 'string' ? params.codeOrBarcode.trim() : '';
|
|
302
|
-
const products = (this.store.list || []).filter(product => {
|
|
303
|
-
const productId = String(product.id ?? '').trim();
|
|
304
|
-
if (includeIds && !includeIds.has(productId)) return false;
|
|
305
|
-
if (excludeIds && excludeIds.has(productId)) return false;
|
|
306
|
-
if (categoryIds) {
|
|
307
|
-
const productCategoryIds = (product.categories || []).flatMap(category => [category?.id, category?.pivot?.product_category_id]);
|
|
308
|
-
if (!matchesAny(productCategoryIds, categoryIds)) return false;
|
|
309
|
-
}
|
|
310
|
-
if (collectionIds) {
|
|
311
|
-
const productCollectionIds = (product.collection || []).map(collection => collection?.id);
|
|
312
|
-
if (!matchesAny(productCollectionIds, collectionIds)) return false;
|
|
313
|
-
}
|
|
314
|
-
if (extensionTypes && !extensionTypes.has(String(product.extension_type ?? '').trim())) return false;
|
|
315
|
-
if (statuses && !statuses.has(String(product.status ?? '').trim())) return false;
|
|
316
|
-
if (channelApplications) {
|
|
317
|
-
if (!matchesAny(product.channel_application || [], channelApplications)) return false;
|
|
318
|
-
}
|
|
319
|
-
if (codeOrBarcode) {
|
|
320
|
-
const code = typeof product.code === 'string' ? product.code.trim() : '';
|
|
321
|
-
const barcode = typeof product.barcode === 'string' ? product.barcode.trim() : '';
|
|
322
|
-
if (code !== codeOrBarcode && barcode !== codeOrBarcode) return false;
|
|
323
|
-
}
|
|
324
|
-
return true;
|
|
325
|
-
});
|
|
326
|
-
return (0, _lodashEs.cloneDeep)(products);
|
|
327
|
-
}
|
|
328
284
|
async getProductByIds(ids) {
|
|
329
285
|
await this.core.effects.emit(`${this.name}:onGetProductByIds`, this.store.list);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
});
|
|
286
|
+
const products = this.store.list.filter(product => ids.includes(product.id));
|
|
287
|
+
return products;
|
|
333
288
|
}
|
|
334
289
|
async addProduct(products) {
|
|
335
290
|
// list 需要根据 id 去重
|
|
@@ -15,16 +15,6 @@ export interface ProductListLoadProductsParams {
|
|
|
15
15
|
/** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
|
|
16
16
|
strategy_context?: Record<string, any>;
|
|
17
17
|
}
|
|
18
|
-
export interface ProductListStoreQueryParams {
|
|
19
|
-
includeIds?: Array<number | string>;
|
|
20
|
-
excludeIds?: Array<number | string>;
|
|
21
|
-
categoryIds?: Array<number | string>;
|
|
22
|
-
collectionIds?: Array<number | string>;
|
|
23
|
-
extensionTypes?: string[];
|
|
24
|
-
statuses?: ProductData['status'][];
|
|
25
|
-
channelApplications?: string[];
|
|
26
|
-
codeOrBarcode?: string;
|
|
27
|
-
}
|
|
28
18
|
export interface ProductListData {
|
|
29
19
|
list: ProductData[];
|
|
30
20
|
selectProducts: ProductData[];
|
package/lib/server/index.d.ts
CHANGED
|
@@ -520,12 +520,6 @@ declare class Server {
|
|
|
520
520
|
private stringifyCheckoutResourceIdentifier;
|
|
521
521
|
private normalizeCheckoutSubmitData;
|
|
522
522
|
private ensureCheckoutOrderNumbers;
|
|
523
|
-
/**
|
|
524
|
-
* Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
|
|
525
|
-
* shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
|
|
526
|
-
* 都使用同一份完整快照。
|
|
527
|
-
*/
|
|
528
|
-
private finalizeCheckoutSalesNotes;
|
|
529
523
|
private dispatchCheckoutSyncTask;
|
|
530
524
|
private dispatchPrintOtherReceiptTask;
|
|
531
525
|
private buildPrintOtherReceiptIdempotencyKey;
|
package/lib/server/index.js
CHANGED
|
@@ -27,7 +27,6 @@ var _filterBookings = require("./modules/order/utils/filterBookings");
|
|
|
27
27
|
var _smallTicket = require("./utils/small-ticket");
|
|
28
28
|
var _BaseSales = require("../solution/BaseSales");
|
|
29
29
|
var _paymentUtils = require("../modules/Order/payment-utils");
|
|
30
|
-
var _salesNotes = require("../modules/Order/salesNotes");
|
|
31
30
|
var _modules = require("./modules");
|
|
32
31
|
Object.keys(_modules).forEach(function (key) {
|
|
33
32
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -3588,16 +3587,14 @@ class Server {
|
|
|
3588
3587
|
};
|
|
3589
3588
|
const needsShopOrderNumber = next.shop_order_number === undefined || next.shop_order_number === null || next.shop_order_number === '';
|
|
3590
3589
|
const needsShopFullOrderNumber = next.shop_full_order_number === undefined || next.shop_full_order_number === null || next.shop_full_order_number === '';
|
|
3591
|
-
if (!needsShopOrderNumber && !needsShopFullOrderNumber)
|
|
3592
|
-
return this.finalizeCheckoutSalesNotes(next, title);
|
|
3593
|
-
}
|
|
3590
|
+
if (!needsShopOrderNumber && !needsShopFullOrderNumber) return next;
|
|
3594
3591
|
const idGenerator = this.getIdGeneratorPlugin();
|
|
3595
3592
|
if (!idGenerator) {
|
|
3596
3593
|
this.logWarning(`${title}: idGenerator 插件不可用,无法生成订单号`, {
|
|
3597
3594
|
needsShopOrderNumber,
|
|
3598
3595
|
needsShopFullOrderNumber
|
|
3599
3596
|
});
|
|
3600
|
-
return
|
|
3597
|
+
return next;
|
|
3601
3598
|
}
|
|
3602
3599
|
try {
|
|
3603
3600
|
if (needsShopOrderNumber && idGenerator.generateShopOrderNumber) {
|
|
@@ -3619,38 +3616,7 @@ class Server {
|
|
|
3619
3616
|
error: error instanceof Error ? error.message : String(error)
|
|
3620
3617
|
});
|
|
3621
3618
|
}
|
|
3622
|
-
return
|
|
3623
|
-
}
|
|
3624
|
-
|
|
3625
|
-
/**
|
|
3626
|
-
* Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
|
|
3627
|
-
* shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
|
|
3628
|
-
* 都使用同一份完整快照。
|
|
3629
|
-
*/
|
|
3630
|
-
finalizeCheckoutSalesNotes(data, title) {
|
|
3631
|
-
if (!data || typeof data !== 'object') return data;
|
|
3632
|
-
if (!Object.prototype.hasOwnProperty.call(data, 'notes')) return data;
|
|
3633
|
-
if (data.notes === undefined || data.notes === null) return data;
|
|
3634
|
-
if (!Array.isArray(data.notes)) {
|
|
3635
|
-
throw new Error('[Order Notes] checkout notes 必须为数组');
|
|
3636
|
-
}
|
|
3637
|
-
if (data.notes.length === 0) return data;
|
|
3638
|
-
const productTargetUuids = (Array.isArray(data.products) ? data.products : []).map(product => product?.metadata?.unique_identification_number ?? product?.unique_identification_number).filter(targetUuid => targetUuid !== undefined && targetUuid !== null && String(targetUuid).trim().length > 0).map(targetUuid => String(targetUuid));
|
|
3639
|
-
const shopOrderNumber = String(data.shop_order_number ?? '').trim();
|
|
3640
|
-
const notes = (0, _salesNotes.finalizeSalesNotesForCheckout)({
|
|
3641
|
-
notes: data.notes,
|
|
3642
|
-
shopOrderNumber,
|
|
3643
|
-
productTargetUuids
|
|
3644
|
-
});
|
|
3645
|
-
this.logInfo(`${title}: checkout Notes 已绑定订单号`, {
|
|
3646
|
-
shop_order_number: shopOrderNumber,
|
|
3647
|
-
note_count: notes.length
|
|
3648
|
-
});
|
|
3649
|
-
return {
|
|
3650
|
-
...data,
|
|
3651
|
-
shop_order_number: shopOrderNumber,
|
|
3652
|
-
notes
|
|
3653
|
-
};
|
|
3619
|
+
return next;
|
|
3654
3620
|
}
|
|
3655
3621
|
async dispatchCheckoutSyncTask(params) {
|
|
3656
3622
|
this.registerDeviceTaskActions();
|
|
@@ -22,6 +22,8 @@ const LABELS = {
|
|
|
22
22
|
pickUpTime: 'Pick-up time',
|
|
23
23
|
asap: 'ASAP',
|
|
24
24
|
cash: 'Cash',
|
|
25
|
+
cashReceived: 'Cash received',
|
|
26
|
+
changeDue: 'Change due',
|
|
25
27
|
eftpos: 'Eftpos',
|
|
26
28
|
wallet: 'Wallet',
|
|
27
29
|
giftCard: 'Gift card',
|
|
@@ -49,6 +51,8 @@ const LABELS = {
|
|
|
49
51
|
pickUpTime: '取餐时间',
|
|
50
52
|
asap: '尽快',
|
|
51
53
|
cash: '现金支付',
|
|
54
|
+
cashReceived: '收取现金',
|
|
55
|
+
changeDue: '找零',
|
|
52
56
|
eftpos: '刷卡支付',
|
|
53
57
|
wallet: '钱包支付',
|
|
54
58
|
giftCard: '礼品卡',
|
|
@@ -76,6 +80,8 @@ const LABELS = {
|
|
|
76
80
|
pickUpTime: '取餐時間',
|
|
77
81
|
asap: '盡快',
|
|
78
82
|
cash: '現金支付',
|
|
83
|
+
cashReceived: '收取現金',
|
|
84
|
+
changeDue: '找零',
|
|
79
85
|
eftpos: '刷卡支付',
|
|
80
86
|
wallet: '錢包支付',
|
|
81
87
|
giftCard: '禮品卡',
|
|
@@ -90,6 +96,14 @@ const LABELS = {
|
|
|
90
96
|
rounding: '抹零',
|
|
91
97
|
gross: '重量',
|
|
92
98
|
tare: '去皮'
|
|
99
|
+
},
|
|
100
|
+
ja: {
|
|
101
|
+
cashReceived: 'お預かり',
|
|
102
|
+
changeDue: 'お釣り'
|
|
103
|
+
},
|
|
104
|
+
pt: {
|
|
105
|
+
cashReceived: 'Dinheiro recebido',
|
|
106
|
+
changeDue: 'Troco'
|
|
93
107
|
}
|
|
94
108
|
};
|
|
95
109
|
function buildSmallTicketData(params) {
|
|
@@ -169,7 +183,7 @@ function buildBaseData(params) {
|
|
|
169
183
|
order_number: orderNumber,
|
|
170
184
|
shop_tax_number: stringify(shopInfo.tax_number || order.shop_tax_number),
|
|
171
185
|
shop_phone: stringify(shopInfo.phone || order.shop_phone),
|
|
172
|
-
shop_address: stringify(shopInfo.address || buildShopAddress(shopInfo) || order.shop_address),
|
|
186
|
+
shop_address: stringify(shopInfo.receipt_address || shopInfo.address || buildShopAddress(shopInfo) || order.shop_address),
|
|
173
187
|
original_payment_status: stringify(order.payment_status),
|
|
174
188
|
is_repeat: 0,
|
|
175
189
|
buzzer: stringify(order.buzzer || order.pickup_number || order.metadata?.buzzer),
|
|
@@ -807,6 +821,11 @@ function buildPaymentItems(params) {
|
|
|
807
821
|
item: paymentMethodName(payment, locale),
|
|
808
822
|
value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), currencySymbol)
|
|
809
823
|
}];
|
|
824
|
+
items.push(...buildCashChangePaymentItems({
|
|
825
|
+
payment,
|
|
826
|
+
locale,
|
|
827
|
+
currencySymbol
|
|
828
|
+
}));
|
|
810
829
|
if (serviceFee.gt(0)) {
|
|
811
830
|
items.push({
|
|
812
831
|
item: label(locale, 'surchargeIncluded'),
|
|
@@ -848,6 +867,36 @@ function resolveReceiptPaymentAmount(payment, serviceFee) {
|
|
|
848
867
|
const originAmount = new _decimal.default(toMoneyNumber(payment.origin_amount));
|
|
849
868
|
return amount.eq(originAmount) ? amount.plus(serviceFee) : amount;
|
|
850
869
|
}
|
|
870
|
+
function buildCashChangePaymentItems(params) {
|
|
871
|
+
const {
|
|
872
|
+
payment,
|
|
873
|
+
locale,
|
|
874
|
+
currencySymbol
|
|
875
|
+
} = params;
|
|
876
|
+
if (!shouldDisplayCashChange(payment)) return [];
|
|
877
|
+
return [{
|
|
878
|
+
item: label(locale, 'cashReceived'),
|
|
879
|
+
value: formatMoney(payment.metadata.actual_paid_amount, currencySymbol)
|
|
880
|
+
}, {
|
|
881
|
+
item: label(locale, 'changeDue'),
|
|
882
|
+
value: formatMoney(payment.metadata.change_given_amount, currencySymbol)
|
|
883
|
+
}];
|
|
884
|
+
}
|
|
885
|
+
function shouldDisplayCashChange(payment) {
|
|
886
|
+
if (stringify(payment.status).toLowerCase() !== 'paid') return false;
|
|
887
|
+
const paymentMethod = stringify(payment.code ?? payment.payment_method).toUpperCase();
|
|
888
|
+
if (paymentMethod !== 'CASHMANUAL') return false;
|
|
889
|
+
const actualPaidAmount = payment.metadata?.actual_paid_amount;
|
|
890
|
+
const changeGivenAmount = payment.metadata?.change_given_amount;
|
|
891
|
+
if (!isNumericAmount(actualPaidAmount) || !isNumericAmount(changeGivenAmount)) return false;
|
|
892
|
+
return new _decimal.default(changeGivenAmount).toDecimalPlaces(2).gt(0);
|
|
893
|
+
}
|
|
894
|
+
function isNumericAmount(value) {
|
|
895
|
+
if (typeof value === 'number') return Number.isFinite(value);
|
|
896
|
+
if (typeof value !== 'string') return false;
|
|
897
|
+
const normalized = value.trim();
|
|
898
|
+
return normalized !== '' && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(normalized);
|
|
899
|
+
}
|
|
851
900
|
function buildFundRecordPaymentItems(params) {
|
|
852
901
|
const {
|
|
853
902
|
payment,
|
|
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
3
|
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
4
4
|
import { OrderModule } from '../../modules/Order';
|
|
5
|
-
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions
|
|
5
|
+
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions } from '../../modules/Order/types';
|
|
6
6
|
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
7
7
|
import type { Discount } from '../../modules/Discount/types';
|
|
8
8
|
import { RequestPlugin, WindowPlugin } from '../../plugins';
|
|
@@ -225,20 +225,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
225
225
|
getOrderSyncState(): import("../../modules/Order/types").OrderSyncState;
|
|
226
226
|
getOrderAmountSnapshot(): import("../../modules/Order/types").OrderAmountSnapshot | null;
|
|
227
227
|
getTempOrderNote(): string;
|
|
228
|
-
getSalesNotes(): SalesNote[];
|
|
229
|
-
createSalesNotesMutationSnapshot(): SalesNotesMutationSnapshot;
|
|
230
|
-
restoreSalesNotesMutationSnapshot(snapshot: SalesNotesMutationSnapshot): void;
|
|
231
|
-
setSalesNote(input: SetSalesNoteInput): Promise<SalesNote>;
|
|
232
|
-
removeSalesNote(uuid: string): Promise<void>;
|
|
233
|
-
clearSalesNotes(): Promise<void>;
|
|
234
228
|
updateTempOrderNote(note: string): string;
|
|
235
229
|
updateTempOrderNote(note: string, sync: true): Promise<string>;
|
|
236
230
|
updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
|
|
237
231
|
updateRemoteOrderNote(orderId: number | string, note: string): void;
|
|
238
232
|
updateTempOrderShopDiscount(amount: string | number): string;
|
|
239
233
|
updateTempOrderDepositAmount(amount: string | number): OrderSummary;
|
|
240
|
-
setPickupReferenceMode(mode: PickupReferenceMode): ShopServiceData;
|
|
241
|
-
setServiceType(serviceType: ShopServiceType): ShopServiceData;
|
|
242
234
|
updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
|
|
243
235
|
/** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
|
|
244
236
|
setEnableTempOrderPersist(enabled: boolean): void;
|
|
@@ -283,56 +283,7 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
|
|
|
283
283
|
loadedValue.forEach(appendOrReplaceByUid);
|
|
284
284
|
return result;
|
|
285
285
|
}
|
|
286
|
-
|
|
287
|
-
// checkout / realtime snapshots may reorder protocol arrays or append persistence fields.
|
|
288
|
-
// Compare only the Sales Note protocol fields so a matching remote echo can acknowledge dirty state.
|
|
289
|
-
function normalizeBaseSalesNotesForComparison(value, options) {
|
|
290
|
-
if (!Array.isArray(value)) return null;
|
|
291
|
-
const unresolvedOrderTargetUuid = String(options?.unresolvedOrderTargetUuid ?? '').trim();
|
|
292
|
-
return value.map(note => {
|
|
293
|
-
if (!note || typeof note !== 'object' || Array.isArray(note)) {
|
|
294
|
-
return (0, _lodashEs.cloneDeep)(note);
|
|
295
|
-
}
|
|
296
|
-
const noteRecord = note;
|
|
297
|
-
const relations = Array.isArray(noteRecord.note_relations) ? noteRecord.note_relations.map(relation => {
|
|
298
|
-
if (!relation || typeof relation !== 'object' || Array.isArray(relation)) {
|
|
299
|
-
return (0, _lodashEs.cloneDeep)(relation);
|
|
300
|
-
}
|
|
301
|
-
const shouldResolveOrderTarget = relation.is_primary === 0 && relation.relation_type === 'related_to' && relation.target_type === 'order' && String(relation.target_uuid ?? '').trim() === '' && unresolvedOrderTargetUuid.length > 0;
|
|
302
|
-
return {
|
|
303
|
-
uuid: relation.uuid,
|
|
304
|
-
relation_type: relation.relation_type,
|
|
305
|
-
target_type: relation.target_type,
|
|
306
|
-
target_uuid: shouldResolveOrderTarget ? unresolvedOrderTargetUuid : relation.target_uuid,
|
|
307
|
-
is_primary: relation.is_primary
|
|
308
|
-
};
|
|
309
|
-
}).sort((left, right) => String(left?.uuid ?? '').localeCompare(String(right?.uuid ?? ''))) : (0, _lodashEs.cloneDeep)(noteRecord.note_relations);
|
|
310
|
-
return {
|
|
311
|
-
uuid: noteRecord.uuid,
|
|
312
|
-
note_type: noteRecord.note_type,
|
|
313
|
-
content: {
|
|
314
|
-
text: (0, _lodashEs.cloneDeep)(noteRecord.content?.text)
|
|
315
|
-
},
|
|
316
|
-
importance: noteRecord.importance,
|
|
317
|
-
note_relations: relations
|
|
318
|
-
};
|
|
319
|
-
}).sort((left, right) => String(left?.uuid ?? '').localeCompare(String(right?.uuid ?? '')));
|
|
320
|
-
}
|
|
321
|
-
function areBaseSalesNotesEquivalent(currentValue, loadedValue, options) {
|
|
322
|
-
const currentNotes = normalizeBaseSalesNotesForComparison(currentValue, {
|
|
323
|
-
unresolvedOrderTargetUuid: options?.currentOrderTargetUuid
|
|
324
|
-
});
|
|
325
|
-
const loadedNotes = normalizeBaseSalesNotesForComparison(loadedValue);
|
|
326
|
-
return currentNotes !== null && loadedNotes !== null && (0, _lodashEs.isEqual)(currentNotes, loadedNotes);
|
|
327
|
-
}
|
|
328
286
|
function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
|
|
329
|
-
const loadedHasSalesNotes = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'notes');
|
|
330
|
-
const hasDirtyLocalSalesNotes = currentTempOrder?._extend?.salesNotesState?.dirty === true;
|
|
331
|
-
const incomingSalesNotesMatchLocal = loadedHasSalesNotes && areBaseSalesNotesEquivalent(currentTempOrder?.notes, loadedRecord.notes, {
|
|
332
|
-
currentOrderTargetUuid: loadedRecord?.shop_order_number || currentTempOrder?.shop_order_number
|
|
333
|
-
});
|
|
334
|
-
const shouldAwaitAuthoritativeSalesNotes = strategy === 'authoritative-incoming' && hasDirtyLocalSalesNotes && (Number(loadedRecord?.need_sync) === 1 || !incomingSalesNotesMatchLocal);
|
|
335
|
-
const preserveDirtyLocalSalesNotes = hasDirtyLocalSalesNotes && (strategy === 'preserve-local' || shouldAwaitAuthoritativeSalesNotes);
|
|
336
287
|
const normalizedLoadedRecord = normalizeBaseSalesRecordCollections(loadedRecord || {}, {
|
|
337
288
|
ensureUid: false
|
|
338
289
|
});
|
|
@@ -344,12 +295,6 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
|
|
|
344
295
|
});
|
|
345
296
|
const uidRemaps = [];
|
|
346
297
|
const mergedRecord = (0, _lodashEs.mergeWith)(normalizedCurrentTempOrder, normalizedLoadedRecord, (currentValue, loadedValue, key) => {
|
|
347
|
-
if (key === 'notes') {
|
|
348
|
-
if (preserveDirtyLocalSalesNotes && Array.isArray(currentValue)) {
|
|
349
|
-
return (0, _lodashEs.cloneDeep)(currentValue);
|
|
350
|
-
}
|
|
351
|
-
if (Array.isArray(loadedValue)) return (0, _lodashEs.cloneDeep)(loadedValue);
|
|
352
|
-
}
|
|
353
298
|
const collectionKind = getBaseSalesOrderCollectionKind(key);
|
|
354
299
|
if (collectionKind && Array.isArray(loadedValue)) {
|
|
355
300
|
return mergeBaseSalesOrderCollection(collectionKind, Array.isArray(currentValue) ? currentValue : [], loadedValue, strategy, uidRemaps);
|
|
@@ -373,24 +318,7 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
|
|
|
373
318
|
return undefined;
|
|
374
319
|
});
|
|
375
320
|
delete mergedRecord.request_unique_idempotency_token;
|
|
376
|
-
|
|
377
|
-
normalizedMergedRecord._extend = {
|
|
378
|
-
...(normalizedMergedRecord._extend || {}),
|
|
379
|
-
salesNotesState: preserveDirtyLocalSalesNotes ? {
|
|
380
|
-
loaded: true,
|
|
381
|
-
dirty: true
|
|
382
|
-
} : loadedHasSalesNotes ? {
|
|
383
|
-
loaded: true,
|
|
384
|
-
dirty: normalizedLoadedRecord._extend?.salesNotesState?.dirty === true
|
|
385
|
-
} : {
|
|
386
|
-
loaded: false,
|
|
387
|
-
dirty: false
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
if (!loadedHasSalesNotes && !preserveDirtyLocalSalesNotes) {
|
|
391
|
-
delete normalizedMergedRecord.notes;
|
|
392
|
-
}
|
|
393
|
-
return normalizedMergedRecord;
|
|
321
|
+
return normalizeBaseSalesRecordCollections((0, _orderCollectionIdentity.applyOrderCollectionUidRemaps)(mergedRecord, uidRemaps));
|
|
394
322
|
}
|
|
395
323
|
function filterPendingPaymentsFromLoadedSalesDetail(sourceRecord) {
|
|
396
324
|
if (!sourceRecord || typeof sourceRecord !== 'object') return sourceRecord;
|
|
@@ -1498,30 +1426,6 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1498
1426
|
if (!this.store.order) return '';
|
|
1499
1427
|
return this.store.order.getTempOrderNote();
|
|
1500
1428
|
}
|
|
1501
|
-
getSalesNotes() {
|
|
1502
|
-
if (!this.store.order) return [];
|
|
1503
|
-
return this.store.order.getSalesNotes();
|
|
1504
|
-
}
|
|
1505
|
-
createSalesNotesMutationSnapshot() {
|
|
1506
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1507
|
-
return this.store.order.createSalesNotesMutationSnapshot();
|
|
1508
|
-
}
|
|
1509
|
-
restoreSalesNotesMutationSnapshot(snapshot) {
|
|
1510
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1511
|
-
this.store.order.restoreSalesNotesMutationSnapshot(snapshot);
|
|
1512
|
-
}
|
|
1513
|
-
async setSalesNote(input) {
|
|
1514
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1515
|
-
return this.store.order.setSalesNote(input);
|
|
1516
|
-
}
|
|
1517
|
-
async removeSalesNote(uuid) {
|
|
1518
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1519
|
-
await this.store.order.removeSalesNote(uuid);
|
|
1520
|
-
}
|
|
1521
|
-
async clearSalesNotes() {
|
|
1522
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1523
|
-
await this.store.order.clearSalesNotes();
|
|
1524
|
-
}
|
|
1525
1429
|
updateTempOrderNote(note, sync = false) {
|
|
1526
1430
|
try {
|
|
1527
1431
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
@@ -1543,14 +1447,6 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1543
1447
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1544
1448
|
return this.store.order.updateTempOrderDepositAmount(amount);
|
|
1545
1449
|
}
|
|
1546
|
-
setPickupReferenceMode(mode) {
|
|
1547
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1548
|
-
return this.store.order.updateTempOrderPickupReferenceMode(mode);
|
|
1549
|
-
}
|
|
1550
|
-
setServiceType(serviceType) {
|
|
1551
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1552
|
-
return this.store.order.updateTempOrderServiceType(serviceType);
|
|
1553
|
-
}
|
|
1554
1450
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
1555
1451
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1556
1452
|
return this.store.order.updateTempOrderContactsInfo(contactsInfo);
|
|
@@ -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 |
|
|
329
|
+
weekNum: 0 | 2 | 1 | 6 | 4 | 3 | 5;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "lots_of_space" | "filling_up_fast" | "sold_out";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -23,8 +23,7 @@ function resolveCustomerDisplayName(customer) {
|
|
|
23
23
|
|
|
24
24
|
/** 将 ICustomer 格式化为写入 tempOrder 的协议字段。 */
|
|
25
25
|
function formatOrderCustomerPatch(customer) {
|
|
26
|
-
const
|
|
27
|
-
const rawId = c.customer_id ?? c.customerId ?? customer.id;
|
|
26
|
+
const rawId = customer.id;
|
|
28
27
|
const numericId = typeof rawId === 'number' ? rawId : rawId !== undefined && rawId !== null && rawId !== '' ? Number(rawId) : null;
|
|
29
28
|
return {
|
|
30
29
|
customer_id: Number.isFinite(numericId) ? numericId : null,
|
|
@@ -10,11 +10,7 @@ export interface ApiConfig {
|
|
|
10
10
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
11
11
|
transformParams?: (params: any) => any;
|
|
12
12
|
transformResponse?: (response: any) => any;
|
|
13
|
-
options?: Record<string, any
|
|
14
|
-
}
|
|
15
|
-
export interface ApiCallerOptions {
|
|
16
|
-
baseUrl?: string;
|
|
17
|
-
shopDomain?: string;
|
|
13
|
+
options?: Record<string, any>;
|
|
18
14
|
}
|
|
19
15
|
/**
|
|
20
16
|
* 渠道配置接口
|
|
@@ -69,14 +65,12 @@ export declare function getChannelConfig(channel: string): ChannelConfig;
|
|
|
69
65
|
export declare class ApiCaller {
|
|
70
66
|
private request;
|
|
71
67
|
private config;
|
|
72
|
-
private options;
|
|
73
68
|
constructor(request: {
|
|
74
69
|
get: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
75
70
|
post: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
76
71
|
put: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
77
72
|
delete: <T = any>(url: string, options?: any) => Promise<T>;
|
|
78
|
-
}, config: ChannelConfig
|
|
79
|
-
private resolveUrl;
|
|
73
|
+
}, config: ChannelConfig);
|
|
80
74
|
/**
|
|
81
75
|
* 执行 API 调用
|
|
82
76
|
*/
|
|
@@ -90,4 +84,4 @@ export declare function createApiCaller(request: {
|
|
|
90
84
|
post: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
91
85
|
put: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
92
86
|
delete: <T = any>(url: string, options?: any) => Promise<T>;
|
|
93
|
-
}, channel: string
|
|
87
|
+
}, channel: string): ApiCaller;
|