@jsdev_ninja/core 0.10.9 → 0.11.1
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/core.cjs.js +1 -1
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.es.js +38 -37
- package/dist/core.es.js.map +1 -1
- package/dist/core.umd.js +1 -1
- package/dist/core.umd.js.map +1 -1
- package/dist/entities/Cart.d.ts +550 -0
- package/dist/entities/Cart.d.ts.map +1 -1
- package/dist/entities/Cart.js +8 -4
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/utils/index.d.ts +111 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +149 -0
- package/lib/entities/Cart.ts +11 -6
- package/lib/entities/Order.ts +2 -1
- package/lib/utils/index.ts +205 -0
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { TCart, TDiscount, TStore } from "../entities";
|
|
2
|
+
export declare function getCartCost({ cart, discounts, store, }: {
|
|
3
|
+
cart: TCart["items"];
|
|
4
|
+
discounts: TDiscount[];
|
|
5
|
+
store: TStore;
|
|
6
|
+
}): {
|
|
7
|
+
discount: number;
|
|
8
|
+
cost: number;
|
|
9
|
+
finalCost: number;
|
|
10
|
+
vat: number;
|
|
11
|
+
items: {
|
|
12
|
+
amount: number;
|
|
13
|
+
product: {
|
|
14
|
+
type: "Product";
|
|
15
|
+
id: string;
|
|
16
|
+
companyId: string;
|
|
17
|
+
storeId: string;
|
|
18
|
+
objectID: string;
|
|
19
|
+
sku: string;
|
|
20
|
+
name: {
|
|
21
|
+
value: string;
|
|
22
|
+
lang: "he";
|
|
23
|
+
}[];
|
|
24
|
+
description: {
|
|
25
|
+
value: string;
|
|
26
|
+
lang: "he";
|
|
27
|
+
}[];
|
|
28
|
+
isPublished: boolean;
|
|
29
|
+
vat: boolean;
|
|
30
|
+
priceType: {
|
|
31
|
+
value: number;
|
|
32
|
+
type: "unit" | "kg" | "gram" | "liter" | "ml";
|
|
33
|
+
};
|
|
34
|
+
price: number;
|
|
35
|
+
currency: "ILS";
|
|
36
|
+
discount: {
|
|
37
|
+
value: number;
|
|
38
|
+
type: "number" | "percent" | "none";
|
|
39
|
+
};
|
|
40
|
+
weight: {
|
|
41
|
+
value: number;
|
|
42
|
+
unit: "kg" | "gram" | "none";
|
|
43
|
+
};
|
|
44
|
+
volume: {
|
|
45
|
+
value: number;
|
|
46
|
+
unit: "liter" | "ml" | "none";
|
|
47
|
+
};
|
|
48
|
+
images: {
|
|
49
|
+
id: string;
|
|
50
|
+
url: string;
|
|
51
|
+
}[];
|
|
52
|
+
manufacturer: string;
|
|
53
|
+
brand: string;
|
|
54
|
+
importer: string;
|
|
55
|
+
supplier: string;
|
|
56
|
+
ingredients: {
|
|
57
|
+
value: string;
|
|
58
|
+
lang: "he";
|
|
59
|
+
}[];
|
|
60
|
+
created_at: number;
|
|
61
|
+
updated_at: number;
|
|
62
|
+
categoryIds: string[];
|
|
63
|
+
categoryList: ({
|
|
64
|
+
id: string;
|
|
65
|
+
companyId: string;
|
|
66
|
+
storeId: string;
|
|
67
|
+
locales: {
|
|
68
|
+
value: string;
|
|
69
|
+
lang: "he";
|
|
70
|
+
}[];
|
|
71
|
+
depth: number;
|
|
72
|
+
parentId?: string | null | undefined;
|
|
73
|
+
tag?: string | undefined;
|
|
74
|
+
} & {
|
|
75
|
+
children: ({
|
|
76
|
+
id: string;
|
|
77
|
+
companyId: string;
|
|
78
|
+
storeId: string;
|
|
79
|
+
locales: {
|
|
80
|
+
value: string;
|
|
81
|
+
lang: "he";
|
|
82
|
+
}[];
|
|
83
|
+
depth: number;
|
|
84
|
+
parentId?: string | null | undefined;
|
|
85
|
+
tag?: string | undefined;
|
|
86
|
+
} & /*elided*/ any)[];
|
|
87
|
+
})[];
|
|
88
|
+
categories: {
|
|
89
|
+
lvl0: string[];
|
|
90
|
+
lvl1: string[];
|
|
91
|
+
lvl2: string[];
|
|
92
|
+
lvl3: string[];
|
|
93
|
+
lvl4: string[];
|
|
94
|
+
};
|
|
95
|
+
categoryNames: string[];
|
|
96
|
+
purchasePrice?: number | undefined;
|
|
97
|
+
profitPercentage?: number | undefined;
|
|
98
|
+
isDiscountable?: boolean | undefined;
|
|
99
|
+
};
|
|
100
|
+
originalPrice: number;
|
|
101
|
+
finalPrice: number;
|
|
102
|
+
finalDiscount: number;
|
|
103
|
+
}[];
|
|
104
|
+
};
|
|
105
|
+
export declare function calculateCartPrice(items: TCart["items"]): {
|
|
106
|
+
cost: number;
|
|
107
|
+
discount: number;
|
|
108
|
+
vat: number;
|
|
109
|
+
finalCost: number;
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAY,MAAM,EAAE,MAAM,aAAa,CAAC;AA6BjE,wBAAgB,WAAW,CAAC,EAC3B,IAAI,EACJ,SAAS,EACT,KAAK,GACL,EAAE;IACF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACrB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyIA;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;;;;;EA4BvD"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const CONFIG = {
|
|
2
|
+
VAT: 18,
|
|
3
|
+
};
|
|
4
|
+
function calculateDiscount(product) {
|
|
5
|
+
if (product.discount?.type === "percent") {
|
|
6
|
+
return (product.price * (product.discount.value ?? 100)) / 100;
|
|
7
|
+
}
|
|
8
|
+
if (product.discount?.type === "number") {
|
|
9
|
+
return product.price - (product.discount.value ?? 0);
|
|
10
|
+
}
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
function getPriceAfterDiscount(product) {
|
|
14
|
+
if (product.discount?.type === "percent") {
|
|
15
|
+
const dscountAmount = (product.price * product.discount.value) / 100;
|
|
16
|
+
return product.price - dscountAmount;
|
|
17
|
+
}
|
|
18
|
+
if (product.discount?.type === "number") {
|
|
19
|
+
const dscountAmount = product.price - product.discount.value;
|
|
20
|
+
return dscountAmount;
|
|
21
|
+
}
|
|
22
|
+
return product.price;
|
|
23
|
+
}
|
|
24
|
+
// main
|
|
25
|
+
export function getCartCost({ cart, discounts, store, }) {
|
|
26
|
+
const { isVatIncludedInPrice } = store;
|
|
27
|
+
let result = cart.map((item) => {
|
|
28
|
+
return {
|
|
29
|
+
amount: item.amount,
|
|
30
|
+
product: { ...item.product },
|
|
31
|
+
originalPrice: item.product.price,
|
|
32
|
+
finalPrice: item.product.price,
|
|
33
|
+
finalDiscount: 0,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const activeDiscounts = discounts.filter((discount) => {
|
|
37
|
+
if (discount.variant.variantType === "bundle") {
|
|
38
|
+
const productsTotal = cart?.reduce((total, item) => {
|
|
39
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
40
|
+
total += item.amount;
|
|
41
|
+
return total;
|
|
42
|
+
}
|
|
43
|
+
return total;
|
|
44
|
+
}, 0) ?? 0;
|
|
45
|
+
if (productsTotal >= discount.variant.requiredQuantity) {
|
|
46
|
+
// const times = Math.floor(productsTotal / discount.variant.requiredQuantity);
|
|
47
|
+
// console.log("yes", times, discount.variant.discountPrice);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
});
|
|
53
|
+
console.log("activeDiscounts", activeDiscounts);
|
|
54
|
+
activeDiscounts.forEach((discount) => {
|
|
55
|
+
if (discount.variant.variantType === "bundle") {
|
|
56
|
+
// get all products in cart
|
|
57
|
+
const products = cart.filter((item) => discount.variant.productsId.includes(item.product.id));
|
|
58
|
+
const productsTotal = products?.reduce((total, item) => {
|
|
59
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
60
|
+
total += item.amount;
|
|
61
|
+
return total;
|
|
62
|
+
}
|
|
63
|
+
return total;
|
|
64
|
+
}, 0) ?? 0;
|
|
65
|
+
const times = Math.floor(productsTotal / discount.variant.requiredQuantity);
|
|
66
|
+
const price = getPriceAfterDiscount(products[0]?.product);
|
|
67
|
+
const _discount = calculateDiscount(products[0]?.product);
|
|
68
|
+
console.log("price", price, _discount);
|
|
69
|
+
const discountPrice = Number((discount.variant.discountPrice / discount.variant.requiredQuantity).toFixed(2)) * 1;
|
|
70
|
+
console.log("discountPrice", discountPrice);
|
|
71
|
+
const totalDiscount = (price * discount.variant.requiredQuantity - discount.variant.discountPrice) * times;
|
|
72
|
+
const originalPrice = productsTotal * price;
|
|
73
|
+
const discountPriceFinal = originalPrice - totalDiscount;
|
|
74
|
+
console.log("totalDiscount", totalDiscount);
|
|
75
|
+
console.log("discountPriceFinal", discountPriceFinal, originalPrice);
|
|
76
|
+
const averagePrice = Number((discountPriceFinal / productsTotal).toFixed(2));
|
|
77
|
+
console.log("averagePrice", averagePrice);
|
|
78
|
+
result = result.map((item) => {
|
|
79
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
80
|
+
return {
|
|
81
|
+
...item,
|
|
82
|
+
finalPrice: averagePrice,
|
|
83
|
+
originalPrice: item.product.price,
|
|
84
|
+
finalDiscount: item.product.price - averagePrice,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return item;
|
|
88
|
+
});
|
|
89
|
+
console.log("averagePrice", averagePrice);
|
|
90
|
+
console.log("yes", times, discount.variant.requiredQuantity, discount.variant.discountPrice);
|
|
91
|
+
console.log("dis", productsTotal, products);
|
|
92
|
+
// find average price
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
console.log("result", result);
|
|
96
|
+
const cartDetails = result.reduce((acc, item) => {
|
|
97
|
+
const { product, amount, finalPrice, finalDiscount } = item;
|
|
98
|
+
console.log("isVatIncludedInPrice", isVatIncludedInPrice);
|
|
99
|
+
let productVatValue = 0;
|
|
100
|
+
if (product.vat) {
|
|
101
|
+
if (isVatIncludedInPrice) {
|
|
102
|
+
const vat_amount = finalPrice * (CONFIG.VAT / (100 + CONFIG.VAT));
|
|
103
|
+
productVatValue = Number(vat_amount.toFixed(2));
|
|
104
|
+
productVatValue = productVatValue * amount;
|
|
105
|
+
acc.vat += Number(productVatValue.toFixed(2));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
productVatValue = (finalPrice * CONFIG.VAT) / 100;
|
|
109
|
+
productVatValue = productVatValue * amount;
|
|
110
|
+
acc.vat += Number(productVatValue.toFixed(2));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
console.log("finalDiscount", finalDiscount);
|
|
114
|
+
acc.cost += amount * finalPrice;
|
|
115
|
+
acc.discount += finalDiscount ? amount * finalDiscount : finalDiscount;
|
|
116
|
+
acc.finalCost += amount * finalPrice + (isVatIncludedInPrice ? 0 : productVatValue);
|
|
117
|
+
return acc;
|
|
118
|
+
}, {
|
|
119
|
+
discount: 0,
|
|
120
|
+
cost: 0,
|
|
121
|
+
finalCost: 0,
|
|
122
|
+
vat: 0,
|
|
123
|
+
});
|
|
124
|
+
console.log("cartDetails", cartDetails);
|
|
125
|
+
return { items: result, ...cartDetails };
|
|
126
|
+
}
|
|
127
|
+
export function calculateCartPrice(items) {
|
|
128
|
+
return (items ?? []).reduce((acc, item) => {
|
|
129
|
+
const { product, amount } = item;
|
|
130
|
+
const productPrice = getPriceAfterDiscount(product);
|
|
131
|
+
const discount = calculateDiscount(product);
|
|
132
|
+
const realPrice = product.price - discount;
|
|
133
|
+
let productVatValue = 0;
|
|
134
|
+
if (product.vat) {
|
|
135
|
+
productVatValue = (realPrice * CONFIG.VAT) / 100;
|
|
136
|
+
productVatValue = productVatValue * amount;
|
|
137
|
+
acc.vat += productVatValue;
|
|
138
|
+
}
|
|
139
|
+
acc.cost += amount * product.price;
|
|
140
|
+
acc.discount += discount ? amount * discount : discount;
|
|
141
|
+
acc.finalCost += amount * productPrice + productVatValue;
|
|
142
|
+
return acc;
|
|
143
|
+
}, {
|
|
144
|
+
cost: 0,
|
|
145
|
+
discount: 0,
|
|
146
|
+
vat: 0,
|
|
147
|
+
finalCost: 0,
|
|
148
|
+
});
|
|
149
|
+
}
|
package/lib/entities/Cart.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { ProductSchema } from "./Product";
|
|
3
3
|
|
|
4
|
+
export const CartItemProductSchema = z.object({
|
|
5
|
+
product: ProductSchema,
|
|
6
|
+
originalPrice: z.number().optional(),
|
|
7
|
+
finalPrice: z.number().optional(),
|
|
8
|
+
finalDiscount: z.number().optional(),
|
|
9
|
+
amount: z.number().int().positive({ message: "Quantity must be a positive integer." }),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type TCartItemProduct = z.infer<typeof CartItemProductSchema>;
|
|
13
|
+
|
|
4
14
|
export const CartSchema = z.object({
|
|
5
15
|
type: z.literal("Cart"),
|
|
6
16
|
id: z.string().uuid(),
|
|
@@ -8,12 +18,7 @@ export const CartSchema = z.object({
|
|
|
8
18
|
storeId: z.string().uuid(),
|
|
9
19
|
userId: z.string().uuid(),
|
|
10
20
|
status: z.enum(["active", "draft", "completed"]),
|
|
11
|
-
items: z.array(
|
|
12
|
-
z.object({
|
|
13
|
-
product: ProductSchema,
|
|
14
|
-
amount: z.number().int().positive({ message: "Quantity must be a positive integer." }),
|
|
15
|
-
})
|
|
16
|
-
),
|
|
21
|
+
items: z.array(CartItemProductSchema),
|
|
17
22
|
});
|
|
18
23
|
|
|
19
24
|
export type TCart = z.infer<typeof CartSchema>;
|
package/lib/entities/Order.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { ProfileSchema } from "./Profile";
|
|
3
3
|
import { ProductSchema } from "./Product";
|
|
4
4
|
import { notEmptyTextSchema } from "./Atoms";
|
|
5
|
+
import { CartItemProductSchema } from "./Cart";
|
|
5
6
|
|
|
6
7
|
// pending - order created / by user
|
|
7
8
|
// processing order accepted by store by admin
|
|
@@ -30,7 +31,7 @@ export const OrderSchema = z.object({
|
|
|
30
31
|
paymentStatus: z.enum(["pending", "pending_j5", "completed", "failed", "refunded"]), //todo check if hyp support partial refund
|
|
31
32
|
cart: z.object({
|
|
32
33
|
id: z.string(),
|
|
33
|
-
items: z.array(
|
|
34
|
+
items: z.array(CartItemProductSchema),
|
|
34
35
|
cartDiscount: z.number(),
|
|
35
36
|
cartTotal: z.number(),
|
|
36
37
|
cartVat: z.number(),
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { TCart, TDiscount, TProduct, TStore } from "../entities";
|
|
2
|
+
|
|
3
|
+
const CONFIG = {
|
|
4
|
+
VAT: 18,
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
function calculateDiscount(product: TProduct) {
|
|
8
|
+
if (product.discount?.type === "percent") {
|
|
9
|
+
return (product.price * (product.discount.value ?? 100)) / 100;
|
|
10
|
+
}
|
|
11
|
+
if (product.discount?.type === "number") {
|
|
12
|
+
return product.price - (product.discount.value ?? 0);
|
|
13
|
+
}
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getPriceAfterDiscount(product: TProduct) {
|
|
18
|
+
if (product.discount?.type === "percent") {
|
|
19
|
+
const dscountAmount = (product.price * product.discount.value) / 100;
|
|
20
|
+
return product.price - dscountAmount;
|
|
21
|
+
}
|
|
22
|
+
if (product.discount?.type === "number") {
|
|
23
|
+
const dscountAmount = product.price - product.discount.value;
|
|
24
|
+
return dscountAmount;
|
|
25
|
+
}
|
|
26
|
+
return product.price;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// main
|
|
30
|
+
export function getCartCost({
|
|
31
|
+
cart,
|
|
32
|
+
discounts,
|
|
33
|
+
store,
|
|
34
|
+
}: {
|
|
35
|
+
cart: TCart["items"];
|
|
36
|
+
discounts: TDiscount[];
|
|
37
|
+
store: TStore;
|
|
38
|
+
}) {
|
|
39
|
+
const { isVatIncludedInPrice } = store;
|
|
40
|
+
let result = cart.map((item) => {
|
|
41
|
+
return {
|
|
42
|
+
amount: item.amount,
|
|
43
|
+
product: { ...item.product },
|
|
44
|
+
originalPrice: item.product.price,
|
|
45
|
+
finalPrice: item.product.price,
|
|
46
|
+
finalDiscount: 0,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const activeDiscounts = discounts.filter((discount) => {
|
|
51
|
+
if (discount.variant.variantType === "bundle") {
|
|
52
|
+
const productsTotal =
|
|
53
|
+
cart?.reduce((total, item) => {
|
|
54
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
55
|
+
total += item.amount;
|
|
56
|
+
return total;
|
|
57
|
+
}
|
|
58
|
+
return total;
|
|
59
|
+
}, 0) ?? 0;
|
|
60
|
+
if (productsTotal >= discount.variant.requiredQuantity) {
|
|
61
|
+
// const times = Math.floor(productsTotal / discount.variant.requiredQuantity);
|
|
62
|
+
// console.log("yes", times, discount.variant.discountPrice);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
});
|
|
68
|
+
console.log("activeDiscounts", activeDiscounts);
|
|
69
|
+
|
|
70
|
+
activeDiscounts.forEach((discount) => {
|
|
71
|
+
if (discount.variant.variantType === "bundle") {
|
|
72
|
+
// get all products in cart
|
|
73
|
+
const products = cart.filter((item) =>
|
|
74
|
+
discount.variant.productsId.includes(item.product.id)
|
|
75
|
+
);
|
|
76
|
+
const productsTotal =
|
|
77
|
+
products?.reduce((total, item) => {
|
|
78
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
79
|
+
total += item.amount;
|
|
80
|
+
return total;
|
|
81
|
+
}
|
|
82
|
+
return total;
|
|
83
|
+
}, 0) ?? 0;
|
|
84
|
+
|
|
85
|
+
const times = Math.floor(productsTotal / discount.variant.requiredQuantity);
|
|
86
|
+
const price = getPriceAfterDiscount(products[0]?.product);
|
|
87
|
+
const _discount = calculateDiscount(products[0]?.product);
|
|
88
|
+
console.log("price", price, _discount);
|
|
89
|
+
const discountPrice =
|
|
90
|
+
Number(
|
|
91
|
+
(discount.variant.discountPrice / discount.variant.requiredQuantity).toFixed(2)
|
|
92
|
+
) * 1;
|
|
93
|
+
|
|
94
|
+
console.log("discountPrice", discountPrice);
|
|
95
|
+
const totalDiscount =
|
|
96
|
+
(price * discount.variant.requiredQuantity - discount.variant.discountPrice) * times;
|
|
97
|
+
|
|
98
|
+
const originalPrice = productsTotal * price;
|
|
99
|
+
const discountPriceFinal = originalPrice - totalDiscount;
|
|
100
|
+
|
|
101
|
+
console.log("totalDiscount", totalDiscount);
|
|
102
|
+
|
|
103
|
+
console.log("discountPriceFinal", discountPriceFinal, originalPrice);
|
|
104
|
+
|
|
105
|
+
const averagePrice = Number((discountPriceFinal / productsTotal).toFixed(2));
|
|
106
|
+
console.log("averagePrice", averagePrice);
|
|
107
|
+
|
|
108
|
+
result = result.map((item) => {
|
|
109
|
+
if (discount.variant.productsId.includes(item.product.id)) {
|
|
110
|
+
return {
|
|
111
|
+
...item,
|
|
112
|
+
finalPrice: averagePrice,
|
|
113
|
+
originalPrice: item.product.price,
|
|
114
|
+
finalDiscount: item.product.price - averagePrice,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return item;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log("averagePrice", averagePrice);
|
|
121
|
+
|
|
122
|
+
console.log(
|
|
123
|
+
"yes",
|
|
124
|
+
times,
|
|
125
|
+
discount.variant.requiredQuantity,
|
|
126
|
+
discount.variant.discountPrice
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
console.log("dis", productsTotal, products);
|
|
130
|
+
|
|
131
|
+
// find average price
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
console.log("result", result);
|
|
136
|
+
|
|
137
|
+
const cartDetails = result.reduce(
|
|
138
|
+
(acc, item) => {
|
|
139
|
+
const { product, amount, finalPrice, finalDiscount } = item;
|
|
140
|
+
console.log("isVatIncludedInPrice", isVatIncludedInPrice);
|
|
141
|
+
|
|
142
|
+
let productVatValue: number = 0;
|
|
143
|
+
if (product.vat) {
|
|
144
|
+
if (isVatIncludedInPrice) {
|
|
145
|
+
const vat_amount = finalPrice * (CONFIG.VAT / (100 + CONFIG.VAT));
|
|
146
|
+
productVatValue = Number(vat_amount.toFixed(2));
|
|
147
|
+
productVatValue = productVatValue * amount;
|
|
148
|
+
|
|
149
|
+
acc.vat += Number(productVatValue.toFixed(2));
|
|
150
|
+
} else {
|
|
151
|
+
productVatValue = (finalPrice * CONFIG.VAT) / 100;
|
|
152
|
+
productVatValue = productVatValue * amount;
|
|
153
|
+
acc.vat += Number(productVatValue.toFixed(2));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
console.log("finalDiscount", finalDiscount);
|
|
157
|
+
|
|
158
|
+
acc.cost += amount * finalPrice;
|
|
159
|
+
acc.discount += finalDiscount ? amount * finalDiscount : finalDiscount;
|
|
160
|
+
acc.finalCost += amount * finalPrice + (isVatIncludedInPrice ? 0 : productVatValue);
|
|
161
|
+
|
|
162
|
+
return acc;
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
discount: 0,
|
|
166
|
+
cost: 0,
|
|
167
|
+
finalCost: 0,
|
|
168
|
+
vat: 0,
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
console.log("cartDetails", cartDetails);
|
|
173
|
+
|
|
174
|
+
return { items: result, ...cartDetails };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function calculateCartPrice(items: TCart["items"]) {
|
|
178
|
+
return (items ?? []).reduce(
|
|
179
|
+
(acc, item) => {
|
|
180
|
+
const { product, amount } = item;
|
|
181
|
+
const productPrice = getPriceAfterDiscount(product);
|
|
182
|
+
const discount = calculateDiscount(product);
|
|
183
|
+
|
|
184
|
+
const realPrice = product.price - discount;
|
|
185
|
+
|
|
186
|
+
let productVatValue: number = 0;
|
|
187
|
+
if (product.vat) {
|
|
188
|
+
productVatValue = (realPrice * CONFIG.VAT) / 100;
|
|
189
|
+
productVatValue = productVatValue * amount;
|
|
190
|
+
acc.vat += productVatValue;
|
|
191
|
+
}
|
|
192
|
+
acc.cost += amount * product.price;
|
|
193
|
+
acc.discount += discount ? amount * discount : discount;
|
|
194
|
+
acc.finalCost += amount * productPrice + productVatValue;
|
|
195
|
+
|
|
196
|
+
return acc;
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
cost: 0,
|
|
200
|
+
discount: 0,
|
|
201
|
+
vat: 0,
|
|
202
|
+
finalCost: 0,
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
}
|