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