washday-sdk 0.0.160 → 0.0.162
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/utils/orders/calculateTotalTaxesIncluded.js +33 -21
- package/dist/utils/orders/calculateTotalTaxesOverPrice.js +24 -34
- package/dist/utils/orders/helpers.js +17 -27
- package/package.json +1 -1
- package/src/utils/orders/calculateOrderTotal.test.js +541 -8
- package/src/utils/orders/calculateTotalTaxesIncluded.ts +44 -28
- package/src/utils/orders/calculateTotalTaxesOverPrice.ts +29 -36
- package/src/utils/orders/helpers.ts +128 -144
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// myModule.test.js
|
|
2
2
|
import { calculateOrderTotal } from "./index";
|
|
3
3
|
|
|
4
|
-
describe("
|
|
5
|
-
|
|
4
|
+
describe("Calculate Order Total tests", () => {
|
|
5
|
+
let ORDER_DEMO = {
|
|
6
6
|
orderDto: {
|
|
7
7
|
deliveryDateFormatted: "lunes 08 abr.",
|
|
8
8
|
pickupInfo: null,
|
|
@@ -347,9 +347,394 @@ describe("sum function", () => {
|
|
|
347
347
|
};
|
|
348
348
|
beforeEach(() => {
|
|
349
349
|
// Run this setup function before each test case
|
|
350
|
+
ORDER_DEMO = {
|
|
351
|
+
orderDto: {
|
|
352
|
+
deliveryDateFormatted: "lunes 08 abr.",
|
|
353
|
+
pickupInfo: null,
|
|
354
|
+
deliveryInfo: {
|
|
355
|
+
date: "2024-04-09T05:00:00.000Z",
|
|
356
|
+
fromTime: "2024-04-08T21:00:00.000Z",
|
|
357
|
+
},
|
|
358
|
+
express: false,
|
|
359
|
+
products: [
|
|
360
|
+
{
|
|
361
|
+
extraAmount: 0,
|
|
362
|
+
type: "weight",
|
|
363
|
+
showInApp: true,
|
|
364
|
+
order: 0,
|
|
365
|
+
invoice_description: "",
|
|
366
|
+
invoice_product_key: "",
|
|
367
|
+
invoice_product_unit_key: "",
|
|
368
|
+
invoice_product_unit_name: "",
|
|
369
|
+
productType: "storeProduct",
|
|
370
|
+
_id: "62d186387ec9330016319594",
|
|
371
|
+
name: "Lavado por kilo",
|
|
372
|
+
price: 17,
|
|
373
|
+
expressPrice: 20,
|
|
374
|
+
pieces: "1",
|
|
375
|
+
sku: "lavxkilo",
|
|
376
|
+
overlayText: "Lavado por kilo",
|
|
377
|
+
image: "6184782c3927a40018e36dea",
|
|
378
|
+
taxExemptOne: false,
|
|
379
|
+
taxExemptTwo: false,
|
|
380
|
+
taxExemptThree: false,
|
|
381
|
+
isActive: true,
|
|
382
|
+
store: "629c267812db5b001692adae",
|
|
383
|
+
owner: "629c267812db5b001692ada4",
|
|
384
|
+
productSupplies: [
|
|
385
|
+
{
|
|
386
|
+
usageAmount: 25,
|
|
387
|
+
_id: "62d6151fac2fc200166d0304",
|
|
388
|
+
supplyId: "62d35942c642440016cfcda8",
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
__v: 1,
|
|
392
|
+
discountAmount: 0,
|
|
393
|
+
quantity: 3.7,
|
|
394
|
+
productId: "62d186387ec9330016319594",
|
|
395
|
+
qty: 3.7,
|
|
396
|
+
},
|
|
397
|
+
],
|
|
398
|
+
taxesType: "included",
|
|
399
|
+
total: 62.9,
|
|
400
|
+
customer: "66147eecae83bb001540dd96",
|
|
401
|
+
store: "629c267812db5b001692adae",
|
|
402
|
+
paymentMethod: "delivery",
|
|
403
|
+
notifyBy: "none",
|
|
404
|
+
pickup: false,
|
|
405
|
+
delivery: false,
|
|
406
|
+
phone: "",
|
|
407
|
+
email: "",
|
|
408
|
+
address: "",
|
|
409
|
+
notes: "",
|
|
410
|
+
privateNotes: "",
|
|
411
|
+
creditApplied: 0,
|
|
412
|
+
amountPaid: 0,
|
|
413
|
+
customerInfo: {
|
|
414
|
+
password: "",
|
|
415
|
+
google: false,
|
|
416
|
+
facebook: false,
|
|
417
|
+
apple: false,
|
|
418
|
+
useStoreApp: false,
|
|
419
|
+
discount: 0,
|
|
420
|
+
credit: 0,
|
|
421
|
+
isActive: true,
|
|
422
|
+
createdDate: "2024-04-08T23:34:04.586Z",
|
|
423
|
+
stripeCustomerId: "",
|
|
424
|
+
invoiceInfo: {
|
|
425
|
+
_id: "66147eecae83bb001540dd95",
|
|
426
|
+
legal_name: "",
|
|
427
|
+
tax_system: "",
|
|
428
|
+
zipCode: "",
|
|
429
|
+
},
|
|
430
|
+
_id: "66147eecae83bb001540dd96",
|
|
431
|
+
name: "Carlos Piña 🍍",
|
|
432
|
+
phone: "",
|
|
433
|
+
address: "",
|
|
434
|
+
notes: "",
|
|
435
|
+
privateNotes: "",
|
|
436
|
+
rfc: "",
|
|
437
|
+
createdBy: "62d194d77ec933001631e831",
|
|
438
|
+
createdIn: "629c267812db5b001692adae",
|
|
439
|
+
company: "629c267712db5b001692ad9e",
|
|
440
|
+
paymentMethods: [],
|
|
441
|
+
__v: 0,
|
|
442
|
+
title: "Carlos Piña 🍍",
|
|
443
|
+
id: "66147eecae83bb001540dd96",
|
|
444
|
+
},
|
|
445
|
+
customerName: "Carlos Piña 🍍",
|
|
446
|
+
pickingUpDateTime: null,
|
|
447
|
+
cleanedDateTime: null,
|
|
448
|
+
readyDateTime: null,
|
|
449
|
+
deliveringDateTime: null,
|
|
450
|
+
collectedDateTime: null,
|
|
451
|
+
cancelledDateTime: null,
|
|
452
|
+
paidDateTime: null,
|
|
453
|
+
status: "cleaning",
|
|
454
|
+
prepaidAmount: 0,
|
|
455
|
+
prepaidPaymentMethod: "",
|
|
456
|
+
customerDiscount: 0,
|
|
457
|
+
productTotal: 54.22,
|
|
458
|
+
taxesTotal: 8.68,
|
|
459
|
+
productTotalWithoutDiscount: 54.22,
|
|
460
|
+
totalDiscountAmount: 0,
|
|
461
|
+
shippingServiceTotal: 0,
|
|
462
|
+
discountsToApply: [],
|
|
463
|
+
usePrepaid: false,
|
|
464
|
+
cashierBox: "629c267812db5b001692adb3",
|
|
465
|
+
discountCode: "",
|
|
466
|
+
buyAndGetProducts: [],
|
|
467
|
+
deliveryRoute: null,
|
|
468
|
+
pickupRoute: null,
|
|
469
|
+
createdDate: "2024-04-08T23:34:48.950Z",
|
|
470
|
+
},
|
|
471
|
+
customer: {
|
|
472
|
+
customer: {
|
|
473
|
+
password: "",
|
|
474
|
+
google: false,
|
|
475
|
+
facebook: false,
|
|
476
|
+
apple: false,
|
|
477
|
+
useStoreApp: false,
|
|
478
|
+
discount: 0,
|
|
479
|
+
credit: 0,
|
|
480
|
+
isActive: true,
|
|
481
|
+
createdDate: "2024-04-08T23:34:04.586Z",
|
|
482
|
+
stripeCustomerId: "",
|
|
483
|
+
invoiceInfo: {
|
|
484
|
+
_id: "66147eecae83bb001540dd95",
|
|
485
|
+
legal_name: "",
|
|
486
|
+
tax_system: "",
|
|
487
|
+
zipCode: "",
|
|
488
|
+
},
|
|
489
|
+
_id: "66147eecae83bb001540dd96",
|
|
490
|
+
name: "Carlos Piña 🍍",
|
|
491
|
+
phone: "",
|
|
492
|
+
address: "",
|
|
493
|
+
notes: "",
|
|
494
|
+
privateNotes: "",
|
|
495
|
+
rfc: "",
|
|
496
|
+
createdBy: "62d194d77ec933001631e831",
|
|
497
|
+
createdIn: "629c267812db5b001692adae",
|
|
498
|
+
company: "629c267712db5b001692ad9e",
|
|
499
|
+
paymentMethods: [],
|
|
500
|
+
__v: 0,
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
store: {
|
|
504
|
+
taxesType: "included",
|
|
505
|
+
notificationConfig: {
|
|
506
|
+
notifyOrderCreated: false,
|
|
507
|
+
notifyPickedUp: false,
|
|
508
|
+
notifyCleaned: true,
|
|
509
|
+
notifyCollected: false,
|
|
510
|
+
notifyDelivered: false,
|
|
511
|
+
notifyOwnerOnOrderCreated: false,
|
|
512
|
+
notifyEmail: "",
|
|
513
|
+
_id: "62a2d05fd0a7c800160869bc",
|
|
514
|
+
},
|
|
515
|
+
paymentConfig: {
|
|
516
|
+
defaultPaymentMethod: "delivery",
|
|
517
|
+
_id: "63650e8dcfa0e30016729776",
|
|
518
|
+
},
|
|
519
|
+
orderPageConfig: {
|
|
520
|
+
defaultDeliveryDate: "0",
|
|
521
|
+
defaultDeliveryTime: "18:00",
|
|
522
|
+
defaultNotifyMethod: "none",
|
|
523
|
+
printTicketAfterOrder: true,
|
|
524
|
+
shippingServiceCost: 0,
|
|
525
|
+
showProductSearchBarWeb: true,
|
|
526
|
+
_id: "6407b53301a1aa00141b217e",
|
|
527
|
+
},
|
|
528
|
+
_id: "629c267812db5b001692adae",
|
|
529
|
+
name: "Clean & Go",
|
|
530
|
+
phone: "9983524573",
|
|
531
|
+
inventory: [],
|
|
532
|
+
discountCodes: [
|
|
533
|
+
{
|
|
534
|
+
type: "percentage",
|
|
535
|
+
value: 14,
|
|
536
|
+
products: [
|
|
537
|
+
"62d1893f7ec933001631ab24",
|
|
538
|
+
"62d189697ec933001631acab",
|
|
539
|
+
"62d19a287ec933001632156f",
|
|
540
|
+
"62d199117ec9330016320ec0",
|
|
541
|
+
"62d198e07ec9330016320cc7",
|
|
542
|
+
"62d191d67ec933001631cd76",
|
|
543
|
+
"62d191747ec933001631c9cc",
|
|
544
|
+
"62d191ad7ec933001631cbef",
|
|
545
|
+
],
|
|
546
|
+
applyToAllProducts: false,
|
|
547
|
+
applyOnceOnOrder: false,
|
|
548
|
+
hasUseLimit: false,
|
|
549
|
+
useLimitQty: 0,
|
|
550
|
+
usedCounter: 0,
|
|
551
|
+
onePerCustomer: true,
|
|
552
|
+
isActive: true,
|
|
553
|
+
buyAndGetConditions: [],
|
|
554
|
+
_id: "62d1ae1b7ec9330016328166",
|
|
555
|
+
name: "Anfitriones Airbnb",
|
|
556
|
+
code: "AIRBNBANF",
|
|
557
|
+
fromDate: "2022-07-01T05:00:00.000Z",
|
|
558
|
+
toDate: "2022-08-01T04:59:59.999Z",
|
|
559
|
+
fromTime: "00:00",
|
|
560
|
+
toTime: "23:59",
|
|
561
|
+
createdBy: "629c267812db5b001692ada4",
|
|
562
|
+
createdAt: "2022-07-15T18:12:43.506Z",
|
|
563
|
+
updatedAt: "2022-07-15T18:12:43.506Z",
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
type: "percentage",
|
|
567
|
+
value: 20,
|
|
568
|
+
products: [],
|
|
569
|
+
applyToAllProducts: true,
|
|
570
|
+
applyOnceOnOrder: false,
|
|
571
|
+
hasUseLimit: false,
|
|
572
|
+
useLimitQty: 0,
|
|
573
|
+
usedCounter: 0,
|
|
574
|
+
onePerCustomer: true,
|
|
575
|
+
isActive: true,
|
|
576
|
+
buyAndGetConditions: [],
|
|
577
|
+
_id: "635821305b689d0016c97f8c",
|
|
578
|
+
name: "Descuento por comentarios",
|
|
579
|
+
code: "20DESC01",
|
|
580
|
+
fromDate: "2022-01-01T05:00:00.000Z",
|
|
581
|
+
toDate: "2023-01-01T04:59:59.999Z",
|
|
582
|
+
fromTime: "00:00",
|
|
583
|
+
toTime: "23:59",
|
|
584
|
+
createdBy: "629c267812db5b001692ada4",
|
|
585
|
+
createdAt: "2022-10-25T17:47:28.314Z",
|
|
586
|
+
updatedAt: "2022-10-25T17:47:28.314Z",
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
type: "percentage",
|
|
590
|
+
value: 20,
|
|
591
|
+
products: [],
|
|
592
|
+
applyToAllProducts: true,
|
|
593
|
+
applyOnceOnOrder: false,
|
|
594
|
+
hasUseLimit: false,
|
|
595
|
+
useLimitQty: 0,
|
|
596
|
+
usedCounter: 0,
|
|
597
|
+
onePerCustomer: true,
|
|
598
|
+
isActive: true,
|
|
599
|
+
buyAndGetConditions: [],
|
|
600
|
+
_id: "6359c5d21332cf00168c5008",
|
|
601
|
+
name: "Descuento por comentario",
|
|
602
|
+
code: "20DESC02",
|
|
603
|
+
fromDate: "2022-01-01T05:00:00.000Z",
|
|
604
|
+
toDate: "2023-01-01T04:59:59.999Z",
|
|
605
|
+
fromTime: "00:00",
|
|
606
|
+
toTime: "23:59",
|
|
607
|
+
createdBy: "62d194d77ec933001631e831",
|
|
608
|
+
createdAt: "2022-10-26T23:42:10.732Z",
|
|
609
|
+
updatedAt: "2022-10-26T23:42:10.732Z",
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
type: "percentage",
|
|
613
|
+
value: 19,
|
|
614
|
+
products: [],
|
|
615
|
+
applyToAllProducts: true,
|
|
616
|
+
applyOnceOnOrder: false,
|
|
617
|
+
hasUseLimit: false,
|
|
618
|
+
useLimitQty: 0,
|
|
619
|
+
usedCounter: 0,
|
|
620
|
+
onePerCustomer: true,
|
|
621
|
+
isActive: true,
|
|
622
|
+
buyAndGetConditions: [],
|
|
623
|
+
_id: "6359c5ef1332cf00168c516d",
|
|
624
|
+
name: "Descuento por comentario",
|
|
625
|
+
code: "20DESC03",
|
|
626
|
+
fromDate: "2022-01-01T05:00:00.000Z",
|
|
627
|
+
toDate: "2023-01-01T04:59:59.999Z",
|
|
628
|
+
fromTime: "00:00",
|
|
629
|
+
toTime: "23:59",
|
|
630
|
+
createdBy: "62d194d77ec933001631e831",
|
|
631
|
+
createdAt: "2022-10-26T23:42:39.555Z",
|
|
632
|
+
updatedAt: "2022-10-26T23:42:39.555Z",
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
type: "percentage",
|
|
636
|
+
value: 20,
|
|
637
|
+
products: [],
|
|
638
|
+
applyToAllProducts: true,
|
|
639
|
+
applyOnceOnOrder: false,
|
|
640
|
+
hasUseLimit: false,
|
|
641
|
+
useLimitQty: 0,
|
|
642
|
+
usedCounter: 0,
|
|
643
|
+
onePerCustomer: true,
|
|
644
|
+
isActive: true,
|
|
645
|
+
buyAndGetConditions: [],
|
|
646
|
+
_id: "6359c60c1332cf00168c52c6",
|
|
647
|
+
name: "Descuento por comentario",
|
|
648
|
+
code: "20DESC04",
|
|
649
|
+
fromDate: "2022-01-01T05:00:00.000Z",
|
|
650
|
+
toDate: "2023-01-01T04:59:59.999Z",
|
|
651
|
+
fromTime: "00:00",
|
|
652
|
+
toTime: "23:59",
|
|
653
|
+
createdBy: "62d194d77ec933001631e831",
|
|
654
|
+
createdAt: "2022-10-26T23:43:08.577Z",
|
|
655
|
+
updatedAt: "2022-10-26T23:43:08.577Z",
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
type: "percentage",
|
|
659
|
+
value: 20,
|
|
660
|
+
products: [],
|
|
661
|
+
applyToAllProducts: true,
|
|
662
|
+
applyOnceOnOrder: false,
|
|
663
|
+
hasUseLimit: false,
|
|
664
|
+
useLimitQty: 0,
|
|
665
|
+
usedCounter: 0,
|
|
666
|
+
onePerCustomer: true,
|
|
667
|
+
isActive: true,
|
|
668
|
+
buyAndGetConditions: [],
|
|
669
|
+
_id: "6359c6261332cf00168c5468",
|
|
670
|
+
name: "Descuento por comentario",
|
|
671
|
+
code: "20DESC05",
|
|
672
|
+
fromDate: "2022-01-01T05:00:00.000Z",
|
|
673
|
+
toDate: "2023-01-01T04:59:59.999Z",
|
|
674
|
+
fromTime: "00:00",
|
|
675
|
+
toTime: "23:59",
|
|
676
|
+
createdBy: "62d194d77ec933001631e831",
|
|
677
|
+
createdAt: "2022-10-26T23:43:34.663Z",
|
|
678
|
+
updatedAt: "2022-10-26T23:43:34.663Z",
|
|
679
|
+
},
|
|
680
|
+
],
|
|
681
|
+
taxOne: {
|
|
682
|
+
_id: "658bb2f376aa7b001482888c",
|
|
683
|
+
value: 16,
|
|
684
|
+
name: "IVA",
|
|
685
|
+
},
|
|
686
|
+
taxThree: null,
|
|
687
|
+
taxTwo: null,
|
|
688
|
+
},
|
|
689
|
+
hasShippingCost: false,
|
|
690
|
+
storeDiscounts: [],
|
|
691
|
+
discountCodeObj: null,
|
|
692
|
+
};
|
|
350
693
|
});
|
|
351
|
-
|
|
694
|
+
|
|
695
|
+
it("test calculateOrderTotal taxes included no extra amount", () => {
|
|
352
696
|
// Test case
|
|
697
|
+
ORDER_DEMO.store.taxesType = "included";
|
|
698
|
+
ORDER_DEMO.taxesType = "included";
|
|
699
|
+
const { orderDto, customer, store, storeDiscounts, discountCodeObj } =
|
|
700
|
+
ORDER_DEMO;
|
|
701
|
+
|
|
702
|
+
const { ...informationNewPackage } = calculateOrderTotal(
|
|
703
|
+
orderDto,
|
|
704
|
+
{ customer },
|
|
705
|
+
store,
|
|
706
|
+
orderDto.delivery || orderDto.pickup,
|
|
707
|
+
// storeDiscounts.data?.discounts || [],
|
|
708
|
+
storeDiscounts,
|
|
709
|
+
discountCodeObj
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
const res = {
|
|
713
|
+
totalDiscountAmount: informationNewPackage.totalDiscountAmount,
|
|
714
|
+
totalQuantity: informationNewPackage.totalQuantity,
|
|
715
|
+
totalImportWithDiscount: informationNewPackage.productTotal,
|
|
716
|
+
totalImportWithoutDiscount:
|
|
717
|
+
informationNewPackage.productTotalWithoutDiscount,
|
|
718
|
+
totalImporTaxes: informationNewPackage.taxesTotal,
|
|
719
|
+
shippingCost: informationNewPackage.shippingServiceTotal,
|
|
720
|
+
total: informationNewPackage.total,
|
|
721
|
+
};
|
|
722
|
+
expect(res).toEqual({
|
|
723
|
+
totalDiscountAmount: 0,
|
|
724
|
+
totalQuantity: 3.7,
|
|
725
|
+
totalImportWithDiscount: 54.22,
|
|
726
|
+
totalImportWithoutDiscount: 54.22,
|
|
727
|
+
totalImporTaxes: 8.68,
|
|
728
|
+
shippingCost: 0,
|
|
729
|
+
total: 54.22 + 8.68,
|
|
730
|
+
});
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
it("test calculateOrderTotal taxes over_price no extra amount", () => {
|
|
735
|
+
// Test case
|
|
736
|
+
ORDER_DEMO.store.taxesType = "over_price";
|
|
737
|
+
ORDER_DEMO.taxesType = "over_price";
|
|
353
738
|
const {
|
|
354
739
|
orderDto,
|
|
355
740
|
customer,
|
|
@@ -377,21 +762,169 @@ describe("sum function", () => {
|
|
|
377
762
|
informationNewPackage.productTotalWithoutDiscount,
|
|
378
763
|
totalImporTaxes: informationNewPackage.taxesTotal,
|
|
379
764
|
shippingCost: informationNewPackage.shippingServiceTotal,
|
|
765
|
+
total: informationNewPackage.total,
|
|
380
766
|
};
|
|
767
|
+
expect(res).toEqual(
|
|
768
|
+
{
|
|
769
|
+
totalDiscountAmount: 0,
|
|
770
|
+
totalQuantity: 3.7,
|
|
771
|
+
totalImportWithDiscount: 62.9,
|
|
772
|
+
totalImportWithoutDiscount: 62.9,
|
|
773
|
+
totalImporTaxes: 10.06,
|
|
774
|
+
shippingCost: 0,
|
|
775
|
+
total: 72.96,
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
it("test calculateOrderTotal taxes included with extra amount", () => {
|
|
780
|
+
// Test case
|
|
781
|
+
ORDER_DEMO.orderDto.products[0].extraAmount = 50;
|
|
782
|
+
const {
|
|
783
|
+
orderDto,
|
|
784
|
+
customer,
|
|
785
|
+
store,
|
|
786
|
+
hasShippingCost,
|
|
787
|
+
storeDiscounts,
|
|
788
|
+
discountCodeObj,
|
|
789
|
+
} = ORDER_DEMO;
|
|
790
|
+
|
|
791
|
+
const { ...informationNewPackage } = calculateOrderTotal(
|
|
792
|
+
orderDto,
|
|
793
|
+
{ customer },
|
|
794
|
+
store,
|
|
795
|
+
orderDto.delivery || orderDto.pickup,
|
|
796
|
+
// storeDiscounts.data?.discounts || [],
|
|
797
|
+
storeDiscounts,
|
|
798
|
+
discountCodeObj
|
|
799
|
+
);
|
|
800
|
+
|
|
801
|
+
const res = {
|
|
802
|
+
totalDiscountAmount: informationNewPackage.totalDiscountAmount,
|
|
803
|
+
totalQuantity: informationNewPackage.totalQuantity,
|
|
804
|
+
totalImportWithDiscount: informationNewPackage.productTotal,
|
|
805
|
+
totalImportWithoutDiscount:
|
|
806
|
+
informationNewPackage.productTotalWithoutDiscount,
|
|
807
|
+
totalImporTaxes: informationNewPackage.taxesTotal,
|
|
808
|
+
shippingCost: informationNewPackage.shippingServiceTotal,
|
|
809
|
+
total: informationNewPackage.total,
|
|
810
|
+
total: informationNewPackage.total,
|
|
811
|
+
};
|
|
812
|
+
|
|
381
813
|
expect(res).toEqual({
|
|
814
|
+
total: 112.9,
|
|
382
815
|
totalDiscountAmount: 0,
|
|
383
816
|
totalQuantity: 3.7,
|
|
384
|
-
totalImportWithDiscount:
|
|
385
|
-
totalImportWithoutDiscount:
|
|
386
|
-
totalImporTaxes:
|
|
817
|
+
totalImportWithDiscount: 97.33,
|
|
818
|
+
totalImportWithoutDiscount: 97.33,
|
|
819
|
+
totalImporTaxes: 15.57,
|
|
387
820
|
shippingCost: 0,
|
|
388
821
|
});
|
|
389
822
|
});
|
|
390
823
|
|
|
391
|
-
it("
|
|
824
|
+
it("test calculateOrderTotal taxes over_price with extra amount", () => {
|
|
392
825
|
// Test case
|
|
393
|
-
|
|
826
|
+
ORDER_DEMO.orderDto.products[0].extraAmount = 50;
|
|
827
|
+
ORDER_DEMO.store.taxesType = "over_price";
|
|
828
|
+
ORDER_DEMO.taxesType = "over_price";
|
|
829
|
+
const {
|
|
830
|
+
orderDto,
|
|
831
|
+
customer,
|
|
832
|
+
store,
|
|
833
|
+
storeDiscounts,
|
|
834
|
+
discountCodeObj,
|
|
835
|
+
} = ORDER_DEMO;
|
|
836
|
+
|
|
837
|
+
const { ...informationNewPackage } = calculateOrderTotal(
|
|
838
|
+
orderDto,
|
|
839
|
+
{ customer },
|
|
840
|
+
store,
|
|
841
|
+
orderDto.delivery || orderDto.pickup,
|
|
842
|
+
// storeDiscounts.data?.discounts || [],
|
|
843
|
+
storeDiscounts,
|
|
844
|
+
discountCodeObj
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
const res = {
|
|
848
|
+
totalDiscountAmount: informationNewPackage.totalDiscountAmount,
|
|
849
|
+
totalQuantity: informationNewPackage.totalQuantity,
|
|
850
|
+
totalImportWithDiscount: informationNewPackage.productTotal,
|
|
851
|
+
totalImportWithoutDiscount:
|
|
852
|
+
informationNewPackage.productTotalWithoutDiscount,
|
|
853
|
+
totalImporTaxes: informationNewPackage.taxesTotal,
|
|
854
|
+
shippingCost: informationNewPackage.shippingServiceTotal,
|
|
855
|
+
total: informationNewPackage.total,
|
|
856
|
+
total: informationNewPackage.total,
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
expect(res).toEqual({
|
|
860
|
+
total: 112.9 + 18.06,
|
|
861
|
+
totalDiscountAmount: 0,
|
|
862
|
+
totalQuantity: 3.7,
|
|
863
|
+
totalImportWithDiscount: 112.9,
|
|
864
|
+
totalImportWithoutDiscount: 112.9,
|
|
865
|
+
totalImporTaxes: 18.06,
|
|
866
|
+
shippingCost: 0,
|
|
867
|
+
});
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it("test calculateOrderTotal taxes over_price with discount and sin extra amount", () => {
|
|
871
|
+
// Configurar el escenario:
|
|
872
|
+
// - Se asigna extraAmount = 0
|
|
873
|
+
// - Se activa un discountCode en orderDto y se provee un objeto discountCodeObj con descuento del 20%
|
|
874
|
+
ORDER_DEMO.orderDto.products[0].extraAmount = 0;
|
|
875
|
+
ORDER_DEMO.orderDto.discountCode = "DISCOUNT20";
|
|
876
|
+
ORDER_DEMO.discountCodeObj = {
|
|
877
|
+
type: "percentage",
|
|
878
|
+
value: 20,
|
|
879
|
+
applyToAllProducts: true,
|
|
880
|
+
products: [] // para todos, se ignora el filtrado
|
|
881
|
+
};
|
|
882
|
+
ORDER_DEMO.store.taxesType = "over_price";
|
|
883
|
+
ORDER_DEMO.taxesType = "over_price";
|
|
884
|
+
|
|
885
|
+
const { orderDto, customer, store, storeDiscounts, discountCodeObj } = ORDER_DEMO;
|
|
886
|
+
|
|
887
|
+
const informationNewPackage = calculateOrderTotal(
|
|
888
|
+
orderDto,
|
|
889
|
+
{ customer },
|
|
890
|
+
store,
|
|
891
|
+
orderDto.delivery || orderDto.pickup,
|
|
892
|
+
storeDiscounts,
|
|
893
|
+
ORDER_DEMO.discountCodeObj
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
// Con un precio base de 17, cantidad 3.7 y sin extraAmount:
|
|
897
|
+
// - Importe original sin descuento: 17 x 3.7 = 62.9
|
|
898
|
+
// - Con descuento del 20%: descuento por unidad = 17 x 0.20 = 3.4,
|
|
899
|
+
// precio descontado = 17 - 3.4 = 13.6,
|
|
900
|
+
// importe de producto con descuento = 13.6 x 3.7 = 50.32.
|
|
901
|
+
// - Impuestos (16% sobre subtotal): 112.9 es el subtotal si no se aplica descuento;
|
|
902
|
+
// pero en "over_price" se calcula sobre (precio descontado x qty + extraAmount):
|
|
903
|
+
// subtotal = 50.32, impuestos = 50.32 x 0.16 = 8.0512 ≈ 8.05.
|
|
904
|
+
// - Total a cobrar = 50.32 + 8.05 = 58.37.
|
|
905
|
+
// - El totalDiscountAmount (total de descuento aplicado) es 3.4 x 3.7 = 12.58.
|
|
906
|
+
|
|
907
|
+
const res = {
|
|
908
|
+
totalDiscountAmount: informationNewPackage.totalDiscountAmount,
|
|
909
|
+
totalQuantity: informationNewPackage.totalQuantity,
|
|
910
|
+
totalImportWithDiscount: informationNewPackage.productTotal,
|
|
911
|
+
totalImportWithoutDiscount: informationNewPackage.productTotalWithoutDiscount,
|
|
912
|
+
totalImporTaxes: informationNewPackage.taxesTotal,
|
|
913
|
+
shippingCost: informationNewPackage.shippingServiceTotal,
|
|
914
|
+
total: informationNewPackage.total,
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
expect(res).toEqual({
|
|
918
|
+
totalDiscountAmount: 12.58,
|
|
919
|
+
totalQuantity: 3.7,
|
|
920
|
+
totalImportWithDiscount: 50.32,
|
|
921
|
+
totalImportWithoutDiscount: 62.9,
|
|
922
|
+
totalImporTaxes: 8.05,
|
|
923
|
+
shippingCost: 0,
|
|
924
|
+
total: 58.37,
|
|
925
|
+
});
|
|
394
926
|
});
|
|
395
927
|
|
|
928
|
+
|
|
396
929
|
// Add more test cases as needed
|
|
397
930
|
});
|
|
@@ -8,25 +8,32 @@ export const calculateTotalTaxesIncluded = (
|
|
|
8
8
|
storeDiscounts: any[],
|
|
9
9
|
appliedOrderDiscounts: any,
|
|
10
10
|
discountCodeObj: any | null
|
|
11
|
-
) => {
|
|
11
|
+
): any => {
|
|
12
12
|
const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current: IOrderProduct) => {
|
|
13
|
+
const qty = current.qty || 0;
|
|
14
|
+
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
15
|
+
const taxFactor = 1 + taxPercentage / 100;
|
|
16
|
+
|
|
17
|
+
// Convert extraAmount from gross to net (assume extraAmount is not discounted)
|
|
18
|
+
const extraAmountGross = current.extraAmount || 0;
|
|
19
|
+
const extraAmountNet = extraAmountGross / taxFactor;
|
|
20
|
+
|
|
21
|
+
// Get the product’s gross price (excluding extraAmount)
|
|
22
|
+
const productGrossPrice = order.express ? current.expressPrice : current.price;
|
|
23
|
+
// Convert product gross price to net
|
|
24
|
+
const unitNetPrice = productGrossPrice / taxFactor;
|
|
25
|
+
|
|
26
|
+
// Determine discount percentage (if any) – discount is applied only on product net price.
|
|
13
27
|
let discPercentageInteger = 0;
|
|
14
28
|
let productPercentageDiscount = 0;
|
|
15
29
|
let customerDiscount = 0;
|
|
16
|
-
let qty = current.qty || 0;
|
|
17
|
-
const extraAmountPerUnit = current.extraAmount / qty;
|
|
18
|
-
const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
|
|
19
|
-
|
|
20
30
|
if (!order.discountCode) {
|
|
21
31
|
const discountsToApply = storeDiscounts.filter(
|
|
22
32
|
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
23
33
|
);
|
|
24
34
|
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
25
|
-
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
26
|
-
|
|
27
|
-
return prev + next.value;
|
|
28
|
-
}
|
|
29
|
-
return prev;
|
|
35
|
+
productPercentageDiscount = discountsToApply.reduce((prev: number, next: any) => {
|
|
36
|
+
return next.type === 'percentage' ? prev + next.value : prev;
|
|
30
37
|
}, 0);
|
|
31
38
|
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
32
39
|
discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount));
|
|
@@ -47,26 +54,35 @@ export const calculateTotalTaxesIncluded = (
|
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
57
|
+
|
|
58
|
+
// Calculate discount on product net price only.
|
|
59
|
+
const discountAmountPerUnit = discPercentageInteger ? unitNetPrice * discPercentageInteger : 0;
|
|
60
|
+
const discountedUnitNetPrice = unitNetPrice - discountAmountPerUnit;
|
|
61
|
+
// Reapply VAT to get discounted product gross price.
|
|
62
|
+
const discountedUnitGrossPrice = discountedUnitNetPrice * taxFactor;
|
|
63
|
+
|
|
64
|
+
// Now, calculate the final totals:
|
|
65
|
+
// For the product part:
|
|
66
|
+
const productNetTotalWithoutDiscount = unitNetPrice * qty;
|
|
67
|
+
const productNetTotalWithDiscount = discountedUnitNetPrice * qty;
|
|
68
|
+
// Add the extraAmount net (since it is not discounted):
|
|
69
|
+
const totalNetWithoutDiscount = productNetTotalWithoutDiscount + extraAmountNet;
|
|
70
|
+
const totalNetWithDiscount = productNetTotalWithDiscount + extraAmountNet;
|
|
71
|
+
|
|
72
|
+
// Reapply VAT to both totals:
|
|
73
|
+
const productLineImportTotal = + (totalNetWithoutDiscount * taxFactor).toFixed(2);
|
|
74
|
+
const productLineTotalWithDiscount = + (totalNetWithDiscount * taxFactor).toFixed(2);
|
|
75
|
+
|
|
76
|
+
// Calculate the taxes as the difference between gross and net:
|
|
77
|
+
const totalTaxesApplied = + (productLineImportTotal - totalNetWithoutDiscount).toFixed(2);
|
|
78
|
+
|
|
79
|
+
const lineDiscount = + (discountAmountPerUnit * qty).toFixed(2);
|
|
80
|
+
|
|
65
81
|
return {
|
|
66
82
|
product: current,
|
|
67
|
-
qty
|
|
68
|
-
productLineImportTotal
|
|
69
|
-
productLineTotalWithDiscount
|
|
83
|
+
qty,
|
|
84
|
+
productLineImportTotal, // original gross total (no discount)
|
|
85
|
+
productLineTotalWithDiscount, // gross total after discount on product (extra not discounted)
|
|
70
86
|
productLineTaxesTotal: totalTaxesApplied,
|
|
71
87
|
lineDiscountAmount: lineDiscount
|
|
72
88
|
};
|