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.
@@ -2,20 +2,25 @@ import { getProductTaxesPercentage } from "./helpers";
2
2
  export const calculateTotalTaxesIncluded = (order, selectedCustomer, storeSettings, storeDiscounts, appliedOrderDiscounts, discountCodeObj) => {
3
3
  const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current) => {
4
4
  var _a, _b;
5
+ const qty = current.qty || 0;
6
+ const taxPercentage = getProductTaxesPercentage(current, storeSettings);
7
+ const taxFactor = 1 + taxPercentage / 100;
8
+ // Convert extraAmount from gross to net (assume extraAmount is not discounted)
9
+ const extraAmountGross = current.extraAmount || 0;
10
+ const extraAmountNet = extraAmountGross / taxFactor;
11
+ // Get the product’s gross price (excluding extraAmount)
12
+ const productGrossPrice = order.express ? current.expressPrice : current.price;
13
+ // Convert product gross price to net
14
+ const unitNetPrice = productGrossPrice / taxFactor;
15
+ // Determine discount percentage (if any) – discount is applied only on product net price.
5
16
  let discPercentageInteger = 0;
6
17
  let productPercentageDiscount = 0;
7
18
  let customerDiscount = 0;
8
- let qty = current.qty || 0;
9
- const extraAmountPerUnit = current.extraAmount / qty;
10
- const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
11
19
  if (!order.discountCode) {
12
20
  const discountsToApply = storeDiscounts.filter((discount) => discount.products.includes(current._id) && discount.isActive);
13
21
  customerDiscount = ((_a = selectedCustomer === null || selectedCustomer === void 0 ? void 0 : selectedCustomer.customer) === null || _a === void 0 ? void 0 : _a.discount) || 0;
14
22
  productPercentageDiscount = discountsToApply.reduce((prev, next) => {
15
- if (next.type === 'percentage') {
16
- return prev + next.value;
17
- }
18
- return prev;
23
+ return next.type === 'percentage' ? prev + next.value : prev;
19
24
  }, 0);
20
25
  discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
21
26
  discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount));
@@ -37,22 +42,29 @@ export const calculateTotalTaxesIncluded = (order, selectedCustomer, storeSettin
37
42
  }
38
43
  }
39
44
  }
40
- const taxPercentage = getProductTaxesPercentage(current, storeSettings);
41
- const taxPercentageInteger = taxPercentage / 100;
42
- const unitPrice = prodPrice / (1 + taxPercentageInteger);
43
- const discountAmountPerUnit = discPercentageInteger
44
- ? unitPrice * discPercentageInteger
45
- : (current.discountAmount || 0) / (1 + taxPercentageInteger);
46
- const prodPriceWithDiscountPerUnit = unitPrice - discountAmountPerUnit;
47
- const taxesAmountPerUnit = prodPriceWithDiscountPerUnit * taxPercentageInteger;
48
- const totalTaxesApplied = +(taxesAmountPerUnit * qty).toFixed(2);
49
- const lineDiscount = qty * discountAmountPerUnit;
50
- const prodLinePriceWithDiscount = +(qty * prodPriceWithDiscountPerUnit).toFixed(2);
45
+ // Calculate discount on product net price only.
46
+ const discountAmountPerUnit = discPercentageInteger ? unitNetPrice * discPercentageInteger : 0;
47
+ const discountedUnitNetPrice = unitNetPrice - discountAmountPerUnit;
48
+ // Reapply VAT to get discounted product gross price.
49
+ const discountedUnitGrossPrice = discountedUnitNetPrice * taxFactor;
50
+ // Now, calculate the final totals:
51
+ // For the product part:
52
+ const productNetTotalWithoutDiscount = unitNetPrice * qty;
53
+ const productNetTotalWithDiscount = discountedUnitNetPrice * qty;
54
+ // Add the extraAmount net (since it is not discounted):
55
+ const totalNetWithoutDiscount = productNetTotalWithoutDiscount + extraAmountNet;
56
+ const totalNetWithDiscount = productNetTotalWithDiscount + extraAmountNet;
57
+ // Reapply VAT to both totals:
58
+ const productLineImportTotal = +(totalNetWithoutDiscount * taxFactor).toFixed(2);
59
+ const productLineTotalWithDiscount = +(totalNetWithDiscount * taxFactor).toFixed(2);
60
+ // Calculate the taxes as the difference between gross and net:
61
+ const totalTaxesApplied = +(productLineImportTotal - totalNetWithoutDiscount).toFixed(2);
62
+ const lineDiscount = +(discountAmountPerUnit * qty).toFixed(2);
51
63
  return {
52
64
  product: current,
53
- qty: qty,
54
- productLineImportTotal: unitPrice * qty,
55
- productLineTotalWithDiscount: prodLinePriceWithDiscount,
65
+ qty,
66
+ productLineImportTotal, // original gross total (no discount)
67
+ productLineTotalWithDiscount, // gross total after discount on product (extra not discounted)
56
68
  productLineTaxesTotal: totalTaxesApplied,
57
69
  lineDiscountAmount: lineDiscount
58
70
  };
@@ -7,24 +7,16 @@ export const calculateTotalTaxesOverPrice = (order, selectedCustomer, storeSetti
7
7
  let productPercentageDiscount = 0;
8
8
  let customerDiscount = 0;
9
9
  let qty = current.qty;
10
- // extraAmount es en general sin importar el qty, entonces aqui lo repartimos por igual
11
- const extraAmountPerUnit = current.extraAmount / qty;
12
- const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
10
+ // Precio base sin impuestos y sin extraAmount
11
+ const productBasePrice = order.express ? current.expressPrice : current.price;
12
+ // Calcular descuentos solo sobre el producto
13
13
  if (!order.discountCode) {
14
- //IF ORDER HAS A DISCOUNT CODE WE DON'T APPLY ANY OTHER DISCOUNT (AUTOMATICALLY OR CUSTOMER DISCOUNT)
15
- //THIS WILL GET THE DISCOUNTS OF THE CURRENT PRODUCT
16
- // get store discounts if product applies and customer discount
17
14
  const discountsToApply = storeDiscounts.filter((discount) => discount.products.includes(current._id) && discount.isActive);
18
15
  customerDiscount = ((_a = selectedCustomer === null || selectedCustomer === void 0 ? void 0 : selectedCustomer.customer) === null || _a === void 0 ? void 0 : _a.discount) || 0;
19
- productPercentageDiscount = discountsToApply.reduce((prev, next) => {
20
- if (next.type === 'percentage') {
21
- // for now we just sum percetange type discounts
22
- return prev + next.value;
23
- }
24
- return prev;
16
+ productPercentageDiscount = discountsToApply.reduce((acc, discount) => {
17
+ return discount.type === 'percentage' ? acc + discount.value : acc;
25
18
  }, 0);
26
19
  discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
27
- discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount)); // it will do this for every product, if two products has the same discount it will just overwrite
28
20
  }
29
21
  else {
30
22
  if (discountCodeObj.type === DiscountCodeTypes.PERCENTAGE) {
@@ -35,32 +27,30 @@ export const calculateTotalTaxesOverPrice = (order, selectedCustomer, storeSetti
35
27
  : 0;
36
28
  }
37
29
  }
38
- if (discountCodeObj.type === DiscountCodeTypes.BUY_X_GET_Y) {
39
- const discountType = discountCodeObj.buyAndGetConditions[0].getDiscountType;
40
- const discountValue = discountCodeObj.buyAndGetConditions[0].discountValue;
41
- if (discountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
42
- discPercentageInteger = +(discountValue / 100).toFixed(2);
30
+ else if (discountCodeObj.type === DiscountCodeTypes.BUY_X_GET_Y) {
31
+ const condition = discountCodeObj.buyAndGetConditions[0];
32
+ if (condition.getDiscountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
33
+ discPercentageInteger = +(condition.discountValue / 100).toFixed(2);
43
34
  }
44
35
  }
45
36
  }
46
- //GET DISCOUNT AMOUNT (IN CASE discPercentageInteger is 0 it could be a discount of a integer number)
47
- const discountAmountPerUnit = discPercentageInteger
48
- ? prodPrice * discPercentageInteger
49
- : (current.discountAmount || 0);
50
- //GET PRODUCT PRICE WITH DISCOUNT
51
- const prodPriceWithDiscountPerUnit = prodPrice - discountAmountPerUnit;
52
- //GET PRODUCT TAXES APPLIED TO FINAL PRICE PER UNIT
53
- const taxPercentage = getProductTaxesPercentage(current, storeSettings);
54
- const taxPercentageInteger = taxPercentage / 100;
55
- const prodPriceWithoutTaxesPerUnit = prodPriceWithDiscountPerUnit;
56
- const taxesAmountPerUnit = prodPriceWithoutTaxesPerUnit * taxPercentageInteger;
57
- const totalTaxesApplied = +(taxesAmountPerUnit * qty).toFixed(2);
58
- let lineDiscount = qty * discountAmountPerUnit;
59
- let prodLinePriceWithDiscount = +(qty * prodPriceWithDiscountPerUnit).toFixed(2);
37
+ // Calcular descuento solo sobre el producto
38
+ const productDiscount = productBasePrice * discPercentageInteger;
39
+ const discountedProductPrice = productBasePrice - productDiscount;
40
+ // Calcular subtotal: se aplica el descuento al producto, y luego se suma el extraAmount (que se cobra completo)
41
+ const subtotal = (discountedProductPrice * qty) + current.extraAmount;
42
+ // Calcular impuestos sobre el subtotal final
43
+ const taxPercentage = getProductTaxesPercentage(current, storeSettings) / 100;
44
+ const taxes = subtotal * taxPercentage;
45
+ // Resultados finales
46
+ const totalTaxesApplied = +(taxes).toFixed(2);
47
+ const lineDiscount = +(productDiscount * qty).toFixed(2);
48
+ // Se suma el extraAmount a la parte del producto descontado para obtener el valor total a cobrar de la línea
49
+ const prodLinePriceWithDiscount = +(((discountedProductPrice * qty) + current.extraAmount)).toFixed(2);
60
50
  return {
61
51
  product: current,
62
- qty: qty,
63
- productLineImportTotal: prodPrice * qty, //this is line without discount
52
+ qty,
53
+ productLineImportTotal: (productBasePrice * qty) + current.extraAmount,
64
54
  productLineTotalWithDiscount: prodLinePriceWithDiscount,
65
55
  productLineTaxesTotal: totalTaxesApplied,
66
56
  lineDiscountAmount: lineDiscount
@@ -56,42 +56,37 @@ export const getCreditApplied = (selectedCustomer, orderTotal) => {
56
56
  return Math.min(customerCredit, orderTotal);
57
57
  };
58
58
  export const applyDiscountToProducts = (discountCode, productsArr, isExpress, storeDiscounts = [], selectedCustomer = { discount: 0 }) => {
59
- var _a, _b;
60
59
  if (!discountCode) {
61
- ///WE NEED TO APPLY DISCOUNT IN CASE WE HAVE AUTOMATIC DISCOUNT APPLIED
60
+ // Caso sin discountCode: se aplican descuentos automáticos solo sobre el precio del producto
62
61
  return {
63
62
  newOrderProds: productsArr.map((prod) => {
64
63
  const discountsToApply = storeDiscounts.filter((discount) => discount.products.includes(prod._id) && discount.isActive);
65
64
  const customerDiscount = (selectedCustomer === null || selectedCustomer === void 0 ? void 0 : selectedCustomer.discount) / 100 || 0;
66
65
  const productPercentageDiscount = discountsToApply.reduce((prev, next) => {
67
66
  if (next.type === 'percentage') {
68
- // for now we just sum percetange type discounts
69
67
  return prev + next.value / 100;
70
68
  }
71
69
  return prev;
72
70
  }, 0);
73
71
  const prodPrice = isExpress ? prod.expressPrice : prod.price;
74
- const extraAmountPerUnit = prod.extraAmount / prod.qty || 0;
75
- const discountAmount = +((productPercentageDiscount + customerDiscount) *
76
- (prodPrice + extraAmountPerUnit)).toFixed(2);
72
+ // Se remueve el extraAmountPerUnit para que el descuento se aplique solo sobre prodPrice
73
+ const discountAmount = +((productPercentageDiscount + customerDiscount) * prodPrice).toFixed(2);
77
74
  return Object.assign(Object.assign({}, prod), { discountAmount: discountAmount });
78
75
  }),
79
76
  buyAndGetProds: []
80
77
  };
81
78
  }
82
- //RESTART PRODUCTS ARR DISCOUNTS
83
- let newOrderProds = productsArr.map((prod) => {
84
- return Object.assign(Object.assign({}, prod), { discountAmount: 0 });
85
- });
86
- //THIS ARRAY ALSO INCLUDES PRODUCTS OF FREE_ITEM discount code type
79
+ // Reiniciar los descuentos en los productos
80
+ let newOrderProds = productsArr.map((prod) => (Object.assign(Object.assign({}, prod), { discountAmount: 0 })));
81
+ // Array para productos de descuento BUY_X_GET_Y o FREE_ITEM
87
82
  const buyAndGetProds = [];
88
83
  if (discountCode && discountCode.type === DiscountCodeTypes.PERCENTAGE) {
89
84
  const percentageDiscount = discountCode.value / 100;
90
85
  if (discountCode.applyToAllProducts) {
91
86
  newOrderProds = newOrderProds.map((prod) => {
92
87
  const prodPrice = isExpress ? prod.expressPrice : prod.price;
93
- const extraAmountPerUnit = prod.extraAmount / prod.qty || 0;
94
- const discountAmount = +(percentageDiscount * (prodPrice + extraAmountPerUnit)).toFixed(2);
88
+ // Aplica descuento solo sobre prodPrice (no se incluye extraAmountPerUnit)
89
+ const discountAmount = +(percentageDiscount * prodPrice).toFixed(2);
95
90
  return Object.assign(Object.assign({}, prod), { discountAmount: discountAmount });
96
91
  });
97
92
  }
@@ -101,8 +96,7 @@ export const applyDiscountToProducts = (discountCode, productsArr, isExpress, st
101
96
  if (prodIdx !== -1) {
102
97
  let prodObj = newOrderProds[prodIdx];
103
98
  const prodPrice = isExpress ? prodObj.expressPrice : prodObj.price;
104
- const extraAmountPerUnit = prodObj.extraAmount / prodObj.qty || 0;
105
- const discountAmount = +(percentageDiscount * (prodPrice + extraAmountPerUnit)).toFixed(2);
99
+ const discountAmount = +(percentageDiscount * prodPrice).toFixed(2);
106
100
  prodObj.discountAmount = discountAmount;
107
101
  newOrderProds[prodIdx] = prodObj;
108
102
  }
@@ -113,9 +107,7 @@ export const applyDiscountToProducts = (discountCode, productsArr, isExpress, st
113
107
  const discountAmount = discountCode.value;
114
108
  if (!discountCode.applyOnceOnOrder) {
115
109
  if (discountCode.applyToAllProducts) {
116
- newOrderProds = newOrderProds.map((prod) => {
117
- return Object.assign(Object.assign({}, prod), { discountAmount: discountAmount });
118
- });
110
+ newOrderProds = newOrderProds.map((prod) => (Object.assign(Object.assign({}, prod), { discountAmount: discountAmount })));
119
111
  }
120
112
  else {
121
113
  for (let discountProduct of discountCode.products) {
@@ -137,7 +129,7 @@ export const applyDiscountToProducts = (discountCode, productsArr, isExpress, st
137
129
  let buyConditionFulfilledCounter = 0;
138
130
  for (let prodCondition of buyConditions) {
139
131
  const orderProd = productsArr.find((ordProd) => ordProd._id === prodCondition.buyProduct._id);
140
- //TODO : IN CASE WE HAVE MORE PRODUCT CONDITIONS, THIS WON'T WORK SINCE THIS LINE JUST CHECKS 1 PRODUCT CONDITION
132
+ // Nota: Aquí solo se verifica una condición de producto
141
133
  if (orderProd) {
142
134
  let qty = orderProd.qty || orderProd.quantity;
143
135
  buyConditionFulfilledCounter = Math.floor(qty / prodCondition.qty);
@@ -145,15 +137,14 @@ export const applyDiscountToProducts = (discountCode, productsArr, isExpress, st
145
137
  }
146
138
  if (buyConditionFulfilledCounter) {
147
139
  for (let prodCondition of getConditions) {
148
- //HERE WE SHOULD GET PROD PRICE MAYBE VERIFY IF IS PERCENTAGE AND TAXES ARE INCLUDED IN PRICE, WE SHOULD GET PRODUCT WITHOUT TAXES;
140
+ // Se utiliza solo el precio del producto (sin extraAmount) para calcular el descuento
149
141
  const prodPrice = isExpress
150
142
  ? prodCondition.getProduct.expressPrice
151
143
  : prodCondition.getProduct.price;
152
- const extraAmountPerUnit = ((_a = prodCondition.getProduct) === null || _a === void 0 ? void 0 : _a.extraAmount) / ((_b = prodCondition.getProduct) === null || _b === void 0 ? void 0 : _b.qty) || 0 || 0;
153
144
  const percentageDiscount = discountValue / 100;
154
145
  const discountAmount = discountType === BuyAndGetConditionsTypes.FREE
155
- ? prodPrice + extraAmountPerUnit
156
- : +(percentageDiscount * (prodPrice + extraAmountPerUnit)).toFixed(2);
146
+ ? prodPrice
147
+ : +(percentageDiscount * prodPrice).toFixed(2);
157
148
  buyAndGetProds.push(Object.assign(Object.assign({}, prodCondition.getProduct), { qty: buyConditionFulfilledCounter * prodCondition.qty, quantity: buyConditionFulfilledCounter * prodCondition.qty, discountAmount: discountAmount, isBuyAndGetProduct: true }));
158
149
  }
159
150
  }
@@ -162,10 +153,9 @@ export const applyDiscountToProducts = (discountCode, productsArr, isExpress, st
162
153
  const freeProductsSettinggs = discountCode.freeProductSetting[0];
163
154
  const freeProduct = freeProductsSettinggs.product;
164
155
  const prodPrice = isExpress ? freeProduct.expressPrice : freeProduct.price;
165
- const extraAmountPerUnit = freeProduct.extraAmount / freeProduct.qty || 0 || 0;
166
- const discountAmount = prodPrice + extraAmountPerUnit;
167
- buyAndGetProds.push(Object.assign(Object.assign({}, freeProduct), { qty: freeProductsSettinggs.qty, quantity: freeProductsSettinggs.qty, discountAmount: discountAmount, isBuyAndGetProduct: true, isFreeItem: true //we dont' really use this attribute at the moment
168
- }));
156
+ // Para free item, se asume que el producto es gratuito, es decir, se descuenta el precio del producto
157
+ const discountAmount = prodPrice;
158
+ buyAndGetProds.push(Object.assign(Object.assign({}, freeProduct), { qty: freeProductsSettinggs.qty, quantity: freeProductsSettinggs.qty, discountAmount: discountAmount, isBuyAndGetProduct: true, isFreeItem: true }));
169
159
  }
170
160
  return { newOrderProds, buyAndGetProds };
171
161
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "washday-sdk",
3
- "version": "0.0.160",
3
+ "version": "0.0.162",
4
4
  "description": "Washday utilities functions and API",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",