@delicity/client-cart 1.2.13 → 1.2.14

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 (54) hide show
  1. package/classes/Cart.d.ts +129 -0
  2. package/classes/Cart.d.ts.map +1 -0
  3. package/classes/Cart.js +482 -0
  4. package/classes/Cart.js.map +1 -0
  5. package/index.d.ts +4 -0
  6. package/index.d.ts.map +1 -0
  7. package/index.js +20 -0
  8. package/index.js.map +1 -0
  9. package/package.json +1 -1
  10. package/service/CartService.d.ts +14 -0
  11. package/service/CartService.d.ts.map +1 -0
  12. package/service/CartService.js +130 -0
  13. package/service/CartService.js.map +1 -0
  14. package/service/CategoryAvailabilityService.d.ts +23 -0
  15. package/service/CategoryAvailabilityService.d.ts.map +1 -0
  16. package/service/CategoryAvailabilityService.js +103 -0
  17. package/service/CategoryAvailabilityService.js.map +1 -0
  18. package/service/DeliveryService.d.ts +4 -0
  19. package/service/DeliveryService.d.ts.map +1 -0
  20. package/service/DeliveryService.js +30 -0
  21. package/service/DeliveryService.js.map +1 -0
  22. package/service/HelperService.d.ts +2 -0
  23. package/service/HelperService.d.ts.map +1 -0
  24. package/service/HelperService.js +14 -0
  25. package/service/HelperService.js.map +1 -0
  26. package/README.md +0 -1
  27. package/coverage/clover.xml +0 -71
  28. package/coverage/coverage-final.json +0 -3
  29. package/coverage/lcov-report/base.css +0 -224
  30. package/coverage/lcov-report/block-navigation.js +0 -87
  31. package/coverage/lcov-report/classes/Cart.ts.html +0 -340
  32. package/coverage/lcov-report/classes/index.html +0 -116
  33. package/coverage/lcov-report/favicon.png +0 -0
  34. package/coverage/lcov-report/index.html +0 -131
  35. package/coverage/lcov-report/prettify.css +0 -1
  36. package/coverage/lcov-report/prettify.js +0 -2
  37. package/coverage/lcov-report/service/CartService.ts.html +0 -238
  38. package/coverage/lcov-report/service/index.html +0 -116
  39. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  40. package/coverage/lcov-report/sorter.js +0 -196
  41. package/coverage/lcov.info +0 -129
  42. package/jest.config.js +0 -8
  43. package/src/classes/Cart.ts +0 -563
  44. package/src/index.ts +0 -3
  45. package/src/service/CartService.ts +0 -139
  46. package/src/service/CategoryAvailabilityService.ts +0 -121
  47. package/src/service/DeliveryService.ts +0 -17
  48. package/src/service/HelperService.ts +0 -9
  49. package/src/test/availability.test.ts +0 -346
  50. package/src/test/class.test.ts +0 -497
  51. package/src/test/data/CartData.json +0 -244
  52. package/src/test/data/menu.json +0 -5875
  53. package/src/test/data/merchant.json +0 -186
  54. package/tsconfig.json +0 -24
@@ -1,563 +0,0 @@
1
- import {
2
- IAddress,
3
- ICart,
4
- ICartDelivery, ICartDiscount,
5
- ICartItem,
6
- ICartModifierGroup,
7
- ICartPaymentMethod,
8
- ICartPrice,
9
- IClientConfig,
10
- Menu,
11
- MenuItem, MenuModifierGroup,
12
- Merchant,
13
- OrderModesEnum
14
- } from "@delicity/client-types";
15
- import {DateTime} from 'luxon';
16
-
17
- import {v4 as uuidv4} from 'uuid';
18
-
19
- import {
20
- addDiscountCode,
21
- getProductCount,
22
- getProductPrice,
23
- getProductPriceSum,
24
- getTotalModifiersUnitPrice,
25
- isItemAlreadyInCart,
26
- isItemAvailable,
27
- mandatoryModifierCheck, removeDiscountCode,
28
- synchronizeCart
29
- } from "../service/CartService";
30
-
31
- import {getDeliveryDetails} from "../service/DeliveryService";
32
- import {formatPrice} from "../service/HelperService";
33
- // @ts-ignore
34
- import ScheduleManagement from "@delicity/backend-schedule-management";
35
- import {categoryAvailable} from "../service/CategoryAvailabilityService";
36
-
37
- export interface CartClass {
38
- // Setters
39
- setMenu(menu:Menu): Cart
40
- setCart(cart:ICart): Cart
41
- setWhen(when:string|null): Cart
42
- setOrderMode(mode:OrderModesEnum): Cart
43
- setAddress(address:IAddress): Promise<Cart>
44
- setAddressComment(comment: string|null): Cart
45
- setCartComment(comment:string|null): Cart
46
- setAcceptCondition(acceptCondition:boolean):Cart
47
- setPaymentMethods(paymentMethod:ICartPaymentMethod[]):Cart
48
- pushError(field:string, code:string, vars:any): Cart
49
- setErrors(errors:{field:string, code:string, vars:any}[]): Cart
50
-
51
- // Getters
52
- getCart(): ICart
53
- getItems(): ICartItem[]
54
- getTotalItems(): number
55
- getTotalItemPrice(): number
56
- getMerchantId():number
57
- getCartUUID():string|undefined
58
- getOrderMode(): OrderModesEnum
59
- getCartComment():string|null
60
- getDeliveryInfos():ICartDelivery|undefined
61
- getPrices():null|ICartPrice
62
- getWhen():null|string
63
- getAcceptCondition():boolean
64
- getPreparationDurationBetween():number[]|null
65
- getPaymentMethods(): ICartPaymentMethod[]
66
- getErrors(): {field:string, code:string, vars:any}[]
67
- getDiscounts(): ICartDiscount[]
68
- getCoupons(): ICartDiscount[]
69
- canBePayOnsite(): boolean
70
- getRemoteErrors(): any
71
-
72
- // Methods
73
- synchronize(): Promise<Cart>
74
- addToCart(item: MenuItem, modifierGroup:ICartModifierGroup[], quantity:number, comment?:string): Cart
75
- updateCart(cartItem:ICartItem, modifierGroup:ICartModifierGroup[], quantity:number, comment?:string): Cart
76
- removeFromCart(cartItem: ICartItem): Cart
77
- paymentMethodCard(type: 'card_token' | 'payment_method_id', token: string, brand:string, last4:string, expiration: string, amount?:number): Cart
78
- paymentMethodWallet(type: 'apple_pay' | 'google_pay', amount?:number): Cart
79
- paymentMethodOnsite(amount?:number): Cart
80
- validateCart(): Cart
81
- validateMerchantSchedule(): Cart
82
- validateCartIfError(): Cart
83
- resetErrors(): Cart
84
- cartIntegrity(): void
85
- }
86
-
87
- export class Cart implements CartClass{
88
- private cart: ICart
89
- private merchant: Merchant
90
- private menu: Menu
91
- private config: IClientConfig;
92
- private acceptCondition: boolean = false;
93
- private errors:{field:string, code:string, vars: any}[] = []
94
- private listeners:any = {};
95
- private isPriceLoading: boolean = false;
96
- private isDeliveryLoading: boolean = false;
97
- private merchantSchedule: ScheduleManagement | undefined;
98
- private remoteErrors: any;
99
-
100
- constructor(config: IClientConfig, merchant: Merchant, menu: Menu, OrderMode: OrderModesEnum, when: string|null) {
101
- this.merchant = merchant
102
- this.menu = JSON.parse(JSON.stringify(menu))
103
- this.config = config;
104
- this.remoteErrors = {};
105
-
106
- if(this.merchant.schedule){
107
- this.merchantSchedule = new ScheduleManagement(this.merchant.schedule.slots, this.merchant.schedule.closes, this.merchant.schedule.options);
108
- }
109
-
110
- this.cart = {
111
- uuid: uuidv4(),
112
- createdAt: DateTime.now().toISO(),
113
- merchantId: merchant.id,
114
- preparationDurationBetween: null,
115
- items: [],
116
- totalItems: 0,
117
- totalItemPrice: 0,
118
- when: when,
119
- comment: null,
120
- type: OrderMode,
121
- } as ICart;
122
- }
123
-
124
-
125
- on(event:string, callback:any) {
126
- if (!this.listeners[event]) {
127
- this.listeners[event] = [];
128
- }
129
- this.listeners[event].push(callback);
130
- }
131
-
132
- off(event:string, callback:any) {
133
- if (!this.listeners[event]) return;
134
- this.listeners[event] = [];
135
- }
136
-
137
- trigger(event:string, ...args:any) {
138
- if (this.listeners[event]) {
139
- this.listeners[event].forEach((callback: (arg0: any) => void) => {
140
- // @ts-ignore
141
- callback(...args);
142
- });
143
- }
144
- }
145
-
146
-
147
- setMenu(menu:Menu): Cart{
148
- this.menu = JSON.parse(JSON.stringify(menu));
149
- this.cartIntegrity();
150
- this.updateCartProductPrices();
151
- this.trigger('update-cart');
152
- return this;
153
- }
154
- setCart(cart:ICart): Cart{
155
- this.cart = cart;
156
- this.cartIntegrity();
157
- this.trigger('update-cart');
158
- return this;
159
- }
160
-
161
- getPrices():null|ICartPrice{
162
- return this.cart.prices||null;
163
- }
164
- getAcceptCondition():boolean{
165
- return this.acceptCondition;
166
- }
167
- setAcceptCondition(acceptCondition:boolean):Cart{
168
- this.acceptCondition = acceptCondition;
169
- return this;
170
- }
171
- getPreparationDurationBetween():number[]|null{
172
- return this.cart.preparationDurationBetween;
173
- }
174
-
175
- getIsDeliveryLoading():boolean{
176
- return this.isDeliveryLoading
177
- }
178
- getIsPriceLoading():boolean{
179
- return this.isPriceLoading
180
- }
181
- getRemoteErrors(): any{
182
- return this.remoteErrors;
183
- }
184
-
185
- async setAddress(address:IAddress):Promise<Cart>{
186
- if(this.cart.type !== OrderModesEnum.DELIVERY) throw new Error('invalid_order_mode');
187
- this.isDeliveryLoading = true;
188
- const delivery:ICartDelivery = await getDeliveryDetails(this.config, this.merchant.id, address.position);
189
- this.cart.delivery = {
190
- address,
191
- ...delivery
192
- };
193
- this.isDeliveryLoading = false;
194
- this.trigger('update-cart');
195
- return this;
196
- }
197
- getDeliveryInfos():ICartDelivery|undefined{
198
- return this.cart.delivery;
199
- }
200
-
201
- setCartComment(comment:string|null): Cart{
202
- this.cart.comment = comment;
203
- return this;
204
- }
205
- getCartComment():string|null{
206
- return this.cart.comment;
207
- }
208
-
209
- updateCartProductPrices(){
210
-
211
- for(let index in this.cart.items){
212
- const menuItem: MenuItem = this.menu.items.find(m => m.id === this.cart.items[index].item.id) as MenuItem;
213
- if(!menuItem) this.cart.items.splice(parseInt(index), 1);
214
-
215
- const modifierGroups = this.cart.items[index].modifierGroups;
216
- const quantity: number = this.cart.items[index].quantity;
217
-
218
- this.cart.items[index].item = menuItem;
219
- this.cart.items[index].unitPrice = getProductPrice(menuItem, this.cart.type) + getTotalModifiersUnitPrice(modifierGroups)
220
- this.cart.items[index].totalPrice = (getProductPrice(menuItem, this.cart.type) + getTotalModifiersUnitPrice(modifierGroups)) * quantity
221
- }
222
- this.cart.totalItems = getProductCount(this.cart);
223
- this.cart.totalItemPrice = getProductPriceSum(this.cart);
224
- if(this.cart.paymentMethods && this.cart.paymentMethods.length>0){
225
- this.updatePaymentMethodAmount();
226
- }
227
- this.validateCartIfError();
228
- }
229
-
230
- setOrderMode(mode:OrderModesEnum): Cart{
231
- this.cart.type = mode;
232
- if(!this.canBePayOnsite() && this.getPaymentMethods().some(e => e.type === 'cash')){
233
- this.cart.paymentMethods = [];
234
- }
235
- this.updateCartProductPrices();
236
- this.trigger('update-cart');
237
- return this;
238
- }
239
- setWhen(when:string|null): Cart{
240
- this.cart.when = when;
241
- this.trigger('update-cart');
242
- this.cartIntegrity(true);
243
- this.validateCartIfError();
244
- return this;
245
- }
246
- setAddressComment(comment: string|null): Cart {
247
- if(this.cart.delivery?.address){
248
- this.cart.delivery.address.additional_informations = comment;
249
- }
250
- return this;
251
- }
252
- getMerchantId():number{
253
- return this.merchant.id;
254
- }
255
- getCartUUID():string|undefined{
256
- return this.cart.uuid;
257
- }
258
- getOrderMode(): OrderModesEnum {
259
- return this.cart.type;
260
- }
261
- getWhen(): null|string {
262
- return this.cart.when;
263
- }
264
- getPaymentMethods(): ICartPaymentMethod[]{
265
- return this.cart.paymentMethods||[];
266
- }
267
- setPaymentMethods(paymentMethods:ICartPaymentMethod[]):Cart{
268
- this.cart.paymentMethods = paymentMethods;
269
- return this;
270
- }
271
-
272
-
273
- getPaymentMethodTotalAmount():number{
274
- if(!this.cart.paymentMethods) return 0;
275
- return this.cart.paymentMethods.reduce((a, b) => a + b.amount, 0)
276
- }
277
-
278
- paymentMethodCard(type: 'card_token' | 'payment_method_id', token: string, brand:string, last4:string, expiration: string, amount?:number): Cart{
279
- let leftToPay = this.getTotalPrice();
280
- if(!this.cart.paymentMethods) this.cart.paymentMethods = [];
281
-
282
- if(this.cart.paymentMethods){
283
- const sum = this.getPaymentMethodTotalAmount();
284
- if(sum === this.getTotalPrice()) this.cart.paymentMethods = [];
285
- else leftToPay -= sum;
286
- }
287
- if(amount && leftToPay < amount){
288
- this.cart.paymentMethods = [];
289
- }
290
- this.cart.paymentMethods.push({
291
- type: 'card',
292
- amount: amount ? amount : leftToPay,
293
- card: {type, token, brand, last4, expiration}
294
- });
295
- return this;
296
- }
297
-
298
- paymentMethodWallet(type: 'apple_pay' | 'google_pay', amount?:number): Cart{
299
- let leftToPay = this.getTotalPrice();
300
- if(!this.cart.paymentMethods) this.cart.paymentMethods = [];
301
-
302
- if(this.cart.paymentMethods){
303
- const sum = this.getPaymentMethodTotalAmount();
304
- if(sum === this.getTotalPrice()) this.cart.paymentMethods = [];
305
- else leftToPay -= sum;
306
- }
307
- if(amount && leftToPay < amount){
308
- this.cart.paymentMethods = [];
309
- }
310
- this.cart.paymentMethods.push({
311
- type: "wallet",
312
- wallet: {type},
313
- amount: amount ? amount : leftToPay,
314
- });
315
- return this;
316
- }
317
-
318
- paymentMethodOnsite(amount?:number): Cart{
319
- let leftToPay:number = this.getTotalPrice();
320
- if(!this.cart.paymentMethods) this.cart.paymentMethods = [];
321
- if(this.cart.paymentMethods){
322
- const sum = this.getPaymentMethodTotalAmount();
323
- if(sum === this.getTotalPrice()) this.cart.paymentMethods = [];
324
- else leftToPay -= sum;
325
- }
326
- if(amount && leftToPay < amount){
327
- this.cart.paymentMethods = [];
328
- }
329
- this.cart.paymentMethods.push({
330
- type: 'cash',
331
- amount: amount ? amount : leftToPay,
332
- });
333
- return this;
334
- }
335
-
336
-
337
-
338
- addToCart(item: MenuItem, modifierGroups:ICartModifierGroup[], quantity: number, comment?:string, replace?:ICartItem): Cart {
339
- // Check if item have mandatory modifiers
340
- if(!mandatoryModifierCheck(item, modifierGroups, this.menu)){
341
- throw new Error('mandatory_field_missing');
342
- }
343
- // Check if item is available
344
- if(!isItemAvailable(item, this.menu)){
345
- throw new Error('item_not_available');
346
- }
347
-
348
- const index = isItemAlreadyInCart(item, modifierGroups, this.cart, comment);
349
- if(index !== -1 && !replace){
350
- this.cart.items[index].quantity += quantity;
351
- this.cart.items[index].totalPrice = (getProductPrice(item, this.cart.type) + getTotalModifiersUnitPrice(modifierGroups)) * this.cart.items[index].quantity;
352
- }
353
- else{
354
- const cartItem: ICartItem = {
355
- uuid: uuidv4(),
356
- item,
357
- modifierGroups,
358
- quantity,
359
- comment: comment || null,
360
- unitPrice: getProductPrice(item, this.cart.type) + getTotalModifiersUnitPrice(modifierGroups),
361
- totalPrice: (getProductPrice(item, this.cart.type) + getTotalModifiersUnitPrice(modifierGroups)) * quantity
362
- }
363
- if(replace){
364
- const index = this.cart.items.findIndex(i => i.uuid === replace.uuid);
365
- this.cart.items.splice(index, 1, cartItem);
366
- }
367
- else{
368
- this.cart.items.push(cartItem);
369
- }
370
- }
371
-
372
- this.cart.totalItems = getProductCount(this.cart);
373
- this.cart.totalItemPrice = getProductPriceSum(this.cart);
374
- if(this.cart.paymentMethods && this.cart.paymentMethods.length>0){
375
- this.updatePaymentMethodAmount();
376
- }
377
- this.validateCartIfError();
378
- this.cartIntegrity(true);
379
- this.trigger('update-cart');
380
- return this;
381
- }
382
-
383
- removeFromCart(cartItem: ICartItem): Cart {
384
- this.cart.items = this.cart.items.filter((item) => item.uuid !== cartItem.uuid);
385
- this.cart.totalItems = getProductCount(this.cart);
386
- this.cart.totalItemPrice = getProductPriceSum(this.cart);
387
- if(this.cart.paymentMethods){
388
- this.updatePaymentMethodAmount();
389
- }
390
- this.cartIntegrity(true);
391
- this.trigger('update-cart');
392
- return this;
393
- }
394
-
395
- updateCart(cartItem: ICartItem, modifierGroup:ICartModifierGroup[], quantity: number, comment?:string): Cart {
396
- return this.addToCart(cartItem.item, modifierGroup, quantity, comment, cartItem);
397
- }
398
-
399
- getCart(): ICart {
400
- return this.cart;
401
- }
402
- getItems(): ICartItem[] {
403
- return this.cart.items;
404
- }
405
- getTotalItems(): number {
406
- return this.cart.totalItems;
407
- }
408
- getTotalItemPrice(): number {
409
- return this.cart.totalItemPrice;
410
- }
411
- getTotalPrice(): number {
412
- return this.cart.prices?.total || this.cart.totalItemPrice;
413
- }
414
-
415
- canBePayOnsite(): boolean {
416
- return [OrderModesEnum.PICKUP, OrderModesEnum.ON_SITE_COUNTER].includes(this.cart.type) && this.merchant.features.onsitePayment;
417
- }
418
-
419
- async synchronize(): Promise<Cart>{
420
- if(this.cart.type === OrderModesEnum.DELIVERY && !this.cart.delivery){
421
- throw new Error('no_delivery_address')
422
- }
423
- this.isPriceLoading = true;
424
- const request:any = await synchronizeCart(this.config, this.cart);
425
- if(this.cart.delivery && request.delivery){
426
- this.cart.delivery = {
427
- address: this.cart.delivery?.address,
428
- ...request.delivery
429
- };
430
- }
431
- this.cart.preparationDurationBetween = request.preparationDurationBetween;
432
- this.cart.discounts = request.discounts;
433
- this.cart.prices = request.prices;
434
- this.remoteErrors = request.errors;
435
- if(this.cart.paymentMethods && this.cart.paymentMethods.length>0){
436
- this.updatePaymentMethodAmount();
437
- }
438
- this.isPriceLoading = false;
439
- return this;
440
- }
441
-
442
-
443
- validateMerchantSchedule(): Cart{
444
- this.errors = this.errors.filter(e => e.field !== 'schedule')
445
- if(this.merchantSchedule){
446
- const when = this.getWhen() !== null ? DateTime.fromISO(<string>this.getWhen()) : DateTime.now();
447
- if(!this.merchantSchedule.isOpenAt(when)) this.errors.push({field: 'schedule', code: 'merchant_currently_close', vars: {}});
448
- }
449
- return this;
450
- }
451
- validateCart(): Cart{
452
- this.errors = [];
453
- if(this.cart.type === OrderModesEnum.DELIVERY && !this.cart.delivery) this.errors.push({field: 'address', code: 'no_address_defined', vars: {}});
454
- if(this.cart.type === OrderModesEnum.DELIVERY && this.cart.delivery && !this.cart.delivery.available) this.errors.push({field: 'address', code: 'address_not_available', vars: {}});
455
- if(!this.cart.paymentMethods || this.cart.paymentMethods?.length === 0) this.errors.push({field: 'payment_method', code: 'missing_payment_method', vars: {}});
456
- if(!this.acceptCondition) this.errors.push({field: 'conditions', code: 'condition_not_accepted', vars: {}});
457
- if(this.cart.type === OrderModesEnum.DELIVERY && this.merchant.settings.minDeliveryOrderPrice > this.cart.totalItemPrice) this.errors.push({field: 'prices', code: 'minium_delivery_product_price', vars: {min: formatPrice(this.merchant.settings.minDeliveryOrderPrice)}});
458
- this.validateMerchantSchedule();
459
- return this;
460
- }
461
- validateCartIfError(): Cart{
462
- if(this.errors.length>0) this.validateCart();
463
- return this;
464
- }
465
- resetErrors(): Cart{
466
- this.errors = [];
467
- return this;
468
- }
469
- getErrors(): {field:string, code:string, vars:any}[]{
470
- return this.errors;
471
- }
472
- pushError(field:string, code:string, vars:any): Cart{
473
- this.errors.push({field, code, vars});
474
- return this;
475
- }
476
- setErrors(errors:{field:string, code:string, vars:any}[]): Cart{
477
- this.errors = errors;
478
- return this;
479
- }
480
- updatePaymentMethodAmount(){
481
- const totalPrice = this.getTotalPrice();
482
- if(this.cart.paymentMethods?.length === 1){
483
- this.cart.paymentMethods[0].amount = totalPrice;
484
- }
485
- else if(this.cart.paymentMethods?.length === 2 && this.cart.paymentMethods?.some(p => p.type === 'meal-voucher')){
486
- // if voucher, product price = voucher (max voucher limit)
487
- // rest = payment method
488
- }
489
- else{
490
- // If multiple payment methods, split amount
491
- }
492
- }
493
-
494
- async addDiscountCoupon(code:string): Promise<Cart>{
495
- await addDiscountCode(this.config, this.cart, code);
496
- this.trigger('update-cart');
497
- return this;
498
- }
499
- getDiscounts(): ICartDiscount[]{
500
- return this.cart.discounts ?? [];
501
- }
502
- getCoupons(): ICartDiscount[]{
503
- return this.cart.discounts?.filter(d => d.type === 'coupon') ?? [];
504
- }
505
- async removeDiscount(discount: number): Promise<Cart>{
506
- await removeDiscountCode(this.config, this.cart, discount);
507
- this.trigger('update-cart');
508
- return this;
509
- }
510
-
511
-
512
- cartIntegrity(event:boolean=false): void{
513
- // Check if cart products are still available in menu
514
- if(this.cart.items.length>0){
515
- const merchantSchedule = new ScheduleManagement(this.merchant.schedule.slots, this.merchant.schedule.closes, this.merchant.schedule.options);
516
-
517
- const toRemove:ICartItem[] = [];
518
- for(const i in this.cart.items){
519
- // Remove from cart if item not in menu anymore
520
- const menuItem = this.menu.items.find(m => m.id === this.cart.items[i].item.id);
521
- const category = this.menu.categories.find(c => c.itemIds?.includes(this.cart.items[i].item.uid))
522
- if(!menuItem){
523
- toRemove.push(this.cart.items[i]);
524
- continue;
525
- }
526
- // Remove from cart if item not available
527
- if(menuItem.unavailable){
528
- toRemove.push(this.cart.items[i]);
529
- continue;
530
- }
531
- // Check if product is available
532
- if(category?.availability){
533
- const atDate = this.cart.when ? DateTime.fromISO(this.cart.when) : DateTime.now();
534
- // @ts-ignore
535
- const categoryAvailability = categoryAvailable(category.availability, atDate, merchantSchedule);
536
- if(!categoryAvailability.isAvailable){
537
- toRemove.push(this.cart.items[i]);
538
- if(event){
539
- // Used when cart update check.
540
- this.trigger('product-removed:not-available-at-date', this.cart.items[i])
541
- }
542
- continue;
543
- }
544
- }
545
- // Update from menu
546
- this.cart.items[i].item = menuItem;
547
- }
548
-
549
- // Remove item from cart when necessary
550
- toRemove.forEach((cartItem) => {
551
- this.cart.items = this.cart.items.filter((item) => item.uuid !== cartItem.uuid);
552
- });
553
-
554
- // Update cart
555
- this.cart.totalItems = getProductCount(this.cart);
556
- this.cart.totalItemPrice = getProductPriceSum(this.cart);
557
- if(this.cart.paymentMethods && this.cart.paymentMethods.length>0){
558
- this.updatePaymentMethodAmount();
559
- }
560
- }
561
- }
562
-
563
- }
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './classes/Cart'
2
- export * from './service/CartService'
3
- export * from './service/CategoryAvailabilityService'
@@ -1,139 +0,0 @@
1
- import {
2
- ICart,
3
- ICartItem,
4
- ICartModifierGroup,
5
- IClientConfig,
6
- Menu,
7
- MenuItem,
8
- OrderModesEnum
9
- } from "@delicity/client-types";
10
- import axios from "axios";
11
-
12
- export function getProductPriceSum(cart:ICart): number{
13
- return cart.items.reduce((acc, item) => acc + item.totalPrice, 0);
14
- }
15
- export function getProductCount(cart:ICart): number{
16
- return cart.items.reduce((acc, item) => acc + item.quantity, 0);
17
- }
18
-
19
- export function getItemModifierValue(item:ICartItem): string {
20
- return getItemModifierValueArray(item).join(', ');
21
- }
22
- export function getItemModifierValueArray(item:ICartItem): string[] {
23
- return item.modifierGroups
24
- .filter(mg => mg.modifiers.length > 0)
25
- .map(mg => {
26
- return mg.item.name + ': ' + mg.modifiers.map(m => m.item.name).join(', ');
27
- })
28
- }
29
-
30
- export function mandatoryModifierCheck(item: MenuItem, cartModifier: ICartModifierGroup[], menu: Menu): boolean{
31
- if(!item.children) return true;
32
-
33
- // get all mandatory modifiers in this item.
34
- const modifierGroups = menu.modifierGroups.filter((m:any) => item.children?.includes(m.uid) && m.min>0 && m.min);
35
-
36
- for(let modifier of modifierGroups){
37
- const m = cartModifier.find((m:any) => m.item.uid === modifier.uid);
38
- if(!m) return false;
39
- if(modifier.min === null) continue;
40
-
41
- const selectedOption = m.modifiers.reduce((acc:any, m:any) => acc + m.quantity, 0);
42
- if(selectedOption < modifier.min) return false;
43
- }
44
-
45
- return true;
46
- }
47
-
48
- export function isItemAvailable(item: MenuItem, menu: Menu){
49
- const menuItem = menu.items.find((i:any) => i.uid === item.uid);
50
- if(!menuItem) return false;
51
- return !menuItem.unavailable;
52
- }
53
-
54
-
55
- export function getProductPrice(item:MenuItem, mode:OrderModesEnum): number{
56
- if(!item.price){
57
- throw new Error('price_not_set');
58
- }
59
- if(typeof item.price === 'number'){
60
- return item.price;
61
- }
62
- if(mode === 'delivery'){
63
- return item.price.delivery;
64
- }
65
- else if(mode === 'pickup'){
66
- return item.price.pickup;
67
- }
68
- else if(mode === 'on_site_counter'){
69
- return item.price.onsite;
70
- }
71
- return item.price.delivery;
72
- }
73
-
74
- export function getTotalModifiersUnitPrice(modifierGroup:ICartModifierGroup[]): number{
75
- return modifierGroup.reduce((acc, mg) => acc + mg.modifiers.reduce((bcc, m) => bcc + m.price, 0), 0);
76
- }
77
-
78
- export function isItemAlreadyInCart(item:MenuItem, modifierGroups:ICartModifierGroup[], cart:ICart, comment?:string): number{
79
- // Check if item is already in cart
80
- const sameCartProducts = cart.items
81
- .filter((i) => i.item.uid === item.uid)
82
- .filter((i) => i.comment === (comment||null))
83
- .filter((c) => {
84
- if(c.modifierGroups.length !== modifierGroups.length) return false;
85
- const newItemModifierGroupsKey = modifierGroups.flatMap((m) => {
86
- return m.modifiers.map((o) => {return {id: o.item.id, quantity: o.quantity}});
87
- }).sort((a, b) => a.id - b.id).map((m) => m.id + ':' + m.quantity).join('|');
88
- const CartItemModifierGroupsKey = c.modifierGroups.flatMap((m) => {
89
- return m.modifiers.map((o) => {return {id: o.item.id, quantity: o.quantity}});
90
- }).sort((a, b) => a.id - b.id).map((m) => m.id + ':' + m.quantity).join('|');
91
- return newItemModifierGroupsKey === CartItemModifierGroupsKey;
92
- })
93
-
94
- // If not existing in cart, return -1
95
- if(sameCartProducts.length === 0) return -1;
96
-
97
- return cart.items.findIndex((c) => c.uuid === sameCartProducts[0].uuid);
98
- }
99
-
100
-
101
- export function synchronizeCart(config:IClientConfig, cart: ICart){
102
- return new Promise(((resolve, reject) => {
103
- config.axiosClient.post(config.apiUrl+'/v1/client/cart/'+cart.uuid, cart)
104
- .then((response) => {
105
- resolve(response.data);
106
- })
107
- .catch((error) => {
108
- reject(error);
109
- })
110
- }));
111
- }
112
-
113
-
114
- export function addDiscountCode(config:IClientConfig, cart: ICart, code: string){
115
- return new Promise(((resolve, reject) => {
116
- config.axiosClient.put(config.apiUrl+'/v1/client/cart/'+cart.uuid+"/coupon", {code})
117
- .then((response) => {
118
- resolve(response.data);
119
- })
120
- .catch((error) => {
121
- reject(error);
122
- })
123
- }));
124
- }
125
-
126
-
127
- export function removeDiscountCode(config:IClientConfig, cart: ICart, discountId: number){
128
- return new Promise(((resolve, reject) => {
129
- config.axiosClient.delete(config.apiUrl+'/v1/client/cart/'+cart.uuid+'/coupon/'+discountId)
130
- .then((response) => {
131
- resolve(response.data);
132
- })
133
- .catch((error) => {
134
- reject(error);
135
- })
136
- }));
137
- }
138
-
139
-