101 lines
3.6 KiB
TypeScript
101 lines
3.6 KiB
TypeScript
![]() |
import { CartData, Discount, PrivilegeCartData, Tariff, applyCartDiscount, applyLoyaltyDiscount, applyPrivilegeDiscounts, applyServiceDiscounts } from "@frontend/kitui";
|
||
|
|
||
|
|
||
|
export function calcCart(
|
||
|
tariffs: Tariff[],
|
||
|
discounts: Discount[],
|
||
|
purchasesAmount: number,
|
||
|
coupon?: string,
|
||
|
): CartData {
|
||
|
const cartData: CartData = {
|
||
|
services: [],
|
||
|
priceBeforeDiscounts: 0,
|
||
|
priceAfterDiscounts: 0,
|
||
|
itemCount: 0,
|
||
|
appliedCartPurchasesDiscount: null,
|
||
|
appliedLoyaltyDiscount: null,
|
||
|
allAppliedDiscounts: [],
|
||
|
};
|
||
|
|
||
|
const serviceHasNonCustomTariffMap: Record<string, boolean | undefined> = {};
|
||
|
|
||
|
tariffs.forEach(tariff => {
|
||
|
if (tariff.price && tariff.price > 0) cartData.priceBeforeDiscounts += tariff.price;
|
||
|
|
||
|
tariff.privilegies.forEach(privilege => {
|
||
|
if (
|
||
|
serviceHasNonCustomTariffMap[privilege.serviceKey] === true
|
||
|
&& tariff.isCustom
|
||
|
) throw new Error("Если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя");
|
||
|
|
||
|
let serviceData = cartData.services.find(service => service.serviceKey === privilege.serviceKey);
|
||
|
if (!serviceData) {
|
||
|
serviceData = {
|
||
|
serviceKey: privilege.serviceKey,
|
||
|
privileges: [],
|
||
|
price: 0,
|
||
|
appliedServiceDiscount: null,
|
||
|
};
|
||
|
cartData.services.push(serviceData);
|
||
|
}
|
||
|
|
||
|
const privilegePrice = privilege.amount * privilege.price;
|
||
|
|
||
|
if (!tariff.price) cartData.priceBeforeDiscounts += privilegePrice;
|
||
|
|
||
|
const privilegeData: PrivilegeCartData = {
|
||
|
tariffId: tariff._id,
|
||
|
serviceKey: privilege.serviceKey,
|
||
|
privilegeId: privilege.privilegeId,
|
||
|
description: privilege.description,
|
||
|
price: privilegePrice,
|
||
|
appliedPrivilegeDiscount: null,
|
||
|
tariffName: tariff.name,
|
||
|
};
|
||
|
|
||
|
serviceData.privileges.push(privilegeData);
|
||
|
serviceData.price += privilegePrice;
|
||
|
cartData.priceAfterDiscounts += privilegePrice;
|
||
|
cartData.itemCount++;
|
||
|
});
|
||
|
});
|
||
|
|
||
|
applyPrivilegeDiscounts(cartData, discounts);
|
||
|
applyServiceDiscounts(cartData, discounts);
|
||
|
applyCartDiscount(cartData, discounts);
|
||
|
applyLoyaltyDiscount(cartData, discounts, purchasesAmount);
|
||
|
|
||
|
cartData.allAppliedDiscounts = Array.from(new Set(cartData.allAppliedDiscounts));
|
||
|
|
||
|
return cartData;
|
||
|
}
|
||
|
|
||
|
export function findDiscountFactor(discount: Discount | null | undefined): number {
|
||
|
if (!discount) return 1;
|
||
|
|
||
|
if (discount.Condition.CartPurchasesAmount > 0) return Number(discount.Target.Factor);
|
||
|
|
||
|
if (discount.Condition.PurchasesAmount > 0) return Number(discount.Target.Factor);
|
||
|
|
||
|
if (discount.Condition.Product !== "") {
|
||
|
const product = discount.Target.Products[0];
|
||
|
if (!product) throw new Error("Discount target product not found");
|
||
|
return Number(product.Factor);
|
||
|
}
|
||
|
|
||
|
if ((discount.Condition.Group as string) !== "") return Number(discount.Target.Factor);
|
||
|
if (discount.Condition.UserType) return Number(discount.Target.Factor);
|
||
|
if (discount.Condition.User !== "") {
|
||
|
const product = discount.Target.Products[0];
|
||
|
if (!product) throw new Error("Discount target product not found");
|
||
|
|
||
|
return Number(product.Factor);
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
export function formatDiscountFactor(factor: number): string {
|
||
|
return `${((1 - factor) * 100).toFixed(1)}%`;
|
||
|
}
|