fix logic

This commit is contained in:
nflnkr 2023-02-28 16:15:08 +03:00
parent f387ef7f7a
commit 0ebd3a55db

@ -7,84 +7,101 @@ export function calcCartData(
user: User,
cartItems: Cart.CartItem[],
discounts: Cart.AnyDiscount[],
promocode?: Cart.Promocode,
coupon?: string,
): Cart.CartTotal {
const cartTotal: Cart.CartTotal = {
items: [],
totalPrice: 0,
priceByService: {
templategen: 0,
squiz: 0,
dwarfener: 0,
templategen: {
defaultTariffs: 0,
customTariffs: 0,
},
squiz: {
defaultTariffs: 0,
customTariffs: 0,
},
dwarfener: {
defaultTariffs: 0,
customTariffs: 0,
},
},
envolvedCartDiscounts: [],
};
// TODO layer 0
// layer 0
for (const discount of discounts) {
if (discount.conditionType !== "userType" || discount.condition.userType !== user.Type) continue;
cartItems.forEach(cartItem => {
cartTotal.items.push({
envolvedDiscounts: [],
item: cartItem.item,
tariff: cartItem.tariff,
totalPrice: cartItem.price,
});
cartTotal.priceByService[cartItem.tariff.privilege.serviceKey].defaultTariffs += cartItem.price;
cartTotal.totalPrice += cartItem.price;
});
cartTotal.totalPrice *= discount.target.factor;
cartTotal.envolvedCartDiscounts.push(discount._id);
return cartTotal;
}
// TODO layer 1-user
if (promocode) {
for (const discount of discounts) {
if (discount.conditionType !== "user" || discount.condition.user !== user.ID || discount.condition.coupon !== promocode.name) continue;
const couponDiscount = coupon ? findUserDiscount(discounts, user, coupon) : null;
for (const cartItem of cartItems) {
const cartItemTotal = calcCartItemWithPromocode(cartItem, discount, cartTotal.priceByService);
cartTotal.items.push(cartItemTotal);
cartTotal.totalPrice += cartItemTotal.totalPrice;
}
return cartTotal;
}
}
// layer 1-privilege
// layer 1
for (const cartItem of cartItems) {
const cartItemTotal: Cart.CartItemTotal = {
item: cartItem.item,
tariff: cartItem.tariff,
envolvedDiscounts: [],
totalPrice: cartItem.price,
};
const tariff = cartItem.item;
const tariff = cartItem.tariff;
const privilegesAffectedByCoupon: string[] = [];
const maxPrivilegeDiscount = findMaxApplicablePrivilegeDiscount(discounts, tariff);
if (maxPrivilegeDiscount) {
maxPrivilegeDiscount.target.products.forEach(product => {
if (product.productId === tariff.privilege.privilegeId) {
cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscounts.push(maxPrivilegeDiscount._id);
}
});
}
couponDiscount?.target.products.forEach(product => {
if (
product.privilegeId === tariff.privilege.privilegeId &&
(tariff.customPricePerUnit === undefined || couponDiscount.overwhelm)
) {
cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscounts.push(couponDiscount._id);
privilegesAffectedByCoupon.push(product.privilegeId);
}
});
const privilegeDiscount = findMaxApplicablePrivilegeDiscount(discounts, tariff);
privilegeDiscount?.target.products.forEach(product => {
if (
product.privilegeId === tariff.privilege.privilegeId &&
tariff.customPricePerUnit === undefined &&
!privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)
) {
cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscounts.push(privilegeDiscount._id);
}
});
cartTotal.items.push(cartItemTotal);
cartTotal.priceByService[tariff.privilege.serviceKey] += cartItemTotal.totalPrice;
if (tariff.customPricePerUnit === undefined) cartTotal.priceByService[tariff.privilege.serviceKey].defaultTariffs += cartItemTotal.totalPrice;
else cartTotal.priceByService[tariff.privilege.serviceKey].customTariffs += cartItemTotal.totalPrice;
}
// layer 2
SERVICE_LIST.forEach(service => {
const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal);
const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal.priceByService);
if (serviceDiscount) {
cartTotal.priceByService[service] *= serviceDiscount.target.factor;
cartTotal.priceByService[service].defaultTariffs *= serviceDiscount.target.factor;
cartTotal.envolvedCartDiscounts.push(serviceDiscount._id);
}
cartTotal.totalPrice += cartTotal.priceByService[service];
cartTotal.totalPrice += cartTotal.priceByService[service].defaultTariffs;
cartTotal.totalPrice += cartTotal.priceByService[service].customTariffs;
});
// layer 3
@ -153,13 +170,13 @@ function findMaxTotalPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], user
function findMaxServiceDiscount(
service: Tariffs.ServiceType,
discounts: Cart.AnyDiscount[],
cartTotal: Cart.CartTotal
priceByService: Cart.ServiceToPriceMap,
): Cart.ServiceDiscount | null {
const discountsForTariffService = discounts.filter((discount): discount is Cart.ServiceDiscount => {
return (
discount.conditionType === "service" &&
discount.condition.service.id === service &&
cartTotal.priceByService[service] >= discount.condition.service.value
priceByService[service].defaultTariffs + priceByService[service].customTariffs >= discount.condition.service.value
);
});
@ -172,27 +189,14 @@ function findMaxServiceDiscount(
return maxValueDiscount;
}
function calcCartItemWithPromocode(
cartItem: Cart.CartItem,
discount: Cart.UserDiscount,
priceByService: { [Key in Tariffs.ServiceType]: number; },
): Cart.CartItemTotal {
const cartItemTotal: Cart.CartItemTotal = {
item: cartItem.item,
envolvedDiscounts: [],
totalPrice: 0,
};
const tariff = cartItem.item;
discount.target.products.forEach(product => {
if (product.productId === tariff.privilege.privilegeId) {
cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscounts.push(discount._id);
}
function findUserDiscount(discounts: Cart.AnyDiscount[], user: User, coupon: string,): Cart.UserDiscount | null {
const userDiscount = discounts.find((discount): discount is Cart.UserDiscount => {
return (
discount.conditionType === "user" &&
discount.condition.user === user.ID &&
discount.condition.coupon === coupon
);
});
priceByService[tariff.privilege.serviceKey] = cartItemTotal.totalPrice;
return cartItemTotal;
return userDiscount ?? null;
}