@etsoo/appscript 1.3.90 → 1.3.92
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/__tests__/app/CoreApp.ts +1 -1
- package/lib/cjs/app/CoreApp.d.ts +1 -1
- package/lib/cjs/app/CoreApp.js +25 -15
- package/lib/cjs/app/IApp.d.ts +1 -1
- package/lib/cjs/business/ShoppingCart.d.ts +285 -0
- package/lib/cjs/business/ShoppingCart.js +306 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/mjs/app/CoreApp.d.ts +1 -1
- package/lib/mjs/app/CoreApp.js +25 -15
- package/lib/mjs/app/IApp.d.ts +1 -1
- package/lib/mjs/business/ShoppingCart.d.ts +285 -0
- package/lib/mjs/business/ShoppingCart.js +302 -0
- package/lib/mjs/index.d.ts +1 -0
- package/lib/mjs/index.js +1 -0
- package/package.json +2 -2
- package/src/app/CoreApp.ts +28 -22
- package/src/app/IApp.ts +6 -4
- package/src/business/ShoppingCart.ts +524 -0
- package/src/index.ts +1 -0
package/src/app/CoreApp.ts
CHANGED
|
@@ -1237,23 +1237,35 @@ export abstract class CoreApp<
|
|
|
1237
1237
|
getEnumList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(
|
|
1238
1238
|
em: E,
|
|
1239
1239
|
prefix: string,
|
|
1240
|
-
filter?:
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1240
|
+
filter?:
|
|
1241
|
+
| ((
|
|
1242
|
+
id: E[keyof E],
|
|
1243
|
+
key: keyof E & string
|
|
1244
|
+
) => E[keyof E] | undefined)
|
|
1245
|
+
| E[keyof E][]
|
|
1244
1246
|
): ListType[] {
|
|
1245
1247
|
const list: ListType[] = [];
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
id
|
|
1248
|
+
|
|
1249
|
+
if (Array.isArray(filter)) {
|
|
1250
|
+
filter.forEach((id) => {
|
|
1251
|
+
if (typeof id !== 'number') return;
|
|
1252
|
+
const key = DataTypes.getEnumKey(em, id);
|
|
1253
|
+
var label = this.get<string>(prefix + key) ?? key;
|
|
1254
|
+
list.push({ id, label });
|
|
1255
|
+
});
|
|
1256
|
+
} else {
|
|
1257
|
+
const keys = DataTypes.getEnumKeys(em);
|
|
1258
|
+
for (const key of keys) {
|
|
1259
|
+
let id = em[key as keyof E];
|
|
1260
|
+
if (filter) {
|
|
1261
|
+
const fid = filter(id, key);
|
|
1262
|
+
if (fid == null) continue;
|
|
1263
|
+
id = fid;
|
|
1264
|
+
}
|
|
1265
|
+
if (typeof id !== 'number') continue;
|
|
1266
|
+
var label = this.get<string>(prefix + key) ?? key;
|
|
1267
|
+
list.push({ id, label });
|
|
1253
1268
|
}
|
|
1254
|
-
if (typeof id !== 'number') continue;
|
|
1255
|
-
var label = this.get<string>(prefix + key) ?? key;
|
|
1256
|
-
list.push({ id, label });
|
|
1257
1269
|
}
|
|
1258
1270
|
return list;
|
|
1259
1271
|
}
|
|
@@ -1322,14 +1334,8 @@ export abstract class CoreApp<
|
|
|
1322
1334
|
* @param ids Limited ids
|
|
1323
1335
|
* @returns list
|
|
1324
1336
|
*/
|
|
1325
|
-
getStatusList(ids
|
|
1326
|
-
return this.getEnumList(
|
|
1327
|
-
EntityStatus,
|
|
1328
|
-
'status',
|
|
1329
|
-
ids.length > 0
|
|
1330
|
-
? (id, _key) => (ids.includes(id) ? id : undefined)
|
|
1331
|
-
: undefined
|
|
1332
|
-
);
|
|
1337
|
+
getStatusList(ids?: EntityStatus[]) {
|
|
1338
|
+
return this.getEnumList(EntityStatus, 'status', ids);
|
|
1333
1339
|
}
|
|
1334
1340
|
|
|
1335
1341
|
/**
|
package/src/app/IApp.ts
CHANGED
|
@@ -434,10 +434,12 @@ export interface IApp {
|
|
|
434
434
|
getEnumStrList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(
|
|
435
435
|
em: E,
|
|
436
436
|
prefix: string,
|
|
437
|
-
filter?:
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
437
|
+
filter?:
|
|
438
|
+
| ((
|
|
439
|
+
id: E[keyof E],
|
|
440
|
+
key: keyof E & string
|
|
441
|
+
) => E[keyof E] | undefined)
|
|
442
|
+
| E[keyof E][]
|
|
441
443
|
): ListType1[];
|
|
442
444
|
|
|
443
445
|
/**
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import { DataTypes, IStorage, NumberUtils, WindowStorage } from '@etsoo/shared';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shopping cart owner
|
|
5
|
+
* 购物篮所有人
|
|
6
|
+
*/
|
|
7
|
+
export type ShoppingCartOwner = DataTypes.IdNameItem & {
|
|
8
|
+
isSupplier?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Shopping cart data
|
|
13
|
+
* 购物篮数据
|
|
14
|
+
*/
|
|
15
|
+
export type ShoppingCartData<T extends ShoppingCartItem> = {
|
|
16
|
+
currency: string;
|
|
17
|
+
owner: ShoppingCartOwner;
|
|
18
|
+
items: T[];
|
|
19
|
+
promotions: ShoppingPromotion[];
|
|
20
|
+
formData?: any;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Shopping promotion
|
|
25
|
+
* 购物促销
|
|
26
|
+
*/
|
|
27
|
+
export type ShoppingPromotion = {
|
|
28
|
+
/**
|
|
29
|
+
* Promotion id
|
|
30
|
+
* 促销编号
|
|
31
|
+
*/
|
|
32
|
+
id: number;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Promotion title
|
|
36
|
+
* 促销标题
|
|
37
|
+
*/
|
|
38
|
+
title: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Discount amount
|
|
42
|
+
* 折扣金额
|
|
43
|
+
*/
|
|
44
|
+
amount: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Shopping cart base item
|
|
49
|
+
* 购物篮基础项目
|
|
50
|
+
*/
|
|
51
|
+
export type ShoppingCartItemBase = {
|
|
52
|
+
/**
|
|
53
|
+
* Product id
|
|
54
|
+
* 产品编号
|
|
55
|
+
*/
|
|
56
|
+
id: DataTypes.IdType;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Product title, default is name
|
|
60
|
+
* 产品标题,默认为name
|
|
61
|
+
*/
|
|
62
|
+
title?: string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Sale price
|
|
66
|
+
* 销售价格
|
|
67
|
+
*/
|
|
68
|
+
price: number;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Qty
|
|
72
|
+
* 数量
|
|
73
|
+
*/
|
|
74
|
+
qty: number;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Product level promotions
|
|
78
|
+
* 产品层次促销
|
|
79
|
+
*/
|
|
80
|
+
promotions: ShoppingPromotion[];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Shopping cart item
|
|
85
|
+
* 购物篮项目
|
|
86
|
+
*/
|
|
87
|
+
export type ShoppingCartItem = ShoppingCartItemBase & {
|
|
88
|
+
/**
|
|
89
|
+
* Product name
|
|
90
|
+
* 产品名称
|
|
91
|
+
*/
|
|
92
|
+
name: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Current price for cache
|
|
96
|
+
* 当前缓存价格
|
|
97
|
+
*/
|
|
98
|
+
currentPrice?: number;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Subtotal
|
|
102
|
+
* 小计
|
|
103
|
+
*/
|
|
104
|
+
subtotal: number;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Total discount amount
|
|
108
|
+
* 总折扣金额
|
|
109
|
+
*/
|
|
110
|
+
discount: number;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Shopping cart change reason
|
|
115
|
+
* 购物篮改变原因
|
|
116
|
+
*/
|
|
117
|
+
export type ShoppingCartChangeReason =
|
|
118
|
+
| 'add'
|
|
119
|
+
| 'clear'
|
|
120
|
+
| 'remove'
|
|
121
|
+
| 'title'
|
|
122
|
+
| 'update';
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Shopping cart
|
|
126
|
+
* 购物篮
|
|
127
|
+
*/
|
|
128
|
+
export class ShoppingCart<T extends ShoppingCartItem> {
|
|
129
|
+
/**
|
|
130
|
+
* Create identifier key
|
|
131
|
+
* 创建识别键
|
|
132
|
+
* @param currency Currency
|
|
133
|
+
* @returns Result
|
|
134
|
+
*/
|
|
135
|
+
static createKey(currency: string) {
|
|
136
|
+
return `ETSOO-CART-${currency}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Clear shopping cart
|
|
141
|
+
* 清除购物篮
|
|
142
|
+
* @param identifier Identifier
|
|
143
|
+
* @param storage Storage
|
|
144
|
+
*/
|
|
145
|
+
static clear(identifier: string, storage: IStorage) {
|
|
146
|
+
try {
|
|
147
|
+
storage.setData(identifier, null);
|
|
148
|
+
storage.setPersistedData(identifier, null);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.log('ShoppingCart clear', error);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Clear shopping cart
|
|
156
|
+
* 清除购物篮
|
|
157
|
+
* @param currency Currency
|
|
158
|
+
* @param storage Storage
|
|
159
|
+
*/
|
|
160
|
+
static clearWith(
|
|
161
|
+
currency: string,
|
|
162
|
+
storage: IStorage = new WindowStorage()
|
|
163
|
+
) {
|
|
164
|
+
const identifier = this.createKey(currency);
|
|
165
|
+
this.clear(identifier, storage);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Owner data
|
|
170
|
+
* 所有者信息
|
|
171
|
+
*/
|
|
172
|
+
owner?: ShoppingCartOwner;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* ISO currency id
|
|
176
|
+
* 标准货币编号
|
|
177
|
+
*/
|
|
178
|
+
readonly currency: string;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Items
|
|
182
|
+
* 项目
|
|
183
|
+
*/
|
|
184
|
+
readonly items: T[];
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Order level promotions
|
|
188
|
+
* 订单层面促销
|
|
189
|
+
*/
|
|
190
|
+
readonly promotions: ShoppingPromotion[];
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Related form data
|
|
194
|
+
* 关联的表单数据
|
|
195
|
+
*/
|
|
196
|
+
formData: any;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Currency symbol
|
|
200
|
+
* 币种符号
|
|
201
|
+
*/
|
|
202
|
+
readonly symbol: string | undefined;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Cart identifier
|
|
206
|
+
* 购物篮标识
|
|
207
|
+
*/
|
|
208
|
+
private readonly identifier: string;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Lines count
|
|
212
|
+
* 项目数量
|
|
213
|
+
*/
|
|
214
|
+
get lines() {
|
|
215
|
+
return this.items.length;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Total qty
|
|
220
|
+
* 总数量
|
|
221
|
+
*/
|
|
222
|
+
get totalQty() {
|
|
223
|
+
return this.items.map((item) => item.qty).sum();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Total amount
|
|
228
|
+
* 总金额
|
|
229
|
+
*/
|
|
230
|
+
get totalAmount() {
|
|
231
|
+
const subtotal = this.items
|
|
232
|
+
.map((item) => item.subtotal - item.discount)
|
|
233
|
+
.sum();
|
|
234
|
+
|
|
235
|
+
const discount = this.promotions.sum('amount');
|
|
236
|
+
|
|
237
|
+
return subtotal - discount;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Total amount string
|
|
242
|
+
* 总金额字符串
|
|
243
|
+
*/
|
|
244
|
+
get totalAmountStr() {
|
|
245
|
+
return this.formatAmount(this.totalAmount);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Cached prices
|
|
250
|
+
* 缓存的价格
|
|
251
|
+
*/
|
|
252
|
+
private readonly prices: Record<T['id'], number> = {} as any;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Onchange callback
|
|
256
|
+
* 改变时回调
|
|
257
|
+
*/
|
|
258
|
+
onChange?: (reason: ShoppingCartChangeReason, changedItems: T[]) => void;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Constructor
|
|
262
|
+
* 构造函数
|
|
263
|
+
* @param currency Currency ISO code
|
|
264
|
+
* @param storage Data storage
|
|
265
|
+
*/
|
|
266
|
+
constructor(currency: string, storage?: IStorage);
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Constructor
|
|
270
|
+
* 构造函数
|
|
271
|
+
* @param state Initialization state
|
|
272
|
+
* @param storage Data storage
|
|
273
|
+
*/
|
|
274
|
+
constructor(state: ShoppingCartData<T>, storage?: IStorage);
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Constructor
|
|
278
|
+
* 构造函数
|
|
279
|
+
* @param currency Currency ISO code
|
|
280
|
+
* @param storage Data storage
|
|
281
|
+
* @param state Initialization state
|
|
282
|
+
*/
|
|
283
|
+
constructor(
|
|
284
|
+
currencyOrState: string | ShoppingCartData<T>,
|
|
285
|
+
private readonly storage: IStorage = new WindowStorage()
|
|
286
|
+
) {
|
|
287
|
+
const isCurrency = typeof currencyOrState === 'string';
|
|
288
|
+
this.currency = isCurrency ? currencyOrState : currencyOrState.currency;
|
|
289
|
+
|
|
290
|
+
const key = ShoppingCart.createKey(this.currency);
|
|
291
|
+
this.identifier = key;
|
|
292
|
+
this.symbol = NumberUtils.getCurrencySymbol(this.currency);
|
|
293
|
+
|
|
294
|
+
let state: ShoppingCartData<T> | undefined;
|
|
295
|
+
if (isCurrency) {
|
|
296
|
+
try {
|
|
297
|
+
state =
|
|
298
|
+
storage.getPersistedObject<ShoppingCartData<T>>(key) ??
|
|
299
|
+
storage.getObject<ShoppingCartData<T>>(key);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.log('ShoppingCart constructor', error);
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
state = currencyOrState;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const { owner, items = [], promotions = [], formData } = state ?? {};
|
|
308
|
+
|
|
309
|
+
this.owner = owner;
|
|
310
|
+
this.items = items;
|
|
311
|
+
this.promotions = promotions;
|
|
312
|
+
this.formData = formData;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private doChange(reason: ShoppingCartChangeReason, changedItems: T[]) {
|
|
316
|
+
if (this.onChange) this.onChange(reason, changedItems);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Add item
|
|
321
|
+
* 添加项目
|
|
322
|
+
* @param item New item
|
|
323
|
+
*/
|
|
324
|
+
addItem(item: T) {
|
|
325
|
+
this.addItems([item]);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Add items
|
|
330
|
+
* @param items New items
|
|
331
|
+
*/
|
|
332
|
+
addItems(items: T[]) {
|
|
333
|
+
this.items.push(...items);
|
|
334
|
+
this.doChange('add', items);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Cache price
|
|
339
|
+
* @param id Item id
|
|
340
|
+
* @param price Price
|
|
341
|
+
*/
|
|
342
|
+
cachePrice(id: T['id'], price: number) {
|
|
343
|
+
this.prices[id] = price;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Clear storage
|
|
348
|
+
* @param keepOwner Keep owner data
|
|
349
|
+
*/
|
|
350
|
+
clear(keepOwner?: boolean) {
|
|
351
|
+
this.items.length = 0;
|
|
352
|
+
this.promotions.length = 0;
|
|
353
|
+
|
|
354
|
+
if (keepOwner) {
|
|
355
|
+
this.save();
|
|
356
|
+
} else {
|
|
357
|
+
ShoppingCart.clear(this.identifier, this.storage);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this.doChange('clear', []);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Format amount
|
|
365
|
+
* @param amount Amount
|
|
366
|
+
* @returns Result
|
|
367
|
+
*/
|
|
368
|
+
formatAmount(amount: number) {
|
|
369
|
+
return NumberUtils.formatMoney(amount, this.currency);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get item
|
|
374
|
+
* @param id Item id
|
|
375
|
+
* @returns Result
|
|
376
|
+
*/
|
|
377
|
+
getItem(id: T['id']) {
|
|
378
|
+
return this.items.find((item) => item.id === id);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Reset
|
|
383
|
+
* @param item Shopping cart item
|
|
384
|
+
*/
|
|
385
|
+
reset(item: ShoppingCartItem) {
|
|
386
|
+
item.discount = 0;
|
|
387
|
+
item.currentPrice = undefined;
|
|
388
|
+
item.promotions = [];
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Save cart data
|
|
393
|
+
* @param persisted For persisted storage
|
|
394
|
+
*/
|
|
395
|
+
save(persisted: boolean = true) {
|
|
396
|
+
if (this.owner == null) return;
|
|
397
|
+
|
|
398
|
+
const { currency, owner, items, promotions, formData } = this;
|
|
399
|
+
const data: ShoppingCartData<T> = {
|
|
400
|
+
currency,
|
|
401
|
+
owner,
|
|
402
|
+
items,
|
|
403
|
+
promotions,
|
|
404
|
+
formData
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
if (persisted) {
|
|
409
|
+
this.storage.setPersistedData(this.identifier, data);
|
|
410
|
+
} else {
|
|
411
|
+
this.storage.setData(this.identifier, data);
|
|
412
|
+
}
|
|
413
|
+
} catch (error) {
|
|
414
|
+
console.log('ShoppingCart save', error);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return data;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Trigger update
|
|
422
|
+
* 触发更新
|
|
423
|
+
*/
|
|
424
|
+
update() {
|
|
425
|
+
this.doChange('update', []);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Update discount
|
|
430
|
+
* @param item Shopping cart item
|
|
431
|
+
*/
|
|
432
|
+
updateDiscount(item: ShoppingCartItem) {
|
|
433
|
+
item.discount = item.promotions.sum('amount');
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Update item
|
|
438
|
+
* 更新项目
|
|
439
|
+
* @param id Product id
|
|
440
|
+
* @param qty Qty
|
|
441
|
+
* @param itemCreator New item creator
|
|
442
|
+
* @returns Updated or not
|
|
443
|
+
*/
|
|
444
|
+
updateItem(
|
|
445
|
+
id: T['id'],
|
|
446
|
+
qty: number | undefined,
|
|
447
|
+
itemCreator?: () => Omit<
|
|
448
|
+
T,
|
|
449
|
+
'id' | 'price' | 'qty' | 'subtotal' | 'discount' | 'promotions'
|
|
450
|
+
>
|
|
451
|
+
) {
|
|
452
|
+
const index = this.items.findIndex((item) => item.id === id);
|
|
453
|
+
if (qty == null) {
|
|
454
|
+
// Remove the item
|
|
455
|
+
if (index !== -1) {
|
|
456
|
+
const removedItems = this.items.splice(index, 1);
|
|
457
|
+
this.doChange('remove', removedItems);
|
|
458
|
+
}
|
|
459
|
+
} else if (index === -1) {
|
|
460
|
+
// New
|
|
461
|
+
if (itemCreator) {
|
|
462
|
+
const price = this.prices[id];
|
|
463
|
+
const newItem = {
|
|
464
|
+
...itemCreator(),
|
|
465
|
+
id,
|
|
466
|
+
price,
|
|
467
|
+
qty,
|
|
468
|
+
subtotal: price * qty,
|
|
469
|
+
discount: 0
|
|
470
|
+
} as T;
|
|
471
|
+
this.addItem(newItem);
|
|
472
|
+
}
|
|
473
|
+
return false;
|
|
474
|
+
} else {
|
|
475
|
+
// Update
|
|
476
|
+
const item = this.items[index];
|
|
477
|
+
const price = item.price;
|
|
478
|
+
const newItem = {
|
|
479
|
+
...item,
|
|
480
|
+
qty,
|
|
481
|
+
subtotal: price * qty,
|
|
482
|
+
discount: 0
|
|
483
|
+
};
|
|
484
|
+
this.items.splice(index, 1, newItem);
|
|
485
|
+
this.doChange('update', [item, newItem]);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Update price
|
|
493
|
+
* @param id Item id
|
|
494
|
+
* @param price New price
|
|
495
|
+
*/
|
|
496
|
+
updatePrice(id: T['id'], price: number) {
|
|
497
|
+
this.cachePrice(id, price);
|
|
498
|
+
|
|
499
|
+
const index = this.items.findIndex((item) => item.id === id);
|
|
500
|
+
if (index !== -1) {
|
|
501
|
+
const item = this.items[index];
|
|
502
|
+
const qty = item.qty;
|
|
503
|
+
const newItem = { ...item, price, subtotal: price * qty };
|
|
504
|
+
this.items.splice(index, 1, newItem);
|
|
505
|
+
this.doChange('update', [item, newItem]);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Update title
|
|
511
|
+
* @param id Item id
|
|
512
|
+
* @param title New title
|
|
513
|
+
*/
|
|
514
|
+
updateTitle(id: T['id'], title: string) {
|
|
515
|
+
const index = this.items.findIndex((item) => item.id === id);
|
|
516
|
+
if (index !== -1) {
|
|
517
|
+
const item = this.items[index];
|
|
518
|
+
const newItem: T = { ...item, title };
|
|
519
|
+
if (newItem.name === newItem.title) newItem.title = undefined;
|
|
520
|
+
this.items.splice(index, 1, newItem);
|
|
521
|
+
this.doChange('title', [item, newItem]);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -29,6 +29,7 @@ export * from './business/DataPrivacy';
|
|
|
29
29
|
export * from './business/EntityStatus';
|
|
30
30
|
export * from './business/ProductUnit';
|
|
31
31
|
export * from './business/RepeatOption';
|
|
32
|
+
export * from './business/ShoppingCart';
|
|
32
33
|
|
|
33
34
|
// def
|
|
34
35
|
export * from './def/ListItem';
|