From f6a6c54ae64001907678bc252a516e54d450d267 Mon Sep 17 00:00:00 2001 From: nflnkr Date: Wed, 8 Mar 2023 13:52:16 +0300 Subject: [PATCH] refactor --- src/kitUI/Cart/Cart.tsx | 44 +++++++++++++++++------ src/kitUI/Cart/calc.ts | 78 ++++++++++++++++++----------------------- src/model/cart.ts | 16 +++++---- 3 files changed, 77 insertions(+), 61 deletions(-) diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index ef64790..4a288ed 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -14,6 +14,7 @@ interface Props { selectedTariffs: GridSelectionModel; } +// TODO реализовать правило "если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя" export default function Cart({ selectedTariffs }: Props) { const tariffs = useTariffStore(store => store.tariffs); const discounts = useDiscountStore(store => store.discounts); @@ -23,29 +24,50 @@ export default function Cart({ selectedTariffs }: Props) { // const [coupon, setCoupon] = useState(); const cartRows = cartTotal?.items.map(cartItemTotal => { + const service = cartItemTotal.tariff.privilege.serviceKey; + const serviceDiscount = cartTotal.discountsByService[service]; + const envolvedDiscountsElement = ( - {cartItemTotal.envolvedDiscounts.map(discountId => ( - - ))} + {cartItemTotal.envolvedDiscountIds.map((discountId, index, arr) => { + const discount = findDiscountById(discounts, discountId); + + return ( + + + {index < arr.length - (discount ? 0 : 1) && + + } + + ); + })} + {serviceDiscount && + + + + } ); + const totalIncludingServiceDiscount = cartItemTotal.totalPrice * (serviceDiscount?.target.factor || 1); + return { id: cartItemTotal.tariff.id, tariffName: cartItemTotal.tariff.name, privilegeDesc: cartItemTotal.tariff.privilege.description, envolvedDiscounts: envolvedDiscountsElement, - price: cartItemTotal.totalPrice, + price: totalIncludingServiceDiscount, }; }); - - const cartDiscounts = cartTotal?.envolvedCartDiscounts.map(discountId => findDiscountById(discounts, discountId)); - const cartDiscountsResultFactor = cartDiscounts && 1 - cartDiscounts.reduce((acc, discount) => acc * findDiscountFactor(discount), 1); + + const cartDiscounts = cartTotal?.envolvedCartDiscountIds.map(discountId => findDiscountById(discounts, discountId)); + const cartDiscountsResultFactor = cartDiscounts && cartDiscounts.reduce((acc, discount) => acc * findDiscountFactor(discount), 1); const envolvedCartDiscountsElement = cartDiscounts && ( { cartTotal.items.push({ - envolvedDiscounts: [], + envolvedDiscountIds: [], tariff: cartItem.tariff, totalPrice: cartItem.price, }); - cartTotal.priceByService[cartItem.tariff.privilege.serviceKey].defaultTariffs += cartItem.price; + cartTotal.priceByService[cartItem.tariff.privilege.serviceKey] += cartItem.price; cartTotal.totalPrice += cartItem.price; }); cartTotal.totalPrice *= discount.target.factor; - cartTotal.envolvedCartDiscounts.push(discount._id); + cartTotal.envolvedCartDiscountIds.push(discount._id); return cartTotal; } @@ -56,7 +52,7 @@ export function calcCartData( for (const cartItem of cartItems) { const cartItemTotal: CartItemTotal = { tariff: cartItem.tariff, - envolvedDiscounts: [], + envolvedDiscountIds: [], totalPrice: cartItem.price, }; @@ -64,58 +60,52 @@ export function calcCartData( const privilegesAffectedByCoupon: string[] = []; 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); - } + if (product.privilegeId !== tariff.privilege.privilegeId) return; + if (tariff.customPricePerUnit !== undefined && !couponDiscount.overwhelm) return; + + cartItemTotal.totalPrice *= product.factor; + cartItemTotal.envolvedDiscountIds.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); - } + if (product.privilegeId !== tariff.privilege.privilegeId) return; + if (tariff.customPricePerUnit !== undefined) return; + if (privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)) return; + + cartItemTotal.totalPrice *= product.factor; + cartItemTotal.envolvedDiscountIds.push(privilegeDiscount._id); }); cartTotal.items.push(cartItemTotal); - if (tariff.customPricePerUnit === undefined) cartTotal.priceByService[tariff.privilege.serviceKey].defaultTariffs += cartItemTotal.totalPrice; - else cartTotal.priceByService[tariff.privilege.serviceKey].customTariffs += cartItemTotal.totalPrice; + cartTotal.priceByService[tariff.privilege.serviceKey] += cartItemTotal.totalPrice; } // layer 2 SERVICE_LIST.map(service => service.serviceKey).forEach(service => { const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal.priceByService); if (serviceDiscount) { - cartTotal.priceByService[service].defaultTariffs *= serviceDiscount.target.factor; - if (cartTotal.priceByService[service].defaultTariffs > 0) cartTotal.envolvedCartDiscounts.push(serviceDiscount._id); + cartTotal.priceByService[service] *= serviceDiscount.target.factor; + cartTotal.discountsByService[service] = serviceDiscount; } - cartTotal.totalPrice += cartTotal.priceByService[service].defaultTariffs; - cartTotal.totalPrice += cartTotal.priceByService[service].customTariffs; + cartTotal.totalPrice += cartTotal.priceByService[service]; }); // layer 3 const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal); if (cartPurchasesAmountDiscount) { cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor; - cartTotal.envolvedCartDiscounts.push(cartPurchasesAmountDiscount._id); + cartTotal.envolvedCartDiscountIds.push(cartPurchasesAmountDiscount._id); } // layer 4 const totalPurchasesAmountDiscount = findMaxTotalPurchasesAmountDiscount(discounts, user); if (totalPurchasesAmountDiscount) { cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor; - cartTotal.envolvedCartDiscounts.push(totalPurchasesAmountDiscount._id); + cartTotal.envolvedCartDiscountIds.push(totalPurchasesAmountDiscount._id); } return cartTotal; @@ -176,7 +166,7 @@ function findMaxServiceDiscount( return ( discount.conditionType === "service" && discount.condition.service.id === service && - priceByService[service].defaultTariffs + priceByService[service].customTariffs >= discount.condition.service.value + priceByService[service] >= discount.condition.service.value ); }); diff --git a/src/model/cart.ts b/src/model/cart.ts index 204dcb8..29e2242 100644 --- a/src/model/cart.ts +++ b/src/model/cart.ts @@ -119,21 +119,25 @@ export interface CartItem { /** Пункт корзины с уже примененными скидками */ export interface CartItemTotal { /** Массив с id примененных скидок */ - envolvedDiscounts: string[]; + envolvedDiscountIds: string[]; // TODO заменить на ссылки на скидки totalPrice: number; tariff: Tariff; } export type ServiceToPriceMap = { - [Key in ServiceType]: { - customTariffs: number; - defaultTariffs: number; - } + [Key in ServiceType]: number; +}; + +export type ServiceToDiscountMap = { + [Key in ServiceType]: ServiceDiscount | null; }; export interface CartTotal { items: CartItemTotal[]; totalPrice: number; priceByService: ServiceToPriceMap; - envolvedCartDiscounts: string[]; + /** Скидки по сервисам */ + discountsByService: ServiceToDiscountMap; + /** Учтенные скидки типов userType, cartPurchasesAmount, totalPurchasesAmount */ + envolvedCartDiscountIds: string[]; // TODO заменить на ссылки на скидки } \ No newline at end of file