diff --git a/src/pages/dashboard/Content/Tariffs/cartCalcs.ts b/src/pages/dashboard/Content/Tariffs/cartCalcs.ts index 40a4207..0cd54d4 100644 --- a/src/pages/dashboard/Content/Tariffs/cartCalcs.ts +++ b/src/pages/dashboard/Content/Tariffs/cartCalcs.ts @@ -1,5 +1,5 @@ import { Cart } from "../../../../model/cart"; -import { Tariffs } from "../../../../model/tariff"; +import { SERVICE_LIST, Tariffs } from "../../../../model/tariff"; import { User } from "../../../../model/user"; @@ -7,7 +7,7 @@ export function calcCartData( user: User, cartItems: Cart.CartItem[], discounts: Cart.AnyDiscount[], - privileges: Cart.Privilege[], + privileges: Tariffs.Privilege[], promocode?: Cart.Promocode, ): Cart.CartTotal { const cartTotal: Cart.CartTotal = { @@ -20,6 +20,9 @@ export function calcCartData( }, }; + debugger; + + // TODO layer 0 for (const discount of discounts) { if (discount.conditionType !== "userType" || discount.condition.userType !== user.Type) continue; @@ -35,6 +38,7 @@ export function calcCartData( return cartTotal; } + // TODO layer 1 if (promocode) { for (const discount of discounts) { if (discount.conditionType !== "user" || discount.condition.user !== user.ID || discount.condition.coupon !== promocode.name) continue; @@ -65,18 +69,7 @@ export function calcCartData( const tariff = cartItem.item; - const discountsForTariffService = discounts.filter((discount): discount is Cart.ServiceDiscount => ( - discount.conditionType === "service" && discount.condition.service.id === tariff.service - )); - const maxValueServiceDiscount = discountsForTariffService.reduce((prev, current) => { - return current.condition.service.value > prev.condition.service.value ? current : prev; - }); - - cartItemTotal.totalPrice *= maxValueServiceDiscount.target.factor; - cartItemTotal.envolvedDiscounts.push(maxValueServiceDiscount._id); - - - const maxPrivilegeDiscount = findMaxApplicablePrivilegeDiscount(tariff, discounts); + const maxPrivilegeDiscount = findMaxApplicablePrivilegeDiscount(discounts, tariff); if (maxPrivilegeDiscount) { maxPrivilegeDiscount.target.products.forEach(product => { if (product.productId === tariff.id) { // TODO productId - ид продукта(тариф или пакет тарифов) или привилегии? Если второе, то откуда берется привилегия? @@ -87,29 +80,91 @@ export function calcCartData( } cartTotal.items.push(cartItemTotal); - cartTotal.totalPrice += cartItemTotal.totalPrice; cartTotal.priceByService[tariff.service] += cartItemTotal.totalPrice; } + // layer 2 + SERVICE_LIST.forEach(service => { + const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal); + if (serviceDiscount) cartTotal.priceByService[service] *= serviceDiscount.target.factor; + + cartTotal.totalPrice += cartTotal.priceByService[service]; + }); + + // layer 3 + const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal); + if (cartPurchasesAmountDiscount) cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor; + + // layer 4 + const totalPurchasesAmountDiscount = findMaxPurchasesAmountDiscount(discounts, user); + if (totalPurchasesAmountDiscount) cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor; + return cartTotal; } -function findMaxApplicablePrivilegeDiscount( - tariff: Tariffs.Tariff, - discounts: Cart.AnyDiscount[], -): Cart.PrivilegeDiscount | null { - const applicablePrivilegeDiscounts = discounts.filter((discount): discount is Cart.PrivilegeDiscount => { +function findMaxApplicablePrivilegeDiscount(discounts: Cart.AnyDiscount[], tariff: Tariffs.Tariff): Cart.PrivilegeDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is Cart.PrivilegeDiscount => { return discount.conditionType === "privilege" && tariff.amount >= discount.condition.privilege.value; }); - if (!applicablePrivilegeDiscounts.length) return null; + if (!applicableDiscounts.length) return null; - const maxValueDiscount = applicablePrivilegeDiscounts.reduce( + const maxValueDiscount = applicableDiscounts.reduce( (prev, current) => current.condition.privilege.value > prev.condition.privilege.value ? current : prev ); return maxValueDiscount; -}; +} + +function findMaxCartPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], cartTotal: Cart.CartTotal): Cart.CartPurchasesAmountDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is Cart.CartPurchasesAmountDiscount => { + return discount.conditionType === "cartPurchasesAmount" && discount.condition.cartPurchasesAmount >= cartTotal.totalPrice; + }); + + if (!applicableDiscounts.length) return null; + + const maxValueDiscount = applicableDiscounts.reduce( + (prev, current) => current.condition.cartPurchasesAmount > prev.condition.cartPurchasesAmount ? current : prev + ); + + return maxValueDiscount; +} + +function findMaxPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], user: User): Cart.PurchasesAmountDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is Cart.PurchasesAmountDiscount => { + return discount.conditionType === "purchasesAmount" && discount.condition.purchasesAmount >= user.PurchasesAmount; + }); + + if (!applicableDiscounts.length) return null; + + const maxValueDiscount = applicableDiscounts.reduce( + (prev, current) => current.condition.purchasesAmount > prev.condition.purchasesAmount ? current : prev + ); + + return maxValueDiscount; +} + +function findMaxServiceDiscount( + service: Tariffs.ServiceType, + discounts: Cart.AnyDiscount[], + cartTotal: Cart.CartTotal +): Cart.ServiceDiscount | null { + const discountsForTariffService = discounts.filter((discount): discount is Cart.ServiceDiscount => { + return ( + discount.conditionType === "service" && + discount.condition.service.id === service && + discount.condition.service.value >= cartTotal.priceByService[service] + ); + }); + + if (!discountsForTariffService.length) return null; + + const maxValueDiscount = discountsForTariffService.reduce((prev, current) => { + return current.condition.service.value > prev.condition.service.value ? current : prev; + }); + + return maxValueDiscount; +} function calcCartItemWithPromocode( cartItem: Cart.CartItem, @@ -142,9 +197,7 @@ function calcCartItemWithPromocode( return cartItemTotal; } -export function packTariffs(tariffs: Tariffs.Tariff[]): Tariffs.Package { - const id = Date.now().toString(); // TODO actual id - const name = "Package"; // TODO actual name +export function packTariffs(tariffs: Tariffs.Tariff[], id: string, name: string): Tariffs.Package { const services: Tariffs.ServiceType[] = []; tariffs.forEach(tariff => { if (!services.includes(tariff.service)) services.push(tariff.service);