adminFront/src/utils/calcCart/calcCart.ts
2023-08-04 16:04:19 +03:00

100 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 serviceTariffType: Record<string, number> = {};
tariffs.forEach(tariff => {
if (tariff.price && tariff.price > 0) cartData.priceBeforeDiscounts += tariff.price;
tariff.privilegies.forEach(privilege => {
serviceTariffType[privilege.serviceKey] ??= +tariff.isCustom;
const isIncompatibleTariffs = serviceTariffType[privilege.serviceKey] ^ +tariff.isCustom
if (isIncompatibleTariffs) 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)}%`;
}