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
|
@@ -14,27 +14,20 @@ export const calculateTotalTaxesOverPrice = (
|
|
|
14
14
|
let productPercentageDiscount = 0;
|
|
15
15
|
let customerDiscount = 0;
|
|
16
16
|
let qty = current.qty;
|
|
17
|
-
// extraAmount es en general sin importar el qty, entonces aqui lo repartimos por igual
|
|
18
|
-
const extraAmountPerUnit = current.extraAmount / qty;
|
|
19
|
-
const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
|
|
20
17
|
|
|
18
|
+
// Precio base sin impuestos y sin extraAmount
|
|
19
|
+
const productBasePrice = order.express ? current.expressPrice : current.price;
|
|
20
|
+
|
|
21
|
+
// Calcular descuentos solo sobre el producto
|
|
21
22
|
if (!order.discountCode) {
|
|
22
|
-
//IF ORDER HAS A DISCOUNT CODE WE DON'T APPLY ANY OTHER DISCOUNT (AUTOMATICALLY OR CUSTOMER DISCOUNT)
|
|
23
|
-
//THIS WILL GET THE DISCOUNTS OF THE CURRENT PRODUCT
|
|
24
|
-
// get store discounts if product applies and customer discount
|
|
25
23
|
const discountsToApply = storeDiscounts.filter(
|
|
26
24
|
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
27
25
|
);
|
|
28
26
|
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
29
|
-
productPercentageDiscount = discountsToApply.reduce((
|
|
30
|
-
|
|
31
|
-
// for now we just sum percetange type discounts
|
|
32
|
-
return prev + next.value;
|
|
33
|
-
}
|
|
34
|
-
return prev;
|
|
27
|
+
productPercentageDiscount = discountsToApply.reduce((acc, discount) => {
|
|
28
|
+
return discount.type === 'percentage' ? acc + discount.value : acc;
|
|
35
29
|
}, 0);
|
|
36
30
|
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
37
|
-
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
|
|
38
31
|
} else {
|
|
39
32
|
if (discountCodeObj.type === DiscountCodeTypes.PERCENTAGE) {
|
|
40
33
|
discPercentageInteger = +(discountCodeObj.value / 100).toFixed(2);
|
|
@@ -43,39 +36,39 @@ export const calculateTotalTaxesOverPrice = (
|
|
|
43
36
|
? +(discountCodeObj.value / 100).toFixed(2)
|
|
44
37
|
: 0;
|
|
45
38
|
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (discountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
|
|
51
|
-
discPercentageInteger = +(discountValue / 100).toFixed(2);
|
|
39
|
+
} else if (discountCodeObj.type === DiscountCodeTypes.BUY_X_GET_Y) {
|
|
40
|
+
const condition = discountCodeObj.buyAndGetConditions[0];
|
|
41
|
+
if (condition.getDiscountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
|
|
42
|
+
discPercentageInteger = +(condition.discountValue / 100).toFixed(2);
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
45
|
}
|
|
55
46
|
|
|
56
|
-
//
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
// Calcular descuento solo sobre el producto
|
|
48
|
+
const productDiscount = productBasePrice * discPercentageInteger;
|
|
49
|
+
const discountedProductPrice = productBasePrice - productDiscount;
|
|
50
|
+
|
|
51
|
+
// Calcular subtotal: se aplica el descuento al producto, y luego se suma el extraAmount (que se cobra completo)
|
|
52
|
+
const subtotal = (discountedProductPrice * qty) + current.extraAmount;
|
|
53
|
+
|
|
54
|
+
// Calcular impuestos sobre el subtotal final
|
|
55
|
+
const taxPercentage = getProductTaxesPercentage(current, storeSettings) / 100;
|
|
56
|
+
const taxes = subtotal * taxPercentage;
|
|
57
|
+
|
|
58
|
+
// Resultados finales
|
|
59
|
+
const totalTaxesApplied = +(taxes).toFixed(2);
|
|
60
|
+
const lineDiscount = +(productDiscount * qty).toFixed(2);
|
|
61
|
+
// Se suma el extraAmount a la parte del producto descontado para obtener el valor total a cobrar de la línea
|
|
62
|
+
const prodLinePriceWithDiscount = +(((discountedProductPrice * qty) + current.extraAmount)).toFixed(2);
|
|
70
63
|
|
|
71
64
|
return {
|
|
72
65
|
product: current,
|
|
73
|
-
qty
|
|
74
|
-
productLineImportTotal:
|
|
66
|
+
qty,
|
|
67
|
+
productLineImportTotal: (productBasePrice * qty) + current.extraAmount,
|
|
75
68
|
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
76
69
|
productLineTaxesTotal: totalTaxesApplied,
|
|
77
70
|
lineDiscountAmount: lineDiscount
|
|
78
71
|
};
|
|
79
72
|
});
|
|
80
73
|
return productTableImports;
|
|
81
|
-
};
|
|
74
|
+
};
|
|
@@ -71,156 +71,140 @@ export const getCreditApplied = (selectedCustomer: { customer: ICustomer } | und
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
export const applyDiscountToProducts = (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
74
|
+
discountCode: {
|
|
75
|
+
freeProductSetting: any;
|
|
76
|
+
products: any;
|
|
77
|
+
value: number;
|
|
78
|
+
type: string;
|
|
79
|
+
applyToAllProducts: boolean;
|
|
80
|
+
applyOnceOnOrder: boolean;
|
|
81
|
+
buyAndGetConditions: any,
|
|
82
|
+
},
|
|
83
|
+
productsArr: any,
|
|
84
|
+
isExpress: boolean,
|
|
85
|
+
storeDiscounts: any = [],
|
|
86
|
+
selectedCustomer = { discount: 0 }
|
|
87
87
|
) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
for (let discountProduct of discountCode.products) {
|
|
136
|
-
const prodIdx = newOrderProds.findIndex((prod: any) => prod._id === discountProduct);
|
|
137
|
-
if (prodIdx !== -1) {
|
|
138
|
-
let prodObj = newOrderProds[prodIdx];
|
|
139
|
-
const prodPrice = isExpress ? prodObj.expressPrice : prodObj.price;
|
|
140
|
-
const extraAmountPerUnit = prodObj.extraAmount / prodObj.qty || 0;
|
|
141
|
-
const discountAmount = +(percentageDiscount * (prodPrice + extraAmountPerUnit)).toFixed(
|
|
142
|
-
2
|
|
143
|
-
);
|
|
144
|
-
prodObj.discountAmount = discountAmount;
|
|
145
|
-
newOrderProds[prodIdx] = prodObj;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
88
|
+
if (!discountCode) {
|
|
89
|
+
// Caso sin discountCode: se aplican descuentos automáticos solo sobre el precio del producto
|
|
90
|
+
return {
|
|
91
|
+
newOrderProds: productsArr.map((prod: any) => {
|
|
92
|
+
const discountsToApply = storeDiscounts.filter(
|
|
93
|
+
(discount: any) => discount.products.includes(prod._id) && discount.isActive
|
|
94
|
+
);
|
|
95
|
+
const customerDiscount = selectedCustomer?.discount / 100 || 0;
|
|
96
|
+
const productPercentageDiscount = discountsToApply.reduce((prev: number, next: any) => {
|
|
97
|
+
if (next.type === 'percentage') {
|
|
98
|
+
return prev + next.value / 100;
|
|
99
|
+
}
|
|
100
|
+
return prev;
|
|
101
|
+
}, 0);
|
|
102
|
+
const prodPrice = isExpress ? prod.expressPrice : prod.price;
|
|
103
|
+
// Se remueve el extraAmountPerUnit para que el descuento se aplique solo sobre prodPrice
|
|
104
|
+
const discountAmount = +((productPercentageDiscount + customerDiscount) * prodPrice).toFixed(2);
|
|
105
|
+
return { ...prod, discountAmount: discountAmount };
|
|
106
|
+
}),
|
|
107
|
+
buyAndGetProds: []
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Reiniciar los descuentos en los productos
|
|
112
|
+
let newOrderProds = productsArr.map((prod: any) => ({ ...prod, discountAmount: 0 }));
|
|
113
|
+
|
|
114
|
+
// Array para productos de descuento BUY_X_GET_Y o FREE_ITEM
|
|
115
|
+
const buyAndGetProds = [];
|
|
116
|
+
|
|
117
|
+
if (discountCode && discountCode.type === DiscountCodeTypes.PERCENTAGE) {
|
|
118
|
+
const percentageDiscount = discountCode.value / 100;
|
|
119
|
+
if (discountCode.applyToAllProducts) {
|
|
120
|
+
newOrderProds = newOrderProds.map((prod: any) => {
|
|
121
|
+
const prodPrice = isExpress ? prod.expressPrice : prod.price;
|
|
122
|
+
// Aplica descuento solo sobre prodPrice (no se incluye extraAmountPerUnit)
|
|
123
|
+
const discountAmount = +(percentageDiscount * prodPrice).toFixed(2);
|
|
124
|
+
return { ...prod, discountAmount: discountAmount };
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
for (let discountProduct of discountCode.products) {
|
|
128
|
+
const prodIdx = newOrderProds.findIndex((prod: any) => prod._id === discountProduct);
|
|
129
|
+
if (prodIdx !== -1) {
|
|
130
|
+
let prodObj = newOrderProds[prodIdx];
|
|
131
|
+
const prodPrice = isExpress ? prodObj.expressPrice : prodObj.price;
|
|
132
|
+
const discountAmount = +(percentageDiscount * prodPrice).toFixed(2);
|
|
133
|
+
prodObj.discountAmount = discountAmount;
|
|
134
|
+
newOrderProds[prodIdx] = prodObj;
|
|
148
135
|
}
|
|
136
|
+
}
|
|
149
137
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
prodObj.discountAmount = discountAmount;
|
|
166
|
-
newOrderProds[prodIdx] = prodObj;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (discountCode && discountCode.type === DiscountCodeTypes.NUMBER) {
|
|
141
|
+
const discountAmount = discountCode.value;
|
|
142
|
+
if (!discountCode.applyOnceOnOrder) {
|
|
143
|
+
if (discountCode.applyToAllProducts) {
|
|
144
|
+
newOrderProds = newOrderProds.map((prod: any) => ({ ...prod, discountAmount: discountAmount }));
|
|
145
|
+
} else {
|
|
146
|
+
for (let discountProduct of discountCode.products) {
|
|
147
|
+
const prodIdx = newOrderProds.findIndex((prod: any) => prod._id === discountProduct);
|
|
148
|
+
if (prodIdx !== -1) {
|
|
149
|
+
let prodObj = newOrderProds[prodIdx];
|
|
150
|
+
prodObj.discountAmount = discountAmount;
|
|
151
|
+
newOrderProds[prodIdx] = prodObj;
|
|
152
|
+
}
|
|
170
153
|
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (discountCode.buyAndGetConditions && discountCode.type === DiscountCodeTypes.BUY_X_GET_Y) {
|
|
159
|
+
const buyConditions = discountCode.buyAndGetConditions[0].buyConditions;
|
|
160
|
+
const getConditions = discountCode.buyAndGetConditions[0].getConditions;
|
|
161
|
+
const discountType = discountCode.buyAndGetConditions[0].getDiscountType;
|
|
162
|
+
const discountValue = discountCode.buyAndGetConditions[0].discountValue;
|
|
163
|
+
let buyConditionFulfilledCounter = 0;
|
|
164
|
+
|
|
165
|
+
for (let prodCondition of buyConditions) {
|
|
166
|
+
const orderProd = productsArr.find((ordProd: any) => ordProd._id === prodCondition.buyProduct._id);
|
|
167
|
+
// Nota: Aquí solo se verifica una condición de producto
|
|
168
|
+
if (orderProd) {
|
|
169
|
+
let qty = orderProd.qty || orderProd.quantity;
|
|
170
|
+
buyConditionFulfilledCounter = Math.floor(qty / prodCondition.qty);
|
|
171
|
+
}
|
|
171
172
|
}
|
|
172
|
-
if (discountCode.buyAndGetConditions && discountCode.type === DiscountCodeTypes.BUY_X_GET_Y) {
|
|
173
|
-
const buyConditions = discountCode.buyAndGetConditions[0].buyConditions;
|
|
174
|
-
const getConditions = discountCode.buyAndGetConditions[0].getConditions;
|
|
175
|
-
const discountType = discountCode.buyAndGetConditions[0].getDiscountType;
|
|
176
|
-
const discountValue = discountCode.buyAndGetConditions[0].discountValue;
|
|
177
|
-
let buyConditionFulfilledCounter = 0;
|
|
178
|
-
|
|
179
|
-
for (let prodCondition of buyConditions) {
|
|
180
|
-
const orderProd = productsArr.find((ordProd: any) => ordProd._id === prodCondition.buyProduct._id);
|
|
181
|
-
//TODO : IN CASE WE HAVE MORE PRODUCT CONDITIONS, THIS WON'T WORK SINCE THIS LINE JUST CHECKS 1 PRODUCT CONDITION
|
|
182
|
-
if (orderProd) {
|
|
183
|
-
let qty = orderProd.qty || orderProd.quantity;
|
|
184
|
-
buyConditionFulfilledCounter = Math.floor(qty / prodCondition.qty);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
173
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
? prodPrice + extraAmountPerUnit
|
|
200
|
-
: +(percentageDiscount * (prodPrice + extraAmountPerUnit)).toFixed(2);
|
|
201
|
-
buyAndGetProds.push({
|
|
202
|
-
...prodCondition.getProduct,
|
|
203
|
-
qty: buyConditionFulfilledCounter * prodCondition.qty,
|
|
204
|
-
quantity: buyConditionFulfilledCounter * prodCondition.qty,
|
|
205
|
-
discountAmount: discountAmount,
|
|
206
|
-
isBuyAndGetProduct: true
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} else if (discountCode.type === DiscountCodeTypes.FREE_ITEM) {
|
|
211
|
-
const freeProductsSettinggs = discountCode.freeProductSetting[0];
|
|
212
|
-
const freeProduct = freeProductsSettinggs.product;
|
|
213
|
-
const prodPrice = isExpress ? freeProduct.expressPrice : freeProduct.price;
|
|
214
|
-
const extraAmountPerUnit = freeProduct.extraAmount / freeProduct.qty || 0 || 0;
|
|
215
|
-
const discountAmount = prodPrice + extraAmountPerUnit;
|
|
174
|
+
if (buyConditionFulfilledCounter) {
|
|
175
|
+
for (let prodCondition of getConditions) {
|
|
176
|
+
// Se utiliza solo el precio del producto (sin extraAmount) para calcular el descuento
|
|
177
|
+
const prodPrice = isExpress
|
|
178
|
+
? prodCondition.getProduct.expressPrice
|
|
179
|
+
: prodCondition.getProduct.price;
|
|
180
|
+
const percentageDiscount = discountValue / 100;
|
|
181
|
+
const discountAmount =
|
|
182
|
+
discountType === BuyAndGetConditionsTypes.FREE
|
|
183
|
+
? prodPrice
|
|
184
|
+
: +(percentageDiscount * prodPrice).toFixed(2);
|
|
216
185
|
buyAndGetProds.push({
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
isFreeItem: true //we dont' really use this attribute at the moment
|
|
186
|
+
...prodCondition.getProduct,
|
|
187
|
+
qty: buyConditionFulfilledCounter * prodCondition.qty,
|
|
188
|
+
quantity: buyConditionFulfilledCounter * prodCondition.qty,
|
|
189
|
+
discountAmount: discountAmount,
|
|
190
|
+
isBuyAndGetProduct: true
|
|
223
191
|
});
|
|
192
|
+
}
|
|
224
193
|
}
|
|
225
|
-
|
|
226
|
-
|
|
194
|
+
} else if (discountCode.type === DiscountCodeTypes.FREE_ITEM) {
|
|
195
|
+
const freeProductsSettinggs = discountCode.freeProductSetting[0];
|
|
196
|
+
const freeProduct = freeProductsSettinggs.product;
|
|
197
|
+
const prodPrice = isExpress ? freeProduct.expressPrice : freeProduct.price;
|
|
198
|
+
// Para free item, se asume que el producto es gratuito, es decir, se descuenta el precio del producto
|
|
199
|
+
const discountAmount = prodPrice;
|
|
200
|
+
buyAndGetProds.push({
|
|
201
|
+
...freeProduct,
|
|
202
|
+
qty: freeProductsSettinggs.qty,
|
|
203
|
+
quantity: freeProductsSettinggs.qty,
|
|
204
|
+
discountAmount: discountAmount,
|
|
205
|
+
isBuyAndGetProduct: true,
|
|
206
|
+
isFreeItem: true
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return { newOrderProds, buyAndGetProds };
|
|
210
|
+
};
|