diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx new file mode 100644 index 0000000..bca1eae --- /dev/null +++ b/src/kitUI/Cart/Cart.tsx @@ -0,0 +1,230 @@ +import theme from "@theme"; +import { Button, Paper, Box, Typography, TableHead, TableRow, TableCell, TableBody, Table, Tooltip } from "@mui/material"; +import Input from "@kitUI/input"; +import { useCartStore } from "@root/stores/cart"; +import { useState } from "react"; +import { GridSelectionModel } from "@mui/x-data-grid"; +import { testUser } from "@root/stores/mocks/user"; +import { useDiscountStore } from "@root/stores/discounts"; +import { calcCartData, createCartItem, findDiscountById, findDiscountFactorById, formatDiscountFactor } from "./calc"; +import { useTariffStore } from "@root/stores/tariffs"; +import { AnyDiscount, CartItemTotal } from "@root/model/cart"; + +interface Props { + selectedTariffs: GridSelectionModel; +} + +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 [coupon, setCoupon] = useState(); + + const cartRows = cartTotal?.items.map(cartItemTotal => { + const envolvedDiscountsElement = ( + + {cartItemTotal.envolvedDiscounts.map(discountId => ( + + ))} + + ); + + return { + id: cartItemTotal.tariff.id, + tariffName: cartItemTotal.tariff.name, + privilegeDesc: cartItemTotal.tariff.privilege.description, + envolvedDiscounts: envolvedDiscountsElement, + price: cartItemTotal.totalPrice, + }; + }); + + const envolvedCartDiscountsElement = ( + + {cartTotal?.envolvedCartDiscounts.map((discountId, index, arr) => ( + + + {index < arr.length - 1 && + + } + + ))} + + ); + + function handleCalcCartClick() { + const cartTariffs = tariffs.filter(tariff => selectedTariffs.includes(tariff.id)); + const cartItems = cartTariffs.map(tariff => createCartItem(tariff)); + setCartTotal(calcCartData(testUser, cartItems, discounts, couponField)); + } + + return ( + + + корзина + + + + setCouponField(e.target.value)} + InputProps={{ + style: { + backgroundColor: theme.palette.content.main, + color: theme.palette.secondary.main, + } + }} + InputLabelProps={{ + style: { + color: theme.palette.secondary.main + } + }} + /> + {/* */} + + + + + + + + + Имя + + + Описание + + + Скидки + + + стоимость + + + + + {cartRows?.map(row => ( + + {row.tariffName} + {row.privilegeDesc} + {row.envolvedDiscounts} + {row.price.toFixed(2)} ₽ + + ))} + +
+ + + Скидки корзины: {envolvedCartDiscountsElement} + + + + ИТОГО: {cartTotal?.totalPrice.toFixed(2)} ₽ + + +
+ ); +} + +function DiscountTooltip({ discounts, discountId, cartItemTotal }: { + discounts: AnyDiscount[]; + discountId: string; + cartItemTotal?: CartItemTotal; +}) { + const discount = findDiscountById(discounts, discountId); + const discountText = formatDiscountFactor(findDiscountFactorById(discounts, discountId, cartItemTotal?.tariff.privilege.privilegeId)); + + return ( + + Скидка: {discount?.name} + {discount?.description} + ------- + layer: {discount?.layer} + id: {discount?._id} + + }> + {discountText} + + ); +} \ No newline at end of file diff --git a/src/pages/dashboard/Content/Tariffs/cartCalcs.test.ts b/src/kitUI/Cart/calc.test.ts similarity index 90% rename from src/pages/dashboard/Content/Tariffs/cartCalcs.test.ts rename to src/kitUI/Cart/calc.test.ts index af6bc37..1688f55 100644 --- a/src/pages/dashboard/Content/Tariffs/cartCalcs.test.ts +++ b/src/kitUI/Cart/calc.test.ts @@ -1,8 +1,8 @@ -import { Cart } from "../../../../model/cart"; -import { Tariffs } from "../../../../model/tariff"; -import { User } from "../../../../model/user"; -import { exampleCartValues, TestCase } from "../../../../stores/mocks/exampleCartValues"; -import { calcCartData } from "./cartCalcs"; + import { CartItem } from "@root/model/cart"; +import { Tariff } from "@root/model/tariff"; +import { User } from "@root/model/user"; +import { exampleCartValues, TestCase } from "@stores/mocks/exampleCartValues"; +import { calcCartData, createCartItem } from "./calc"; const MAX_PRICE_ERROR = 0.01; @@ -85,7 +85,7 @@ describe("cart tests", () => { expect(cartTotal.totalPrice).toBeGreaterThan(testCase.expect.price - MAX_PRICE_ERROR); expect(cartTotal.totalPrice).toBeLessThan(testCase.expect.price + MAX_PRICE_ERROR); }); - it("case 4", () => { + it("case 5", () => { const testCase = prepareTestCase(exampleCartValues.testCases[4]); // работает если не учитывать скидки id26, id27 (скидка на templategen от 1000/5000 р.) @@ -135,8 +135,6 @@ describe("cart tests", () => { it("история про то, как получилось получить скидку за сервис", () => { const testCase = prepareTestCase(exampleCartValues.testCases[7]); - // TODO Какая-то из скидок id30, id1 не учитывается в expected - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts]; cartTotal.items.forEach(cartItem => { @@ -163,7 +161,7 @@ describe("cart tests", () => { it("юзер использовал промокод id33. он заменяет скидку на p6 собой. в один момент времени может быть активирован только 1 промокод, т.е. после активации следующего, предыдущий заменяется. но в промокоде может быть несколько скидок. промокоды имеют скидки только на привелеги", () => { const testCase = prepareTestCase(exampleCartValues.testCases[9]); - const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "AB\\CD"); + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts, "ABCD"); const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts]; cartTotal.items.forEach(cartItem => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts); @@ -182,6 +180,19 @@ describe("cart tests", () => { allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts); }); + expect(allEnvolvedDiscounts.sort()).toEqual(testCase.expect.envolvedDiscounts.sort()); + expect(cartTotal.totalPrice).toBeGreaterThan(testCase.expect.price - MAX_PRICE_ERROR); + expect(cartTotal.totalPrice).toBeLessThan(testCase.expect.price + MAX_PRICE_ERROR); + }); + it("case 12", () => { + const testCase = prepareTestCase(exampleCartValues.testCases[11]); + + const cartTotal = calcCartData(testCase.user, testCase.cartItems, discounts); + const allEnvolvedDiscounts: string[] = [...cartTotal.envolvedCartDiscounts]; + cartTotal.items.forEach(cartItem => { + allEnvolvedDiscounts.push(...cartItem.envolvedDiscounts); + }); + expect(allEnvolvedDiscounts.sort()).toEqual(testCase.expect.envolvedDiscounts.sort()); expect(cartTotal.totalPrice).toBeGreaterThan(testCase.expect.price - MAX_PRICE_ERROR); expect(cartTotal.totalPrice).toBeLessThan(testCase.expect.price + MAX_PRICE_ERROR); @@ -195,15 +206,17 @@ function prepareTestCase(testCase: TestCase): ({ envolvedDiscounts: string[]; }; user: User; - cartItems: Cart.CartItem[]; + cartItems: CartItem[]; }) { const user = testCase.input.UserInformation; - const tariffs = testCase.input.Products.map((testProduct): Tariffs.Tariff => ({ + const tariffs = testCase.input.Products.map((testProduct): Tariff => ({ + id: "someId", + name: "someName", amount: testProduct.Amount, customPricePerUnit: testProduct.Price && testProduct.Price / testProduct.Amount, // приводим price из сниппета к pricePerUnit privilege: findPrivilegeById(testProduct.ID) })); - const cartItems: Cart.CartItem[] = tariffs.map(createCartItem); + const cartItems: CartItem[] = tariffs.map(createCartItem); return { expect: testCase.expect, user, cartItems }; } @@ -213,11 +226,4 @@ function findPrivilegeById(id: string) { if (!privilege) throw new Error(`Privilege not found with id ${id}`); return privilege; -} - -function createCartItem(tariff: Tariffs.Tariff): Cart.CartItem { - const pricePerUnit = tariff.customPricePerUnit ?? tariff.privilege.pricePerUnit; - const price = pricePerUnit * tariff.amount; - - return { tariff, price }; } \ No newline at end of file diff --git a/src/pages/dashboard/Content/Tariffs/cartCalcs.ts b/src/kitUI/Cart/calc.ts similarity index 65% rename from src/pages/dashboard/Content/Tariffs/cartCalcs.ts rename to src/kitUI/Cart/calc.ts index a0a4715..72c86a0 100644 --- a/src/pages/dashboard/Content/Tariffs/cartCalcs.ts +++ b/src/kitUI/Cart/calc.ts @@ -1,15 +1,15 @@ -import { Cart } from "../../../../model/cart"; -import { SERVICE_LIST, Tariffs } from "../../../../model/tariff"; -import { User } from "../../../../model/user"; +import { CartItem, AnyDiscount, CartTotal, CartItemTotal, PrivilegeDiscount, CartPurchasesAmountDiscount, PurchasesAmountDiscount, ServiceToPriceMap, ServiceDiscount, UserDiscount } from "@root/model/cart"; +import { ServiceType, SERVICE_LIST, Tariff } from "@root/model/tariff"; +import { User } from "@root/model/user"; export function calcCartData( user: User, - cartItems: Cart.CartItem[], - discounts: Cart.AnyDiscount[], + cartItems: CartItem[], + discounts: AnyDiscount[], coupon?: string, -): Cart.CartTotal { - const cartTotal: Cart.CartTotal = { +): CartTotal { + const cartTotal: CartTotal = { items: [], totalPrice: 0, priceByService: { @@ -54,7 +54,7 @@ export function calcCartData( // layer 1 for (const cartItem of cartItems) { - const cartItemTotal: Cart.CartItemTotal = { + const cartItemTotal: CartItemTotal = { tariff: cartItem.tariff, envolvedDiscounts: [], totalPrice: cartItem.price, @@ -93,11 +93,11 @@ export function calcCartData( } // layer 2 - SERVICE_LIST.forEach(service => { + SERVICE_LIST.map(service => service.serviceKey).forEach(service => { const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal.priceByService); if (serviceDiscount) { cartTotal.priceByService[service].defaultTariffs *= serviceDiscount.target.factor; - cartTotal.envolvedCartDiscounts.push(serviceDiscount._id); + if (cartTotal.priceByService[service].defaultTariffs > 0) cartTotal.envolvedCartDiscounts.push(serviceDiscount._id); } cartTotal.totalPrice += cartTotal.priceByService[service].defaultTariffs; @@ -121,8 +121,8 @@ export function calcCartData( return cartTotal; } -function findMaxApplicablePrivilegeDiscount(discounts: Cart.AnyDiscount[], tariff: Tariffs.Tariff): Cart.PrivilegeDiscount | null { - const applicableDiscounts = discounts.filter((discount): discount is Cart.PrivilegeDiscount => { +function findMaxApplicablePrivilegeDiscount(discounts: AnyDiscount[], tariff: Tariff): PrivilegeDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is PrivilegeDiscount => { return ( discount.conditionType === "privilege" && tariff.privilege.privilegeId === discount.condition.privilege.id && @@ -139,8 +139,8 @@ function findMaxApplicablePrivilegeDiscount(discounts: Cart.AnyDiscount[], tarif return maxValueDiscount; } -function findMaxCartPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], cartTotal: Cart.CartTotal): Cart.CartPurchasesAmountDiscount | null { - const applicableDiscounts = discounts.filter((discount): discount is Cart.CartPurchasesAmountDiscount => { +function findMaxCartPurchasesAmountDiscount(discounts: AnyDiscount[], cartTotal: CartTotal): CartPurchasesAmountDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is CartPurchasesAmountDiscount => { return discount.conditionType === "cartPurchasesAmount" && cartTotal.totalPrice >= discount.condition.cartPurchasesAmount; }); @@ -153,8 +153,8 @@ function findMaxCartPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], cartT return maxValueDiscount; } -function findMaxTotalPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], user: User): Cart.PurchasesAmountDiscount | null { - const applicableDiscounts = discounts.filter((discount): discount is Cart.PurchasesAmountDiscount => { +function findMaxTotalPurchasesAmountDiscount(discounts: AnyDiscount[], user: User): PurchasesAmountDiscount | null { + const applicableDiscounts = discounts.filter((discount): discount is PurchasesAmountDiscount => { return discount.conditionType === "purchasesAmount" && user.PurchasesAmount >= discount.condition.purchasesAmount; }); @@ -168,11 +168,11 @@ function findMaxTotalPurchasesAmountDiscount(discounts: Cart.AnyDiscount[], user } function findMaxServiceDiscount( - service: Tariffs.ServiceType, - discounts: Cart.AnyDiscount[], - priceByService: Cart.ServiceToPriceMap, -): Cart.ServiceDiscount | null { - const discountsForTariffService = discounts.filter((discount): discount is Cart.ServiceDiscount => { + service: ServiceType, + discounts: AnyDiscount[], + priceByService: ServiceToPriceMap, +): ServiceDiscount | null { + const discountsForTariffService = discounts.filter((discount): discount is ServiceDiscount => { return ( discount.conditionType === "service" && discount.condition.service.id === service && @@ -189,8 +189,8 @@ function findMaxServiceDiscount( return maxValueDiscount; } -function findUserDiscount(discounts: Cart.AnyDiscount[], user: User, coupon: string,): Cart.UserDiscount | null { - const userDiscount = discounts.find((discount): discount is Cart.UserDiscount => { +function findUserDiscount(discounts: AnyDiscount[], user: User, coupon: string,): UserDiscount | null { + const userDiscount = discounts.find((discount): discount is UserDiscount => { return ( discount.conditionType === "user" && discount.condition.user === user.ID && @@ -199,4 +199,57 @@ function findUserDiscount(discounts: Cart.AnyDiscount[], user: User, coupon: str }); return userDiscount ?? null; -} \ No newline at end of file +} + +export function createCartItem(tariff: Tariff): CartItem { + const pricePerUnit = tariff.customPricePerUnit ?? tariff.privilege.pricePerUnit; + const price = pricePerUnit * tariff.amount; + + 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 findDiscountFactorById(discounts: AnyDiscount[], id: string, privilegeId?: string) { + const discount = discounts.find(discount => discount._id === id); + if (!discount) throw new Error("Discount not found by id"); + + switch (discount.conditionType) { + case "cartPurchasesAmount" || "purchasesAmount": + return discount.factor; + case "privilege": { + const product = discount.target.products.find(product => product.privilegeId === privilegeId); + if (!product) throw new Error("Discount target product not found"); + + return product.factor; + } + case "user": { + const product = discount.target.products.find(product => product.privilegeId === privilegeId); + if (!product) throw new Error("Discount target product not found"); + + return product.factor; + } + case "service": + return discount.target.factor; + case "userType": + return discount.target.factor; + } + + throw new Error(`Unknown discount condition type: ${discount.conditionType}`); +} + +export function formatDiscountFactor(factor: number): string { + 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'; + } +}; diff --git a/src/kitUI/basket/calc.ts b/src/kitUI/basket/calc.ts deleted file mode 100644 index 7399f56..0000000 --- a/src/kitUI/basket/calc.ts +++ /dev/null @@ -1,87 +0,0 @@ -// export const setPromocode = (name: string) => { -// let codeNumber = -1; -// -// promocodeArray.forEach((item, i) => { -// if (name != "" && item.name == name) codeNumber = i; -// }); -// -// setSelectedPromocode(codeNumber); -// } - -export const PositiveInput = (event: any) => { - const numberInput = parseInt(event.target.value); - if (isNaN(numberInput) || numberInput < 0) { - event.target.value = '0' - } -} - -// export const calcPriseTariff () => { -// -// // считаем цену в ТАРИФАХ -// price = item.price; -// percents = 0; -// discounts = ""; -// -// // применяем скидки по промокоду -// if (selectedPromocode >= 0) { -// promocodeArray[selectedPromocode].privileges.forEach((privilege) => { -// console.log(item.service) -// console.log(privilege.good) -// if (item.service == privilege.good) { -// appliedDscnts.push(privilege.discount) -// price *= (1 - privilege.discount) -// } -// }) -// } else { -// // применяем активные скидки -// if (fitDiscounts.length >= 0) { -// fitDiscounts.forEach((activeDiscount) => { -// const discount = discountsArray[activeDiscount] -// discount.privileges.forEach((p) => { -// const svcName = item.service.split(' ')[0] -// if (p.good == svcName) { -// const summary = cartSummary.get(svcName) || { -// mbs: 0, -// points: 0, -// days: 0 -// } -// if (discount.toCapacity === 0 && discount.toTime === 0 && discount.basketMore === 0 && !(discount.incomeMore) || -// discount.toCapacity > 0 && summary.points > discount.toCapacity && item.points > 0 && discount.toTime == 0 -// || discount.toTime > 0 && summary.days > discount.toTime * 100 && item.time > 0 && discount.toCapacity == 0 || -// discount.toTime > 0 && discount.toCapacity > 0 && summary.days > discount.toTime * 100 && summary.points > discount.toCapacity) { -// -// price *= (1 - p.discount) -// appliedDscnts.push(p.discount) -// } -// -// -// } -// }) -// }); -// } -// -// } -// percents = Number(percents.toFixed(2)); -// -// priceBefore = price; -// price = price - (price * percents); -// prices += price; -// } -// -// // применяем активные скидки за объем корзины -// const discountsAfter = (priceBefore: number) => { -// const discounts: Array = []; -// -// -// if (fitDiscounts.length >= 0 && !nonCommercial && selectedPromocode < 0) { -// fitDiscounts.forEach((activeDiscount) => { -// const d = discountsArray[activeDiscount] -// console.log(d) -// console.log(fieldAddedValue) -// if (d.basketMore > 0 && getPrice > d.basketMore && d.basketMore === fitDiscounts.reduce((a, e) => Math.max(a, discountsArray[e].basketMore), 0) || -// d.incomeMore > 0 && parseInt(fieldAddedValue) > d.incomeMore) { -// prices *= (1 - d.privileges[0].discount) -// discounts.push(d.privileges[0].discount) -// } -// }); -// } \ No newline at end of file diff --git a/src/kitUI/basket/index.tsx b/src/kitUI/basket/index.tsx deleted file mode 100644 index c05fcca..0000000 --- a/src/kitUI/basket/index.tsx +++ /dev/null @@ -1,372 +0,0 @@ -import * as React from "react"; -import theme from "@theme"; -import {Button, Paper, ListItemText, IconButton, FormControlLabel, Box, TextField, Typography, Container, Checkbox, List, ListItem, ListItemAvatar, Avatar} from "@mui/material"; -import ShoppingCartIcon from "@mui/icons-material/ShoppingCart"; -import DeleteIcon from "@mui/icons-material/Delete"; -import Input from "@kitUI/input"; -import useStore, {StoreState} from "../../stores/store"; -import {useDemoData} from "@mui/x-data-grid-generator"; -import {GridSelectionModel} from "@mui/x-data-grid"; -import {ArrayProps} from "../../pages/dashboard/Content/Tariffs/types"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; -import TableCell from "@mui/material/TableCell"; -import TableBody from "@mui/material/TableBody"; -import Radio from "@mui/material/Radio"; -import Skeleton from "@mui/material/Skeleton"; -import Table from "@mui/material/Table"; - -export default (props:any):any => { - // const [added, setAdded] = React.useState(0) - // const [notCommercial, setNotCommercial] = React.useState(false) - // - // const setPromocode = (name: string) => { - // let codeNumber = -1; - // - // promocodeArray.forEach((item, i) => { - // if (name != "" && item.name == name) codeNumber = i; - // }); - // - // setSelectedPromocode(codeNumber); - // } - // - // const PositiveInput = (event: any) => { - // const numberInput = parseInt(event.target.value); - // if (isNaN(numberInput) || numberInput < 0) { - // event.target.value = '0' - // } - // } - // - // // const getData = localStorage.getItem("tariffs"); - // // const store = useStore( (state) => state ); - // // - // // if( getData && !store.tariffsArray.length ) { - // // const rows:Array = JSON.parse(getData); - // // if( rows.length ) { store.tariffsArraySet( rows ); }; - // // } - // let priceBefore = 0; - // let price = 0; - // let prices = 0; - // let percents = 0; - // let discounts = ""; - // let discountsSum = ""; - // - // const { discountsArray, discountsArraySet } = useStore((state) => state); - // const { discountsActiveArray, discountsActiveArraySet } = useStore((state) => state); - // - // const [nonCommercial, setNonCommercial] = React.useState(false); - // - // const { data } = useDemoData({ - // dataSet: "Commodity", - // rowLength: 10, - // maxColumns: 5, - // }); - // - // - // const { tariffsArray } = useStore((state) => state); - // const tariffsArrayConverted = tariffsArray.map( (item) => { - // if( item.type === "package" && item.tariffs ) { - // const result = item.tariffs.reduce( (acc, tariff) => { - // acc.service = acc.service? `${acc.service}, ${tariff.service}` : tariff.service; - // acc.disk = acc.disk+ tariff.disk; - // acc.time = acc.time+ tariff.time; - // acc.points = acc.points + tariff.points; - // acc.price = acc.price + tariff.price; - // - // return acc; - // }, { service: "", disk: "", time: "", points: "", price: 0 } ); - // - // return { id: item.id, name: item.name, type: item.type, ...result } - // } else { - // return item; - // } - // } ); - // - // const { tariffsSelectedRowsData, tariffsSelectedRowsDataSet } = useStore((state) => state); - // const onRowsSelectionHandler = ( ids:GridSelectionModel ) => { - // const result:Array = []; - // ids.forEach((id) => tariffsArray.forEach( (row) => { - // if(row.id === id) result.push(row); - // } ) ); - // - // tariffsSelectedRowsDataSet( result ); - // }; - // - // const { cartRowsData, cartRowsDataSet } = useStore((state) => state); - // const handleToBasket = () => { - // cartRowsDataSet( tariffsSelectedRowsData ); - // } - // - // const handleRemoveBasket = ( id:number ) => { - // const cartFiltered = cartRowsData.filter( (row) => row.id != id ); - // cartRowsDataSet( cartFiltered ); - // } - // - // const fieldPromocode = React.useRef(null); - // const checkPromocode = () => { - // if( fieldPromocode.current != null ) { - // setPromocode( fieldPromocode.current.value ); - // } - // } - // - // let { promocodeArray, promocodeArraySet } = useStore((state) => state); - // const [selectedPromocode, setSelectedPromocode] = React.useState( -1 ); - // - // //promocodeArray = [ ...rowz ]; - // - // const setPromocode = ( name:string ) => { - // let codeNumber = -1; - // - // promocodeArray.forEach( (item, i) => { - // if( name != "" && item.name == name ) codeNumber = i; - // } ); - // - // setSelectedPromocode( codeNumber ); - // } - // - // const PositiveInput = (event:any) => { - // const numberInput = parseInt(event.target.value); - // if(isNaN(numberInput) || numberInput < 0) {event.target.value = '0'} - // } - // - // const fieldAdded = React.useRef(null); - // const [ fieldAddedValue, setFieldAddedValue ] = React.useState(""); - // - // const changeAdded = (event:any) => { - // if( fieldAdded.current != null ) { - // if( fieldAdded.current.value != null ) { - // setFieldAddedValue( fieldAdded.current.value ); - // } - // - // } - // PositiveInput(event) - // }; - // - // const separator = (amount: number) => { - // console.log(amount) - // - // if( String(amount).length < 4 ) { return amount; } - // - // let result:Array = []; - // const arrs = String(amount).split('.') - // const arr = arrs[0].split('').reverse(); - // - // arr.forEach( (item, i:number) => { - // result.push( String( arr[ i ] ) ); - // if( ((i+1) / 3) - Math.round((i+1) / 3) == 0 ) result.push(" "); - // }); - // - // if( arrs.length > 1 ) { return result.reverse().join("") +"." +arrs[1]; } - // else { return result.reverse().join(""); } - // - // } - // - // - // const cartSummary = new Map() - // cartRowsData.forEach((row) => { - // const svcName = row.service.split(" ")[0] - // const prev = cartSummary.get(svcName) - // console.log(row) - // console.log(prev) - // if (!prev) { - // cartSummary.set(svcName, { - // mbs: row.disk, - // points: row.points, - // days: row.time, - // }) - // } else { - // cartSummary.set(svcName, { - // mbs: row.disk+prev.mbs, - // points: row.points+prev.points, - // days: row.time+prev.days, - // }) - // } - // }) - // console.log(cartSummary) - // - // const fitDiscounts = discountsActiveArray.filter(e => { - // const d = discountsArray[e] - // const summary = cartSummary.get(d.privileges[0].good.split(' ')[0]) - // return d.incomeMore*100 < parseInt(fieldAddedValue) && d.incomeMore > 0 || - // d.toTime < (summary ? summary.days : 0) && d.toTime > 0 && d.toCapacity === 0 || - // d.toCapacity > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime === 0 || - // d.toCapacity > 0 && d.toTime > 0 && d.toCapacity < (summary ? summary.points : 0) && d.toTime < (summary ? summary.days : 0) || - // !d.toCapacity && !d.toTime && !d.incomeMore && !d.basketMore || - // d.basketMore - // }).filter((e,i,a)=>{ - // const d = discountsArray[e] - // if (d.incomeMore) { - // return d.incomeMore === a.reduce((a, e) => Math.max(a, discountsArray[e].incomeMore || 0), 0 ) - // } - // if (d.toTime && d.toCapacity) { - // return d.toTime === a.reduce((a, e) => Math.max(a, (discountsArray[e].toTime && discountsArray[e].toCapacity) ? discountsArray[e].toTime:0 ), 0 ) && d.toCapacity === a.reduce((a, e) => Math.max(a, (discountsArray[e].toCapacity && discountsArray[e].toTime) ? discountsArray[e].toCapacity : 0 ), 0 ) - // } - // if (d.toTime && !d.toCapacity) { - // return d.toTime === a.reduce((a, e) => Math.max(a, discountsArray[e].toTime && !discountsArray[e].toCapacity ? discountsArray[e].toTime : 0), 0 ) - // } - // if (!d.toTime && d.toCapacity) { - // return d.toCapacity === a.reduce((a, e) => Math.max(a, discountsArray[e].toCapacity && !discountsArray[e].toTime ? discountsArray[e].toCapacity : 0), 0 ) - // } - // return true - // }) - // console.log(fitDiscounts) - // - // const discountsAfter = ( getPrice:number ) => { - // const discounts:Array = []; - // priceBefore = getPrice; - // - // prices = getPrice; - // console.log(getPrice) - // - // // применяем активные скидки за объем корзины - // - // if( fitDiscounts.length >= 0 && !nonCommercial && selectedPromocode < 0 ) { - // fitDiscounts.forEach( (activeDiscount) => { - // const d = discountsArray[activeDiscount] - // console.log(d) - // console.log(fieldAddedValue) - // if (d.basketMore > 0 && getPrice > d.basketMore && d.basketMore === fitDiscounts.reduce((a,e) => Math.max(a, discountsArray[e].basketMore), 0) || - // d.incomeMore > 0 && parseInt(fieldAddedValue) > d.incomeMore) { - // prices *= (1-d.privileges[0].discount) - // discounts.push(d.privileges[0].discount) - // } - // }); - // } - // - // if( nonCommercial ) { - // prices *= 0.2 - // return `80%`; - // } - // - // return discounts.map(e => `${(e*100).toFixed(2)}%`).join(' × ') + ` = ${(100 - discounts.reduce((a : number,cv : number) => a*(1-cv), 100)) .toFixed(2)}%`; - // } - - - return ( - - - корзина - - - - } - sx={{ - color: theme.palette.secondary.main, - }} - /> - ) => setAdded(Number(e.target.value))} - /> - - - - - - - - - {/**/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* Имя*/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* Описание*/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* стоимость*/} - {/* */} - {/* */} - {/* */} - {/* */} - - {/* */} - - - {/* */} - {/*
*/} - - - - Скидки: - - - - ИТОГО: - - -
- ) -} \ No newline at end of file diff --git a/src/pages/dashboard/Content/Tariffs/Cart.tsx b/src/pages/dashboard/Content/Tariffs/Cart.tsx deleted file mode 100644 index 294f6b0..0000000 --- a/src/pages/dashboard/Content/Tariffs/Cart.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import { Avatar, Box, Checkbox, FormControlLabel, IconButton, List, ListItem, ListItemAvatar, ListItemText, TextField, Typography, useTheme } from "@mui/material"; -import DeleteIcon from "@mui/icons-material/Delete"; -import { useMemo, useState } from "react"; -import { calcFitDiscounts, calcTotalAndRowData, separator } from "./utils"; -import type { CartSummary, Promocode } from "../../../../model/cart"; -import ShoppingCartIcon from "@mui/icons-material/ShoppingCart"; -import { useDiscountStore } from "../../../../stores/discounts"; -import { useCartStore } from "../../../../stores/cart"; - - -interface Props { - promocode?: Promocode; -} - -export default function Cart({ promocode }: Props) { - const theme = useTheme(); - const discountsArray = useDiscountStore(state => state.discountsArray); - const discountsActiveArray = useDiscountStore(state => state.discountsActiveArray); - const cartRowsData = useCartStore(state => state.cartRowsData); - const cartRowsDataSet = useCartStore(state => state.setCartRowsData); - const [isNonCommercial, setIsNonCommercial] = useState(false); - const [addedValueField, setAddedValueField] = useState(""); - - const cartSummary = useMemo(() => { - const cartSum: { [key: string]: CartSummary; } = {}; - cartRowsData.forEach((row) => { - const prev = cartSum[row.service]; - cartSum[row.service] = { - mbs: row.disk + (prev?.mbs || 0), - points: row.points + (prev?.points || 0), - days: row.time + (prev?.days || 0), - }; - }); - return cartSum; - }, [cartRowsData]); - - const fitDiscounts = useMemo(() => - calcFitDiscounts(discountsArray, discountsActiveArray, cartSummary, addedValueField), - [addedValueField, cartSummary, discountsActiveArray, discountsArray] - ); - - const { totalPrice, calculatedCartRowData } = useMemo(() => calcTotalAndRowData( - cartRowsData, - isNonCommercial, - discountsArray, - discountsActiveArray, - fitDiscounts, - addedValueField, - cartSummary, - promocode, - ), [addedValueField, cartRowsData, cartSummary, discountsActiveArray, discountsArray, fitDiscounts, isNonCommercial, promocode]); - - const { resultPrice, discountText } = useMemo(() => { - const discounts: Array = []; - - let resultPrice = totalPrice; - - if (isNonCommercial) { - resultPrice *= 0.2; - return { resultPrice, discountText: `80%` }; - } - - // применяем активные скидки за объем корзины - if (fitDiscounts.length >= 0 && !isNonCommercial && !promocode) { - fitDiscounts.forEach(activeDiscount => { - const discount = discountsArray[activeDiscount]; - if ((discount.basketMore > 0 && totalPrice > discount.basketMore && discount.basketMore === fitDiscounts.reduce((a, e) => Math.max(a, discountsArray[e].basketMore), 0)) || - (discount.incomeMore > 0 && parseInt(addedValueField) > discount.incomeMore)) { - resultPrice *= (1 - discount.privileges[0].discount); - discounts.push(discount.privileges[0].discount); - } - }); - } - - const discountText = discounts.map(e => `${(e * 100).toFixed(2)}%`).join(' × ') + ` = ${(100 - discounts.reduce((a: number, cv: number) => a * (1 - cv), 100)).toFixed(2)}%`; - - return { - resultPrice, - discountText, - }; - }, [addedValueField, discountsArray, fitDiscounts, isNonCommercial, promocode, totalPrice]); - - const handleRemoveBasket = (id: number) => cartRowsDataSet(cartRowsData.filter((row) => row.id !== id)); - - return ( - - - Корзина - - - - setIsNonCommercial(prev => !prev)} - />} - /> - - setAddedValueField(Number(e.target.value) >= 0 ? e.target.value : "")} - /> - - - - - - - - - - - - - {calculatedCartRowData.map((cartRow) => ( - - - - - - - - - (e * 100).toFixed(2)).join(' × '))} = ${(100 - cartRow.appliedDiscounts.reduce((a: number, cv: number) => a * (1 - cv), 100)).toFixed(2)}%`} - sx={{ textAlign: "center", maxWidth: "400px" }} - /> - handleRemoveBasket(cartRow.id)}> - - - - ))} - - - Скидки:   {discountText} - - - - ИТОГО:   {resultPrice} ₽ - - - - - ); -} \ No newline at end of file