2023-08-02 11:36:50 +00:00
|
|
|
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: [],
|
|
|
|
};
|
|
|
|
|
2023-08-04 13:04:19 +00:00
|
|
|
const serviceTariffType: Record<string, number> = {};
|
2023-08-02 11:36:50 +00:00
|
|
|
|
|
|
|
tariffs.forEach(tariff => {
|
|
|
|
if (tariff.price && tariff.price > 0) cartData.priceBeforeDiscounts += tariff.price;
|
|
|
|
|
|
|
|
tariff.privilegies.forEach(privilege => {
|
2023-08-04 13:04:19 +00:00
|
|
|
serviceTariffType[privilege.serviceKey] ??= +tariff.isCustom;
|
|
|
|
const isIncompatibleTariffs = serviceTariffType[privilege.serviceKey] ^ +tariff.isCustom
|
|
|
|
if (isIncompatibleTariffs) throw new Error("Если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя");
|
2023-08-02 11:36:50 +00:00
|
|
|
|
|
|
|
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)}%`;
|
|
|
|
}
|