This commit is contained in:
nflnkr 2023-03-09 12:01:40 +03:00
parent 4a5f4f64ff
commit 378de99bff
4 changed files with 47 additions and 65 deletions

@ -6,7 +6,7 @@ import { useState } from "react";
import { GridSelectionModel } from "@mui/x-data-grid"; import { GridSelectionModel } from "@mui/x-data-grid";
import { testUser } from "@root/stores/mocks/user"; import { testUser } from "@root/stores/mocks/user";
import { useDiscountStore } from "@root/stores/discounts"; import { useDiscountStore } from "@root/stores/discounts";
import { calcCartData, createCartItem, findDiscountById, findDiscountFactor, formatDiscountFactor } from "./calc"; import { calcCartData, createCartItem, findDiscountFactor, formatDiscountFactor } from "./calc";
import { useTariffStore } from "@root/stores/tariffs"; import { useTariffStore } from "@root/stores/tariffs";
import { AnyDiscount, CartItemTotal } from "@root/model/cart"; import { AnyDiscount, CartItemTotal } from "@root/model/cart";
@ -30,10 +30,7 @@ export default function Cart({ selectedTariffs }: Props) {
const envolvedDiscountsElement = ( const envolvedDiscountsElement = (
<Box> <Box>
{cartItemTotal.envolvedDiscountIds.map((discountId, index, arr) => { {cartItemTotal.envolvedDiscounts.map((discount, index, arr) => (
const discount = findDiscountById(discounts, discountId);
return (
<span key={discount._id}> <span key={discount._id}>
<DiscountTooltip <DiscountTooltip
discount={discount} discount={discount}
@ -43,8 +40,7 @@ export default function Cart({ selectedTariffs }: Props) {
<span>,&nbsp;</span> <span>,&nbsp;</span>
} }
</span> </span>
); ))}
})}
{serviceDiscount && {serviceDiscount &&
<span> <span>
<DiscountTooltip <DiscountTooltip
@ -67,7 +63,7 @@ export default function Cart({ selectedTariffs }: Props) {
}; };
}); });
const cartDiscounts = cartTotal?.envolvedCartDiscountIds.map(discountId => findDiscountById(discounts, discountId)); const cartDiscounts = cartTotal?.envolvedCartDiscounts
const cartDiscountsResultFactor = cartDiscounts && cartDiscounts.reduce((acc, discount) => acc * findDiscountFactor(discount), 1); const cartDiscountsResultFactor = cartDiscounts && cartDiscounts.reduce((acc, discount) => acc * findDiscountFactor(discount), 1);
const envolvedCartDiscountsElement = cartDiscounts && ( const envolvedCartDiscountsElement = cartDiscounts && (

@ -13,9 +13,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[0]); const testCase = prepareTestCase(exampleCartValues.testCases[0]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -37,9 +37,9 @@ describe("cart tests", () => {
}); });
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -61,9 +61,9 @@ describe("cart tests", () => {
}); });
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -85,9 +85,9 @@ describe("cart tests", () => {
}); });
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -109,9 +109,9 @@ describe("cart tests", () => {
}); });
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -125,9 +125,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[5]); const testCase = prepareTestCase(exampleCartValues.testCases[5]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -141,9 +141,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[6]); const testCase = prepareTestCase(exampleCartValues.testCases[6]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -157,9 +157,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[7]); const testCase = prepareTestCase(exampleCartValues.testCases[7]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -173,9 +173,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[8]); const testCase = prepareTestCase(exampleCartValues.testCases[8]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -189,9 +189,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[9]); const testCase = prepareTestCase(exampleCartValues.testCases[9]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "ABCD") as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "ABCD") as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -205,9 +205,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[10]); const testCase = prepareTestCase(exampleCartValues.testCases[10]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);
@ -221,9 +221,9 @@ describe("cart tests", () => {
const testCase = prepareTestCase(exampleCartValues.testCases[11]); const testCase = prepareTestCase(exampleCartValues.testCases[11]);
const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal;
const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts.map(discount => discount._id)];
cartTotal.items.forEach(cartItem => { cartTotal.items.forEach(cartItem => {
allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts.map(discount => discount._id));
}); });
SERVICE_LIST.map(service => service.serviceKey).forEach(service => { SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id); if (cartTotal.discountsByService[service]) allEnvolvedDiscounts.push(cartTotal.discountsByService[service]!._id);

@ -43,7 +43,7 @@ export function calcCartData(
squiz: null, squiz: null,
dwarfener: null, dwarfener: null,
}, },
envolvedCartDiscountIds: [], envolvedCartDiscounts: [],
}; };
// layer 0 // layer 0
@ -52,7 +52,7 @@ export function calcCartData(
cartItems.forEach(cartItem => { cartItems.forEach(cartItem => {
cartTotal.items.push({ cartTotal.items.push({
envolvedDiscountIds: [], envolvedDiscounts: [],
tariff: cartItem.tariff, tariff: cartItem.tariff,
totalPrice: cartItem.price, totalPrice: cartItem.price,
}); });
@ -62,7 +62,7 @@ export function calcCartData(
}); });
cartTotal.totalPrice *= discount.target.factor; cartTotal.totalPrice *= discount.target.factor;
cartTotal.envolvedCartDiscountIds.push(discount._id); cartTotal.envolvedCartDiscounts.push(discount);
return cartTotal; return cartTotal;
} }
@ -73,7 +73,7 @@ export function calcCartData(
for (const cartItem of cartItems) { for (const cartItem of cartItems) {
const cartItemTotal: CartItemTotal = { const cartItemTotal: CartItemTotal = {
tariff: cartItem.tariff, tariff: cartItem.tariff,
envolvedDiscountIds: [], envolvedDiscounts: [],
totalPrice: cartItem.price, totalPrice: cartItem.price,
}; };
@ -85,7 +85,7 @@ export function calcCartData(
if (tariff.customPricePerUnit !== undefined && !couponDiscount.overwhelm) return; if (tariff.customPricePerUnit !== undefined && !couponDiscount.overwhelm) return;
cartItemTotal.totalPrice *= product.factor; cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscountIds.push(couponDiscount._id); cartItemTotal.envolvedDiscounts.push(couponDiscount);
privilegesAffectedByCoupon.push(product.privilegeId); privilegesAffectedByCoupon.push(product.privilegeId);
}); });
@ -97,7 +97,7 @@ export function calcCartData(
if (privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)) return; if (privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)) return;
cartItemTotal.totalPrice *= product.factor; cartItemTotal.totalPrice *= product.factor;
cartItemTotal.envolvedDiscountIds.push(privilegeDiscount._id); cartItemTotal.envolvedDiscounts.push(privilegeDiscount);
}); });
cartTotal.items.push(cartItemTotal); cartTotal.items.push(cartItemTotal);
@ -119,14 +119,14 @@ export function calcCartData(
const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal); const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal);
if (cartPurchasesAmountDiscount) { if (cartPurchasesAmountDiscount) {
cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor; cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor;
cartTotal.envolvedCartDiscountIds.push(cartPurchasesAmountDiscount._id); cartTotal.envolvedCartDiscounts.push(cartPurchasesAmountDiscount);
} }
// layer 4 // layer 4
const totalPurchasesAmountDiscount = findMaxTotalPurchasesAmountDiscount(discounts, user); const totalPurchasesAmountDiscount = findMaxTotalPurchasesAmountDiscount(discounts, user);
if (totalPurchasesAmountDiscount) { if (totalPurchasesAmountDiscount) {
cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor; cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor;
cartTotal.envolvedCartDiscountIds.push(totalPurchasesAmountDiscount._id); cartTotal.envolvedCartDiscounts.push(totalPurchasesAmountDiscount);
} }
return cartTotal; return cartTotal;
@ -219,13 +219,6 @@ export function createCartItem(tariff: Tariff): CartItem {
return { tariff, price, id: "someId" }; return { tariff, price, id: "someId" };
} }
export function findDiscountById(discounts: AnyDiscount[], id: string) {
const discount = discounts.find(discount => discount._id === id);
if (!discount) throw new Error("Discount not found by id");
return discount;
}
export function findDiscountFactor(discount: AnyDiscount, privilegeId?: string) { export function findDiscountFactor(discount: AnyDiscount, privilegeId?: string) {
switch (discount.conditionType) { switch (discount.conditionType) {
case "cartPurchasesAmount": case "cartPurchasesAmount":
@ -254,10 +247,3 @@ export function findDiscountFactor(discount: AnyDiscount, privilegeId?: string)
export function formatDiscountFactor(factor: number): string { export function formatDiscountFactor(factor: number): string {
return `${((1 - factor) * 100).toFixed(1)}%`; return `${((1 - factor) * 100).toFixed(1)}%`;
} }
export const PositiveInput = (event: any) => {
const numberInput = parseInt(event.target.value);
if (isNaN(numberInput) || numberInput < 0) {
event.target.value = '0';
}
};

@ -119,7 +119,7 @@ export interface CartItem {
/** Пункт корзины с уже примененными скидками */ /** Пункт корзины с уже примененными скидками */
export interface CartItemTotal { export interface CartItemTotal {
/** Массив с id примененных скидок */ /** Массив с id примененных скидок */
envolvedDiscountIds: string[]; // TODO заменить на ссылки на скидки envolvedDiscounts: (PrivilegeDiscount | UserDiscount)[];
totalPrice: number; totalPrice: number;
tariff: Tariff; tariff: Tariff;
} }
@ -139,5 +139,5 @@ export interface CartTotal {
/** Скидки по сервисам */ /** Скидки по сервисам */
discountsByService: ServiceToDiscountMap; discountsByService: ServiceToDiscountMap;
/** Учтенные скидки типов userType, cartPurchasesAmount, totalPurchasesAmount */ /** Учтенные скидки типов userType, cartPurchasesAmount, totalPurchasesAmount */
envolvedCartDiscountIds: string[]; // TODO заменить на ссылки на скидки envolvedCartDiscounts: (UserTypeDiscount | CartPurchasesAmountDiscount | PurchasesAmountDiscount)[];
} }