diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index 4a288ed..e72cfaa 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -1,5 +1,5 @@ import theme from "@theme"; -import { Button, Paper, Box, Typography, TableHead, TableRow, TableCell, TableBody, Table, Tooltip } from "@mui/material"; +import { Button, Paper, Box, Typography, TableHead, TableRow, TableCell, TableBody, Table, Tooltip, Alert } from "@mui/material"; import Input from "@kitUI/input"; import { useCartStore } from "@root/stores/cart"; import { useState } from "react"; @@ -10,17 +10,18 @@ import { calcCartData, createCartItem, findDiscountById, findDiscountFactor, for import { useTariffStore } from "@root/stores/tariffs"; import { AnyDiscount, CartItemTotal } from "@root/model/cart"; + interface Props { selectedTariffs: GridSelectionModel; } -// TODO реализовать правило "если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя" export default function Cart({ selectedTariffs }: Props) { const tariffs = useTariffStore(store => store.tariffs); const discounts = useDiscountStore(store => store.discounts); const cartTotal = useCartStore(state => state.cartTotal); const setCartTotal = useCartStore(store => store.setCartTotal); const [couponField, setCouponField] = useState(""); + const [errorMessage, setErrorMessage] = useState(null); // const [coupon, setCoupon] = useState(); const cartRows = cartTotal?.items.map(cartItemTotal => { @@ -38,7 +39,7 @@ export default function Cart({ selectedTariffs }: Props) { discount={discount} cartItemTotal={cartItemTotal} /> - {index < arr.length - (discount ? 0 : 1) && + {index < arr.length - (serviceDiscount ? 0 : 1) && } @@ -92,7 +93,15 @@ export default function Cart({ selectedTariffs }: Props) { function handleCalcCartClick() { const cartTariffs = tariffs.filter(tariff => selectedTariffs.includes(tariff.id)); const cartItems = cartTariffs.map(tariff => createCartItem(tariff)); - setCartTotal(calcCartData(testUser, cartItems, discounts, couponField)); + const cartData = calcCartData(testUser, cartItems, discounts, couponField); + + if (cartData instanceof Error) { + setErrorMessage(cartData.message); + return setCartTotal(null); + } + + setErrorMessage(null); + setCartTotal(cartData); } return ( @@ -103,7 +112,9 @@ export default function Cart({ selectedTariffs }: Props) { display: "flex", flexDirection: "column", alignItems: "center", - width: "100%" + width: "100%", + pb: "20px", + borderRadius: "4px", }} > @@ -146,86 +157,96 @@ export default function Cart({ selectedTariffs }: Props) { - - - - - Имя - - - Описание - - - Скидки - - - стоимость - - - - - {cartRows?.map(row => ( - 0 && + <> +
+ + - {row.tariffName} - {row.privilegeDesc} - {row.envolvedDiscounts} - {row.price.toFixed(2)} ₽ - - ))} - -
+ height: "100px" + }}> + + Имя + + + Описание + + + Скидки + + + стоимость + + + + + {cartRows?.map(row => ( + + {row.tariffName} + {row.privilegeDesc} + {row.envolvedDiscounts} + {row.price.toFixed(2)} ₽ + + ))} + + - - Скидки корзины: {envolvedCartDiscountsElement} - + + Скидки корзины: {envolvedCartDiscountsElement} + - - ИТОГО: {cartTotal?.totalPrice.toFixed(2)} ₽ - + + ИТОГО: {cartTotal?.totalPrice.toFixed(2)} ₽ + + + } + + {errorMessage !== null && + + {errorMessage} + + } ); diff --git a/src/kitUI/Cart/calc.test.ts b/src/kitUI/Cart/calc.test.ts index b182ad5..1451441 100644 --- a/src/kitUI/Cart/calc.test.ts +++ b/src/kitUI/Cart/calc.test.ts @@ -1,4 +1,4 @@ -import { CartItem } from "../../model/cart"; +import { CartItem, CartTotal } from "../../model/cart"; import { SERVICE_LIST, Tariff } from "../../model/tariff"; import { User } from "../../model/user"; import { exampleCartValues, TestCase } from "../../stores/mocks/exampleCartValues"; @@ -12,7 +12,7 @@ describe("cart tests", () => { it("без скидок", () => { const testCase = prepareTestCase(exampleCartValues.testCases[0]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -36,7 +36,7 @@ describe("cart tests", () => { ); }); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -60,7 +60,7 @@ describe("cart tests", () => { ); }); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -84,7 +84,7 @@ describe("cart tests", () => { ); }); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -108,7 +108,7 @@ describe("cart tests", () => { ); }); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discountsWithoutTemplategen) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -124,7 +124,7 @@ describe("cart tests", () => { it("история про то, как скидки за привилегии помешали получить скидку за сервис", () => { const testCase = prepareTestCase(exampleCartValues.testCases[5]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -140,7 +140,7 @@ describe("cart tests", () => { it("то же что и выше, но без лояльности", () => { const testCase = prepareTestCase(exampleCartValues.testCases[6]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -156,7 +156,7 @@ describe("cart tests", () => { it("история про то, как получилось получить скидку за сервис", () => { const testCase = prepareTestCase(exampleCartValues.testCases[7]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -172,7 +172,7 @@ describe("cart tests", () => { it("две скидки за сервис", () => { const testCase = prepareTestCase(exampleCartValues.testCases[8]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -188,7 +188,7 @@ describe("cart tests", () => { it("юзер использовал промокод id33. он заменяет скидку на p6 собой. в один момент времени может быть активирован только 1 промокод, т.е. после активации следующего, предыдущий заменяется. но в промокоде может быть несколько скидок. промокоды имеют скидки только на привелеги", () => { const testCase = prepareTestCase(exampleCartValues.testCases[9]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "ABCD"); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "ABCD") as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -204,7 +204,7 @@ describe("cart tests", () => { it("юзер подтвердил свой статус НКО, поэтому, не смотря на то что он достиг по лояльности уровня скидки id2, она не применилась, а применилась id32", () => { const testCase = prepareTestCase(exampleCartValues.testCases[10]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); @@ -220,7 +220,7 @@ describe("cart tests", () => { it("case 12", () => { const testCase = prepareTestCase(exampleCartValues.testCases[11]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts) as CartTotal; const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscountIds]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscountIds); diff --git a/src/kitUI/Cart/calc.ts b/src/kitUI/Cart/calc.ts index 889fcc8..a74a48f 100644 --- a/src/kitUI/Cart/calc.ts +++ b/src/kitUI/Cart/calc.ts @@ -8,7 +8,28 @@ export function calcCartData( cartItems: CartItem[], discounts: AnyDiscount[], coupon?: string, -): CartTotal { +): CartTotal | Error | null { + let isIncompatibleTariffs = false; + + const defaultTariffTypePresent: { [Key in ServiceType]: boolean } = { + dwarfener: false, + squiz: false, + templategen: false, + }; + + cartItems.forEach(cartItem => { + if (cartItem.tariff.customPricePerUnit === undefined) return defaultTariffTypePresent[cartItem.tariff.privilege.serviceKey] = true; + + if ( + defaultTariffTypePresent[cartItem.tariff.privilege.serviceKey] && + cartItem.tariff.customPricePerUnit !== undefined + ) isIncompatibleTariffs = true; + }); + + if (isIncompatibleTariffs) return new Error("Если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя"); + + if (!cartItems.length) return null; + const cartTotal: CartTotal = { items: [], totalPrice: 0, diff --git a/src/stores/cart.ts b/src/stores/cart.ts index 9673ca8..a0d7e69 100644 --- a/src/stores/cart.ts +++ b/src/stores/cart.ts @@ -5,7 +5,7 @@ import { CartTotal } from "@root/model/cart"; interface CartStore { cartTotal: CartTotal | null; - setCartTotal: (newCartTotal: CartTotal) => void; + setCartTotal: (newCartTotal: CartTotal | null) => void; } export const useCartStore = create()(