washday-sdk 0.0.9 → 0.0.11
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/babel.config.js +7 -7
- package/dist/api/customers/get.js +1 -1
- package/dist/api/index.js +5 -0
- package/dist/api/stores/get.js +50 -0
- package/package.json +28 -28
- package/src/api/axiosInstance.ts +45 -45
- package/src/api/customers/get.ts +32 -32
- package/src/api/index.ts +26 -21
- package/src/api/stores/get.ts +33 -0
- package/src/enum/index.ts +10 -10
- package/src/index.ts +4 -4
- package/src/interfaces/Api.ts +2 -2
- package/src/interfaces/Customer.ts +51 -51
- package/src/interfaces/Order.ts +95 -95
- package/src/interfaces/Permission.ts +24 -24
- package/src/interfaces/Product.ts +58 -58
- package/src/interfaces/Section.ts +14 -14
- package/src/interfaces/Store.ts +350 -350
- package/src/interfaces/StoreImage.ts +9 -9
- package/src/interfaces/User.ts +42 -42
- package/src/utils/index.ts +1 -1
- package/src/utils/orders/calculateOrderTotal.test.js +399 -399
- package/src/utils/orders/calculateOrderTotal.ts +60 -60
- package/src/utils/orders/calculateTotalTaxesIncluded.ts +75 -75
- package/src/utils/orders/calculateTotalTaxesOverPrice.ts +82 -82
- package/src/utils/orders/helpers.ts +73 -73
- package/src/utils/orders/index.ts +4 -4
- package/tsconfig.json +9 -9
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import { DiscountCodeTypes } from "../../enum";
|
|
2
|
-
import { ICustomer } from "../../interfaces/Customer";
|
|
3
|
-
import { IStore } from "../../interfaces/Store";
|
|
4
|
-
import { calculateTotalTaxesIncluded } from "./calculateTotalTaxesIncluded";
|
|
5
|
-
import { calculateTotalTaxesOverPrice } from "./calculateTotalTaxesOverPrice";
|
|
6
|
-
import { getCreditApplied, getProductLineTotals, getShippingCost } from "./helpers";
|
|
7
|
-
|
|
8
|
-
export const calculateOrderTotal = (
|
|
9
|
-
order: any,
|
|
10
|
-
selectedCustomer: { customer: ICustomer } | undefined,
|
|
11
|
-
storeSettings: IStore,
|
|
12
|
-
hasShippingCost: boolean,
|
|
13
|
-
storeDiscounts: any[] = [],
|
|
14
|
-
discountCodeObj: any
|
|
15
|
-
): any => {
|
|
16
|
-
try {
|
|
17
|
-
const appliedOrderDiscounts: any = {};
|
|
18
|
-
const productTableCalculator = storeSettings?.taxesType === 'over_price' ? calculateTotalTaxesOverPrice : calculateTotalTaxesIncluded;
|
|
19
|
-
const productTableImports = productTableCalculator(order, selectedCustomer, storeSettings, storeDiscounts, appliedOrderDiscounts, discountCodeObj);
|
|
20
|
-
|
|
21
|
-
// PRODUCT LINE TOTALS
|
|
22
|
-
const {
|
|
23
|
-
totalQuantity,
|
|
24
|
-
totalImportWithDiscount,
|
|
25
|
-
totalImportWithoutDiscount,
|
|
26
|
-
totalImporTaxes,
|
|
27
|
-
totalDiscountAmount
|
|
28
|
-
} = getProductLineTotals(productTableImports);
|
|
29
|
-
|
|
30
|
-
// DISCOUNT TOTAL AND SHIPPING SERVICE COST
|
|
31
|
-
let discountCodeAmount = 0;
|
|
32
|
-
let shippingCost = getShippingCost(discountCodeObj, hasShippingCost, storeSettings);
|
|
33
|
-
|
|
34
|
-
if (discountCodeObj && discountCodeObj.type === DiscountCodeTypes.NUMBER && discountCodeObj.applyOnceOnOrder) {
|
|
35
|
-
const includesProducts = discountCodeObj.applyToAllProducts || order.products.some((curr: any) => discountCodeObj.products.includes(curr._id));
|
|
36
|
-
discountCodeAmount = includesProducts ? discountCodeObj.value : 0;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ORDER TOTAL CALCULATION AND CREDIT APPLIED
|
|
40
|
-
let orderTotalWithOutCredit = +(totalImportWithDiscount + totalImporTaxes + shippingCost - discountCodeAmount).toFixed(2);
|
|
41
|
-
let creditApplied = getCreditApplied(selectedCustomer, orderTotalWithOutCredit);
|
|
42
|
-
let orderTotal = +(orderTotalWithOutCredit - creditApplied).toFixed(2);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
...order,
|
|
46
|
-
totalQuantity,
|
|
47
|
-
customerDiscount: order.discountCode ? 0 : selectedCustomer?.customer?.discount,
|
|
48
|
-
productTotal: totalImportWithDiscount,
|
|
49
|
-
taxesTotal: totalImporTaxes,
|
|
50
|
-
total: orderTotal,
|
|
51
|
-
creditApplied,
|
|
52
|
-
productTotalWithoutDiscount: totalImportWithoutDiscount,
|
|
53
|
-
totalDiscountAmount: totalDiscountAmount + discountCodeAmount,
|
|
54
|
-
shippingServiceTotal: shippingCost,
|
|
55
|
-
appliedOrderDiscounts
|
|
56
|
-
};
|
|
57
|
-
} catch (error) {
|
|
58
|
-
throw error;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
1
|
+
import { DiscountCodeTypes } from "../../enum";
|
|
2
|
+
import { ICustomer } from "../../interfaces/Customer";
|
|
3
|
+
import { IStore } from "../../interfaces/Store";
|
|
4
|
+
import { calculateTotalTaxesIncluded } from "./calculateTotalTaxesIncluded";
|
|
5
|
+
import { calculateTotalTaxesOverPrice } from "./calculateTotalTaxesOverPrice";
|
|
6
|
+
import { getCreditApplied, getProductLineTotals, getShippingCost } from "./helpers";
|
|
7
|
+
|
|
8
|
+
export const calculateOrderTotal = (
|
|
9
|
+
order: any,
|
|
10
|
+
selectedCustomer: { customer: ICustomer } | undefined,
|
|
11
|
+
storeSettings: IStore,
|
|
12
|
+
hasShippingCost: boolean,
|
|
13
|
+
storeDiscounts: any[] = [],
|
|
14
|
+
discountCodeObj: any
|
|
15
|
+
): any => {
|
|
16
|
+
try {
|
|
17
|
+
const appliedOrderDiscounts: any = {};
|
|
18
|
+
const productTableCalculator = storeSettings?.taxesType === 'over_price' ? calculateTotalTaxesOverPrice : calculateTotalTaxesIncluded;
|
|
19
|
+
const productTableImports = productTableCalculator(order, selectedCustomer, storeSettings, storeDiscounts, appliedOrderDiscounts, discountCodeObj);
|
|
20
|
+
|
|
21
|
+
// PRODUCT LINE TOTALS
|
|
22
|
+
const {
|
|
23
|
+
totalQuantity,
|
|
24
|
+
totalImportWithDiscount,
|
|
25
|
+
totalImportWithoutDiscount,
|
|
26
|
+
totalImporTaxes,
|
|
27
|
+
totalDiscountAmount
|
|
28
|
+
} = getProductLineTotals(productTableImports);
|
|
29
|
+
|
|
30
|
+
// DISCOUNT TOTAL AND SHIPPING SERVICE COST
|
|
31
|
+
let discountCodeAmount = 0;
|
|
32
|
+
let shippingCost = getShippingCost(discountCodeObj, hasShippingCost, storeSettings);
|
|
33
|
+
|
|
34
|
+
if (discountCodeObj && discountCodeObj.type === DiscountCodeTypes.NUMBER && discountCodeObj.applyOnceOnOrder) {
|
|
35
|
+
const includesProducts = discountCodeObj.applyToAllProducts || order.products.some((curr: any) => discountCodeObj.products.includes(curr._id));
|
|
36
|
+
discountCodeAmount = includesProducts ? discountCodeObj.value : 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ORDER TOTAL CALCULATION AND CREDIT APPLIED
|
|
40
|
+
let orderTotalWithOutCredit = +(totalImportWithDiscount + totalImporTaxes + shippingCost - discountCodeAmount).toFixed(2);
|
|
41
|
+
let creditApplied = getCreditApplied(selectedCustomer, orderTotalWithOutCredit);
|
|
42
|
+
let orderTotal = +(orderTotalWithOutCredit - creditApplied).toFixed(2);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
...order,
|
|
46
|
+
totalQuantity,
|
|
47
|
+
customerDiscount: order.discountCode ? 0 : selectedCustomer?.customer?.discount,
|
|
48
|
+
productTotal: totalImportWithDiscount,
|
|
49
|
+
taxesTotal: totalImporTaxes,
|
|
50
|
+
total: orderTotal,
|
|
51
|
+
creditApplied,
|
|
52
|
+
productTotalWithoutDiscount: totalImportWithoutDiscount,
|
|
53
|
+
totalDiscountAmount: totalDiscountAmount + discountCodeAmount,
|
|
54
|
+
shippingServiceTotal: shippingCost,
|
|
55
|
+
appliedOrderDiscounts
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import { IOrderProduct } from "../../interfaces/Product";
|
|
2
|
-
import { getProductTaxesPercentage } from "./helpers";
|
|
3
|
-
|
|
4
|
-
export const calculateTotalTaxesIncluded = (
|
|
5
|
-
order: any,
|
|
6
|
-
selectedCustomer: any,
|
|
7
|
-
storeSettings: any,
|
|
8
|
-
storeDiscounts: any[],
|
|
9
|
-
appliedOrderDiscounts: any,
|
|
10
|
-
discountCodeObj: any | null
|
|
11
|
-
) => {
|
|
12
|
-
const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current: IOrderProduct) => {
|
|
13
|
-
let discPercentageInteger = 0;
|
|
14
|
-
let productPercentageDiscount = 0;
|
|
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
|
-
|
|
20
|
-
if (!order.discountCode) {
|
|
21
|
-
const discountsToApply = storeDiscounts.filter(
|
|
22
|
-
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
23
|
-
);
|
|
24
|
-
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
25
|
-
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
26
|
-
if (next.type === 'percentage') {
|
|
27
|
-
return prev + next.value;
|
|
28
|
-
}
|
|
29
|
-
return prev;
|
|
30
|
-
}, 0);
|
|
31
|
-
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
32
|
-
discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount));
|
|
33
|
-
} else {
|
|
34
|
-
if (discountCodeObj?.type === 'percentage') {
|
|
35
|
-
discPercentageInteger = +(discountCodeObj.value / 100).toFixed(2);
|
|
36
|
-
if (!discountCodeObj.applyToAllProducts) {
|
|
37
|
-
discPercentageInteger = discountCodeObj.products?.includes(current._id)
|
|
38
|
-
? +(discountCodeObj.value / 100).toFixed(2)
|
|
39
|
-
: 0;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (discountCodeObj?.type === 'buyXGetY') {
|
|
43
|
-
const discountType = discountCodeObj.buyAndGetConditions[0].getDiscountType;
|
|
44
|
-
const discountValue = discountCodeObj.buyAndGetConditions[0].discountValue;
|
|
45
|
-
if (discountType === 'percentage' && current.isBuyAndGetProduct) {
|
|
46
|
-
discPercentageInteger = +(discountValue / 100).toFixed(2);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
52
|
-
const taxPercentageInteger = taxPercentage / 100;
|
|
53
|
-
|
|
54
|
-
const unitPrice = prodPrice / (1 + taxPercentageInteger);
|
|
55
|
-
const discountAmountPerUnit = discPercentageInteger
|
|
56
|
-
? unitPrice * discPercentageInteger
|
|
57
|
-
: (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
|
-
|
|
65
|
-
return {
|
|
66
|
-
product: current,
|
|
67
|
-
qty: qty,
|
|
68
|
-
productLineImportTotal: unitPrice * qty,
|
|
69
|
-
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
70
|
-
productLineTaxesTotal: totalTaxesApplied,
|
|
71
|
-
lineDiscountAmount: lineDiscount
|
|
72
|
-
};
|
|
73
|
-
});
|
|
74
|
-
return productTableImports;
|
|
75
|
-
};
|
|
1
|
+
import { IOrderProduct } from "../../interfaces/Product";
|
|
2
|
+
import { getProductTaxesPercentage } from "./helpers";
|
|
3
|
+
|
|
4
|
+
export const calculateTotalTaxesIncluded = (
|
|
5
|
+
order: any,
|
|
6
|
+
selectedCustomer: any,
|
|
7
|
+
storeSettings: any,
|
|
8
|
+
storeDiscounts: any[],
|
|
9
|
+
appliedOrderDiscounts: any,
|
|
10
|
+
discountCodeObj: any | null
|
|
11
|
+
) => {
|
|
12
|
+
const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current: IOrderProduct) => {
|
|
13
|
+
let discPercentageInteger = 0;
|
|
14
|
+
let productPercentageDiscount = 0;
|
|
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
|
+
|
|
20
|
+
if (!order.discountCode) {
|
|
21
|
+
const discountsToApply = storeDiscounts.filter(
|
|
22
|
+
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
23
|
+
);
|
|
24
|
+
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
25
|
+
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
26
|
+
if (next.type === 'percentage') {
|
|
27
|
+
return prev + next.value;
|
|
28
|
+
}
|
|
29
|
+
return prev;
|
|
30
|
+
}, 0);
|
|
31
|
+
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
32
|
+
discountsToApply.forEach((discount) => (appliedOrderDiscounts[discount._id] = discount));
|
|
33
|
+
} else {
|
|
34
|
+
if (discountCodeObj?.type === 'percentage') {
|
|
35
|
+
discPercentageInteger = +(discountCodeObj.value / 100).toFixed(2);
|
|
36
|
+
if (!discountCodeObj.applyToAllProducts) {
|
|
37
|
+
discPercentageInteger = discountCodeObj.products?.includes(current._id)
|
|
38
|
+
? +(discountCodeObj.value / 100).toFixed(2)
|
|
39
|
+
: 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (discountCodeObj?.type === 'buyXGetY') {
|
|
43
|
+
const discountType = discountCodeObj.buyAndGetConditions[0].getDiscountType;
|
|
44
|
+
const discountValue = discountCodeObj.buyAndGetConditions[0].discountValue;
|
|
45
|
+
if (discountType === 'percentage' && current.isBuyAndGetProduct) {
|
|
46
|
+
discPercentageInteger = +(discountValue / 100).toFixed(2);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
52
|
+
const taxPercentageInteger = taxPercentage / 100;
|
|
53
|
+
|
|
54
|
+
const unitPrice = prodPrice / (1 + taxPercentageInteger);
|
|
55
|
+
const discountAmountPerUnit = discPercentageInteger
|
|
56
|
+
? unitPrice * discPercentageInteger
|
|
57
|
+
: (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
|
+
|
|
65
|
+
return {
|
|
66
|
+
product: current,
|
|
67
|
+
qty: qty,
|
|
68
|
+
productLineImportTotal: unitPrice * qty,
|
|
69
|
+
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
70
|
+
productLineTaxesTotal: totalTaxesApplied,
|
|
71
|
+
lineDiscountAmount: lineDiscount
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return productTableImports;
|
|
75
|
+
};
|
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
import { BuyAndGetConditionsTypes, DiscountCodeTypes } from "../../enum";
|
|
2
|
-
import { getProductTaxesPercentage } from "./helpers";
|
|
3
|
-
|
|
4
|
-
export const calculateTotalTaxesOverPrice = (
|
|
5
|
-
order: any,
|
|
6
|
-
selectedCustomer: any,
|
|
7
|
-
storeSettings: any,
|
|
8
|
-
storeDiscounts: any[],
|
|
9
|
-
appliedOrderDiscounts: any,
|
|
10
|
-
discountCodeObj: any | null
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
) => {
|
|
14
|
-
const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current) => {
|
|
15
|
-
let discPercentageInteger = 0;
|
|
16
|
-
let productPercentageDiscount = 0;
|
|
17
|
-
let customerDiscount = 0;
|
|
18
|
-
let qty = current.qty;
|
|
19
|
-
// extraAmount es en general sin importar el qty, entonces aqui lo repartimos por igual
|
|
20
|
-
const extraAmountPerUnit = current.extraAmount / qty;
|
|
21
|
-
const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
|
|
22
|
-
|
|
23
|
-
if (!order.discountCode) {
|
|
24
|
-
//IF ORDER HAS A DISCOUNT CODE WE DON'T APPLY ANY OTHER DISCOUNT (AUTOMATICALLY OR CUSTOMER DISCOUNT)
|
|
25
|
-
//THIS WILL GET THE DISCOUNTS OF THE CURRENT PRODUCT
|
|
26
|
-
// get store discounts if product applies and customer discount
|
|
27
|
-
const discountsToApply = storeDiscounts.filter(
|
|
28
|
-
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
29
|
-
);
|
|
30
|
-
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
31
|
-
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
32
|
-
if (next.type === 'percentage') {
|
|
33
|
-
// for now we just sum percetange type discounts
|
|
34
|
-
return prev + next.value;
|
|
35
|
-
}
|
|
36
|
-
return prev;
|
|
37
|
-
}, 0);
|
|
38
|
-
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
39
|
-
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
|
|
40
|
-
} else {
|
|
41
|
-
if (discountCodeObj.type === DiscountCodeTypes.PERCENTAGE) {
|
|
42
|
-
discPercentageInteger = +(discountCodeObj.value / 100).toFixed(2);
|
|
43
|
-
if (!discountCodeObj.applyToAllProducts) {
|
|
44
|
-
discPercentageInteger = discountCodeObj.products.includes(current._id)
|
|
45
|
-
? +(discountCodeObj.value / 100).toFixed(2)
|
|
46
|
-
: 0;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (discountCodeObj.type === DiscountCodeTypes.BUY_X_GET_Y) {
|
|
50
|
-
const discountType = discountCodeObj.buyAndGetConditions[0].getDiscountType;
|
|
51
|
-
const discountValue = discountCodeObj.buyAndGetConditions[0].discountValue;
|
|
52
|
-
if (discountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
|
|
53
|
-
discPercentageInteger = +(discountValue / 100).toFixed(2);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
//GET DISCOUNT AMOUNT (IN CASE discPercentageInteger is 0 it could be a discount of a integer number)
|
|
59
|
-
const discountAmountPerUnit = discPercentageInteger
|
|
60
|
-
? prodPrice * discPercentageInteger
|
|
61
|
-
: (current.discountAmount || 0);
|
|
62
|
-
//GET PRODUCT PRICE WITH DISCOUNT
|
|
63
|
-
const prodPriceWithDiscountPerUnit = prodPrice - discountAmountPerUnit;
|
|
64
|
-
//GET PRODUCT TAXES APPLIED TO FINAL PRICE PER UNIT
|
|
65
|
-
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
66
|
-
const taxPercentageInteger = taxPercentage / 100;
|
|
67
|
-
const prodPriceWithoutTaxesPerUnit = prodPriceWithDiscountPerUnit;
|
|
68
|
-
const taxesAmountPerUnit = prodPriceWithoutTaxesPerUnit * taxPercentageInteger;
|
|
69
|
-
const totalTaxesApplied = +(taxesAmountPerUnit * qty).toFixed(2);
|
|
70
|
-
let lineDiscount = qty * discountAmountPerUnit;
|
|
71
|
-
let prodLinePriceWithDiscount = +(qty * prodPriceWithDiscountPerUnit).toFixed(2);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
product: current,
|
|
75
|
-
qty: qty,
|
|
76
|
-
productLineImportTotal: prodPrice * qty, //this is line without discount
|
|
77
|
-
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
78
|
-
productLineTaxesTotal: totalTaxesApplied,
|
|
79
|
-
lineDiscountAmount: lineDiscount
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
|
-
return productTableImports;
|
|
1
|
+
import { BuyAndGetConditionsTypes, DiscountCodeTypes } from "../../enum";
|
|
2
|
+
import { getProductTaxesPercentage } from "./helpers";
|
|
3
|
+
|
|
4
|
+
export const calculateTotalTaxesOverPrice = (
|
|
5
|
+
order: any,
|
|
6
|
+
selectedCustomer: any,
|
|
7
|
+
storeSettings: any,
|
|
8
|
+
storeDiscounts: any[],
|
|
9
|
+
appliedOrderDiscounts: any,
|
|
10
|
+
discountCodeObj: any | null
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
) => {
|
|
14
|
+
const productTableImports = [...order.products, ...order.buyAndGetProducts].map((current) => {
|
|
15
|
+
let discPercentageInteger = 0;
|
|
16
|
+
let productPercentageDiscount = 0;
|
|
17
|
+
let customerDiscount = 0;
|
|
18
|
+
let qty = current.qty;
|
|
19
|
+
// extraAmount es en general sin importar el qty, entonces aqui lo repartimos por igual
|
|
20
|
+
const extraAmountPerUnit = current.extraAmount / qty;
|
|
21
|
+
const prodPrice = (order.express ? current.expressPrice : current.price) + extraAmountPerUnit;
|
|
22
|
+
|
|
23
|
+
if (!order.discountCode) {
|
|
24
|
+
//IF ORDER HAS A DISCOUNT CODE WE DON'T APPLY ANY OTHER DISCOUNT (AUTOMATICALLY OR CUSTOMER DISCOUNT)
|
|
25
|
+
//THIS WILL GET THE DISCOUNTS OF THE CURRENT PRODUCT
|
|
26
|
+
// get store discounts if product applies and customer discount
|
|
27
|
+
const discountsToApply = storeDiscounts.filter(
|
|
28
|
+
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
29
|
+
);
|
|
30
|
+
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
31
|
+
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
32
|
+
if (next.type === 'percentage') {
|
|
33
|
+
// for now we just sum percetange type discounts
|
|
34
|
+
return prev + next.value;
|
|
35
|
+
}
|
|
36
|
+
return prev;
|
|
37
|
+
}, 0);
|
|
38
|
+
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
39
|
+
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
|
|
40
|
+
} else {
|
|
41
|
+
if (discountCodeObj.type === DiscountCodeTypes.PERCENTAGE) {
|
|
42
|
+
discPercentageInteger = +(discountCodeObj.value / 100).toFixed(2);
|
|
43
|
+
if (!discountCodeObj.applyToAllProducts) {
|
|
44
|
+
discPercentageInteger = discountCodeObj.products.includes(current._id)
|
|
45
|
+
? +(discountCodeObj.value / 100).toFixed(2)
|
|
46
|
+
: 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (discountCodeObj.type === DiscountCodeTypes.BUY_X_GET_Y) {
|
|
50
|
+
const discountType = discountCodeObj.buyAndGetConditions[0].getDiscountType;
|
|
51
|
+
const discountValue = discountCodeObj.buyAndGetConditions[0].discountValue;
|
|
52
|
+
if (discountType === BuyAndGetConditionsTypes.PERCENTAGE && current.isBuyAndGetProduct) {
|
|
53
|
+
discPercentageInteger = +(discountValue / 100).toFixed(2);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//GET DISCOUNT AMOUNT (IN CASE discPercentageInteger is 0 it could be a discount of a integer number)
|
|
59
|
+
const discountAmountPerUnit = discPercentageInteger
|
|
60
|
+
? prodPrice * discPercentageInteger
|
|
61
|
+
: (current.discountAmount || 0);
|
|
62
|
+
//GET PRODUCT PRICE WITH DISCOUNT
|
|
63
|
+
const prodPriceWithDiscountPerUnit = prodPrice - discountAmountPerUnit;
|
|
64
|
+
//GET PRODUCT TAXES APPLIED TO FINAL PRICE PER UNIT
|
|
65
|
+
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
66
|
+
const taxPercentageInteger = taxPercentage / 100;
|
|
67
|
+
const prodPriceWithoutTaxesPerUnit = prodPriceWithDiscountPerUnit;
|
|
68
|
+
const taxesAmountPerUnit = prodPriceWithoutTaxesPerUnit * taxPercentageInteger;
|
|
69
|
+
const totalTaxesApplied = +(taxesAmountPerUnit * qty).toFixed(2);
|
|
70
|
+
let lineDiscount = qty * discountAmountPerUnit;
|
|
71
|
+
let prodLinePriceWithDiscount = +(qty * prodPriceWithDiscountPerUnit).toFixed(2);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
product: current,
|
|
75
|
+
qty: qty,
|
|
76
|
+
productLineImportTotal: prodPrice * qty, //this is line without discount
|
|
77
|
+
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
78
|
+
productLineTaxesTotal: totalTaxesApplied,
|
|
79
|
+
lineDiscountAmount: lineDiscount
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
return productTableImports;
|
|
83
83
|
};
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import { DiscountCodeTypes } from "../../enum";
|
|
2
|
-
import { ICustomer } from "../../interfaces/Customer";
|
|
3
|
-
import { IOrderProduct, ProductLineTotals } from "../../interfaces/Product";
|
|
4
|
-
import { IStore, ITaxConfig } from "../../interfaces/Store";
|
|
5
|
-
|
|
6
|
-
export const getProductTaxesPercentage = (productObj: IOrderProduct, store: IStore): number => {
|
|
7
|
-
const getTaxValue = (tax: ITaxConfig | null | undefined, isTaxExempt: boolean): number => {
|
|
8
|
-
if (!tax) {
|
|
9
|
-
// If no store tax configured, always return 0
|
|
10
|
-
return 0;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (isTaxExempt) {
|
|
14
|
-
// If store tax is configured and taxExempt is true, return 0
|
|
15
|
-
return 0;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// If store tax configured and taxExempt is false, return store tax
|
|
19
|
-
return tax.value;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const tax1 = getTaxValue(store.taxOne, productObj.taxExemptOne);
|
|
23
|
-
const tax2 = getTaxValue(store.taxTwo, productObj.taxExemptTwo);
|
|
24
|
-
const tax3 = getTaxValue(store.taxThree, productObj.taxExemptThree);
|
|
25
|
-
|
|
26
|
-
return tax1 + tax2 + tax3;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const getProductLineTotals = (productLinesTotals: ProductLineTotals[]) => {
|
|
30
|
-
const totalQuantity = +productLinesTotals.reduce((acum, line) => acum + line.qty, 0).toFixed(2);
|
|
31
|
-
const totalImportWithDiscount = +productLinesTotals
|
|
32
|
-
.reduce((acum, line) => acum + line.productLineTotalWithDiscount, 0)
|
|
33
|
-
.toFixed(2);
|
|
34
|
-
const totalImportWithoutDiscount = +productLinesTotals
|
|
35
|
-
.reduce((acum, line) => acum + line.productLineImportTotal, 0)
|
|
36
|
-
.toFixed(2);
|
|
37
|
-
const totalImporTaxes = +productLinesTotals
|
|
38
|
-
.reduce((acum, line) => acum + line.productLineTaxesTotal, 0)
|
|
39
|
-
.toFixed(2);
|
|
40
|
-
const totalDiscountAmount = +productLinesTotals
|
|
41
|
-
.reduce((acum, line) => acum + line.lineDiscountAmount, 0)
|
|
42
|
-
.toFixed(2);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
totalQuantity,
|
|
46
|
-
totalImportWithDiscount,
|
|
47
|
-
totalImportWithoutDiscount,
|
|
48
|
-
totalImporTaxes,
|
|
49
|
-
totalDiscountAmount
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export const getShippingCost = (discountObject: any, requireShippingService: boolean, store: IStore): number => {
|
|
54
|
-
const shippingCost = requireShippingService ? store?.orderPageConfig?.shippingServiceCost ?? 0 : 0;
|
|
55
|
-
|
|
56
|
-
if (discountObject?.type === DiscountCodeTypes.FREE_DELIVERY) {
|
|
57
|
-
return 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return shippingCost;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const getCreditApplied = (selectedCustomer: { customer: ICustomer } | undefined, orderTotal: number): number => {
|
|
64
|
-
const customerCredit = selectedCustomer?.customer?.credit ?? 0;
|
|
65
|
-
|
|
66
|
-
if (customerCredit === 0 || !selectedCustomer) {
|
|
67
|
-
return 0;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return Math.min(customerCredit, orderTotal);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
|
|
1
|
+
import { DiscountCodeTypes } from "../../enum";
|
|
2
|
+
import { ICustomer } from "../../interfaces/Customer";
|
|
3
|
+
import { IOrderProduct, ProductLineTotals } from "../../interfaces/Product";
|
|
4
|
+
import { IStore, ITaxConfig } from "../../interfaces/Store";
|
|
5
|
+
|
|
6
|
+
export const getProductTaxesPercentage = (productObj: IOrderProduct, store: IStore): number => {
|
|
7
|
+
const getTaxValue = (tax: ITaxConfig | null | undefined, isTaxExempt: boolean): number => {
|
|
8
|
+
if (!tax) {
|
|
9
|
+
// If no store tax configured, always return 0
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (isTaxExempt) {
|
|
14
|
+
// If store tax is configured and taxExempt is true, return 0
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// If store tax configured and taxExempt is false, return store tax
|
|
19
|
+
return tax.value;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const tax1 = getTaxValue(store.taxOne, productObj.taxExemptOne);
|
|
23
|
+
const tax2 = getTaxValue(store.taxTwo, productObj.taxExemptTwo);
|
|
24
|
+
const tax3 = getTaxValue(store.taxThree, productObj.taxExemptThree);
|
|
25
|
+
|
|
26
|
+
return tax1 + tax2 + tax3;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getProductLineTotals = (productLinesTotals: ProductLineTotals[]) => {
|
|
30
|
+
const totalQuantity = +productLinesTotals.reduce((acum, line) => acum + line.qty, 0).toFixed(2);
|
|
31
|
+
const totalImportWithDiscount = +productLinesTotals
|
|
32
|
+
.reduce((acum, line) => acum + line.productLineTotalWithDiscount, 0)
|
|
33
|
+
.toFixed(2);
|
|
34
|
+
const totalImportWithoutDiscount = +productLinesTotals
|
|
35
|
+
.reduce((acum, line) => acum + line.productLineImportTotal, 0)
|
|
36
|
+
.toFixed(2);
|
|
37
|
+
const totalImporTaxes = +productLinesTotals
|
|
38
|
+
.reduce((acum, line) => acum + line.productLineTaxesTotal, 0)
|
|
39
|
+
.toFixed(2);
|
|
40
|
+
const totalDiscountAmount = +productLinesTotals
|
|
41
|
+
.reduce((acum, line) => acum + line.lineDiscountAmount, 0)
|
|
42
|
+
.toFixed(2);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
totalQuantity,
|
|
46
|
+
totalImportWithDiscount,
|
|
47
|
+
totalImportWithoutDiscount,
|
|
48
|
+
totalImporTaxes,
|
|
49
|
+
totalDiscountAmount
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const getShippingCost = (discountObject: any, requireShippingService: boolean, store: IStore): number => {
|
|
54
|
+
const shippingCost = requireShippingService ? store?.orderPageConfig?.shippingServiceCost ?? 0 : 0;
|
|
55
|
+
|
|
56
|
+
if (discountObject?.type === DiscountCodeTypes.FREE_DELIVERY) {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return shippingCost;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const getCreditApplied = (selectedCustomer: { customer: ICustomer } | undefined, orderTotal: number): number => {
|
|
64
|
+
const customerCredit = selectedCustomer?.customer?.credit ?? 0;
|
|
65
|
+
|
|
66
|
+
if (customerCredit === 0 || !selectedCustomer) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return Math.min(customerCredit, orderTotal);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { calculateOrderTotal } from './calculateOrderTotal';
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
calculateOrderTotal
|
|
1
|
+
import { calculateOrderTotal } from './calculateOrderTotal';
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
calculateOrderTotal
|
|
5
5
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es6",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"outDir": "./dist",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"esModuleInterop": true
|
|
8
|
-
},
|
|
9
|
-
"include": ["src/**/*.ts"]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es6",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "./dist",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true
|
|
8
|
+
},
|
|
9
|
+
"include": ["src/**/*.ts"]
|
|
10
10
|
}
|