washday-sdk 0.0.159 → 0.0.161

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.
@@ -1,8 +1,8 @@
1
1
  // myModule.test.js
2
2
  import { calculateOrderTotal } from "./index";
3
3
 
4
- describe("sum function", () => {
5
- const ORDER_DEMO = {
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
- it("test calculateOrderTotal taxes included", () => {
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: 54.22,
385
- totalImportWithoutDiscount: 54.22,
386
- totalImporTaxes: 8.68,
817
+ totalImportWithDiscount: 97.33,
818
+ totalImportWithoutDiscount: 97.33,
819
+ totalImporTaxes: 15.57,
387
820
  shippingCost: 0,
388
821
  });
389
822
  });
390
823
 
391
- it("should return 0 when adding two zeros", () => {
824
+ it("test calculateOrderTotal taxes over_price with extra amount", () => {
392
825
  // Test case
393
- expect(sum(0, 0)).toBe(0);
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
  });
@@ -13,20 +13,32 @@ export const calculateTotalTaxesIncluded = (
13
13
  let discPercentageInteger = 0;
14
14
  let productPercentageDiscount = 0;
15
15
  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
-
16
+ const qty = current.qty || 0;
17
+
18
+ // ExtraAmount se trata de forma separada: se conserva su valor bruto, pero se convierte a neto
19
+ const extraAmount = current.extraAmount; // valor bruto (con impuestos incluidos)
20
+
21
+ // Obtener la tasa de impuesto (por ejemplo, 16%) y convertirla a decimal:
22
+ const taxPercentage = getProductTaxesPercentage(current, storeSettings);
23
+ const taxPercentageInteger = taxPercentage / 100;
24
+
25
+ // Convertir extraAmount a valor neto
26
+ const extraAmountNet = extraAmount / (1 + taxPercentageInteger);
27
+
28
+ // Precio del producto (con impuestos incluidos) SIN incluir extraAmount
29
+ const productGrossPrice = order.express ? current.expressPrice : current.price;
30
+
31
+ // Extraer el precio neto del producto
32
+ const unitNetPrice = productGrossPrice / (1 + taxPercentageInteger);
33
+
34
+ // Calcular el porcentaje de descuento (aplicable solo sobre el precio neto del producto)
20
35
  if (!order.discountCode) {
21
36
  const discountsToApply = storeDiscounts.filter(
22
37
  (discount) => discount.products.includes(current._id) && discount.isActive
23
38
  );
24
39
  customerDiscount = selectedCustomer?.customer?.discount || 0;
25
40
  productPercentageDiscount = discountsToApply.reduce((prev, next) => {
26
- if (next.type === 'percentage') {
27
- return prev + next.value;
28
- }
29
- return prev;
41
+ return next.type === 'percentage' ? prev + next.value : prev;
30
42
  }, 0);
31
43
  discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
32
44
  discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount));
@@ -47,26 +59,29 @@ export const calculateTotalTaxesIncluded = (
47
59
  }
48
60
  }
49
61
  }
50
-
51
- const taxPercentage = getProductTaxesPercentage(current, storeSettings);
52
- const taxPercentageInteger = taxPercentage / 100;
53
-
54
- const unitPrice = prodPrice / (1 + taxPercentageInteger);
62
+
63
+ // Aplicar el descuento sobre el precio neto del producto
55
64
  const discountAmountPerUnit = discPercentageInteger
56
- ? unitPrice * discPercentageInteger
65
+ ? unitNetPrice * discPercentageInteger
57
66
  : (current.discountAmount || 0) / (1 + taxPercentageInteger);
58
-
59
- const prodPriceWithDiscountPerUnit = unitPrice - discountAmountPerUnit;
60
- const taxesAmountPerUnit = prodPriceWithDiscountPerUnit * taxPercentageInteger;
61
- const totalTaxesApplied = +(taxesAmountPerUnit * qty).toFixed(2);
62
- const lineDiscount = qty * discountAmountPerUnit;
63
- const prodLinePriceWithDiscount = +(qty * prodPriceWithDiscountPerUnit).toFixed(2);
64
-
67
+ const discountedUnitNetPrice = unitNetPrice - discountAmountPerUnit;
68
+
69
+ // Calcular los importes netos:
70
+ const productNetImportWithoutDiscount = (unitNetPrice * qty) + extraAmountNet;
71
+ const productNetImportWithDiscount = (discountedUnitNetPrice * qty) + extraAmountNet;
72
+
73
+ // Para obtener los valores brutos (con impuestos), se multiplica por (1 + taxPercentageInteger)
74
+ const productGrossImportWithoutDiscount = productNetImportWithoutDiscount * (1 + taxPercentageInteger);
75
+ // La parte de impuestos es la diferencia entre el bruto y el neto
76
+ const totalTaxesApplied = +((productGrossImportWithoutDiscount - productNetImportWithoutDiscount)).toFixed(2);
77
+
78
+ const lineDiscount = +(discountAmountPerUnit * qty).toFixed(2);
79
+
65
80
  return {
66
81
  product: current,
67
- qty: qty,
68
- productLineImportTotal: unitPrice * qty,
69
- productLineTotalWithDiscount: prodLinePriceWithDiscount,
82
+ qty,
83
+ productLineImportTotal: +productNetImportWithoutDiscount.toFixed(2), // valor neto sin descuento
84
+ productLineTotalWithDiscount: +productNetImportWithDiscount.toFixed(2), // valor neto con descuento
70
85
  productLineTaxesTotal: totalTaxesApplied,
71
86
  lineDiscountAmount: lineDiscount
72
87
  };