add discount de/activation
This commit is contained in:
parent
ae632f6edf
commit
2084b5619c
@ -95,11 +95,13 @@ export default function Cart({ selectedTariffs }: Props) {
|
|||||||
|
|
||||||
if (!isFinite(loyaltyValue)) loyaltyValue = 0;
|
if (!isFinite(loyaltyValue)) loyaltyValue = 0;
|
||||||
|
|
||||||
|
const activeDiscounts = discounts.filter(discount => !discount.disabled);
|
||||||
|
|
||||||
const cartData = calcCartData({
|
const cartData = calcCartData({
|
||||||
user: testUser,
|
user: testUser,
|
||||||
purchasesAmount: loyaltyValue,
|
purchasesAmount: loyaltyValue,
|
||||||
cartItems,
|
cartItems,
|
||||||
discounts,
|
discounts: activeDiscounts,
|
||||||
isNonCommercial,
|
isNonCommercial,
|
||||||
coupon: couponField,
|
coupon: couponField,
|
||||||
});
|
});
|
||||||
@ -316,7 +318,7 @@ function DiscountTooltip({ discount, cartItemTotal }: {
|
|||||||
discount: AnyDiscount;
|
discount: AnyDiscount;
|
||||||
cartItemTotal?: CartItemTotal;
|
cartItemTotal?: CartItemTotal;
|
||||||
}) {
|
}) {
|
||||||
const discountText = formatDiscountFactor(findDiscountFactor(discount, cartItemTotal?.tariff.privilege.privilegeId));
|
const discountText = formatDiscountFactor(findDiscountFactor(discount));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={
|
<Tooltip title={
|
||||||
|
@ -223,20 +223,20 @@ export function createCartItem(tariff: Tariff): CartItem {
|
|||||||
return { tariff, price, id: "someId" };
|
return { tariff, price, id: "someId" };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findDiscountFactor(discount: AnyDiscount, privilegeId?: string) {
|
export function findDiscountFactor(discount: AnyDiscount): number {
|
||||||
switch (discount.conditionType) {
|
switch (discount.conditionType) {
|
||||||
case "cartPurchasesAmount":
|
case "cartPurchasesAmount":
|
||||||
return discount.factor;
|
return discount.factor;
|
||||||
case "purchasesAmount":
|
case "purchasesAmount":
|
||||||
return discount.factor;
|
return discount.factor;
|
||||||
case "privilege": {
|
case "privilege": {
|
||||||
const product = discount.target.products.find(product => product.privilegeId === privilegeId);
|
const product = discount.target.products[0];
|
||||||
if (!product) throw new Error("Discount target product not found");
|
if (!product) throw new Error("Discount target product not found");
|
||||||
|
|
||||||
return product.factor;
|
return product.factor;
|
||||||
}
|
}
|
||||||
case "user": {
|
case "user": {
|
||||||
const product = discount.target.products.find(product => product.privilegeId === privilegeId);
|
const product = discount.target.products[0];
|
||||||
if (!product) throw new Error("Discount target product not found");
|
if (!product) throw new Error("Discount target product not found");
|
||||||
|
|
||||||
return product.factor;
|
return product.factor;
|
||||||
|
@ -7,6 +7,7 @@ interface DiscountBase {
|
|||||||
description: string;
|
description: string;
|
||||||
/** Этап применения скидки */
|
/** Этап применения скидки */
|
||||||
layer: number;
|
layer: number;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PurchasesAmountDiscount extends DiscountBase {
|
export interface PurchasesAmountDiscount extends DiscountBase {
|
||||||
|
@ -13,10 +13,11 @@ import MenuItem from "@mui/material/MenuItem";
|
|||||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
import theme from "../../../theme";
|
import theme from "../../../theme";
|
||||||
import { styled } from "@mui/material/styles";
|
import { styled } from "@mui/material/styles";
|
||||||
import { useDiscountStore } from "../../../stores/discounts";
|
import { activateDiscounts, deactivateDiscounts, setSelectedDiscountIds, useDiscountStore } from "../../../stores/discounts";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { DiscountConditionType } from "@root/model/cart";
|
import { DiscountConditionType } from "@root/model/cart";
|
||||||
import { ServiceType } from "@root/model/tariff";
|
import { ServiceType } from "@root/model/tariff";
|
||||||
|
import { findDiscountFactor, formatDiscountFactor } from "@root/kitUI/Cart/calc";
|
||||||
|
|
||||||
|
|
||||||
const BoxButton = styled('div')(({ theme }) => ({
|
const BoxButton = styled('div')(({ theme }) => ({
|
||||||
@ -27,56 +28,6 @@ const BoxButton = styled('div')(({ theme }) => ({
|
|||||||
|
|
||||||
|
|
||||||
const columns: GridColDef[] = [
|
const columns: GridColDef[] = [
|
||||||
// {
|
|
||||||
// field: "endless",
|
|
||||||
// headerName: "Бесконечная",
|
|
||||||
// width: 120,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: "from",
|
|
||||||
// headerName: "От",
|
|
||||||
// width: 120,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: "dueTo",
|
|
||||||
// headerName: "До",
|
|
||||||
// width: 120,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: "privileges",
|
|
||||||
// headerName: "Привилегии",
|
|
||||||
// width: 210,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: "active",
|
|
||||||
// headerName: "Активна",
|
|
||||||
// width: 100,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: "basketMore",
|
|
||||||
// headerName: "Корзина больше",
|
|
||||||
// width: 140,
|
|
||||||
// sortable: false,
|
|
||||||
// }
|
|
||||||
// ,
|
|
||||||
// {
|
|
||||||
// field: "toTime",
|
|
||||||
// headerName: "На время",
|
|
||||||
// width: 140,
|
|
||||||
// sortable: false,
|
|
||||||
// }
|
|
||||||
// ,
|
|
||||||
// {
|
|
||||||
// field: "toCapacity",
|
|
||||||
// headerName: "На объем",
|
|
||||||
// width: 140,
|
|
||||||
// sortable: false,
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
field: "id",
|
field: "id",
|
||||||
headerName: "ID",
|
headerName: "ID",
|
||||||
@ -101,11 +52,24 @@ const columns: GridColDef[] = [
|
|||||||
width: 120,
|
width: 120,
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: "factor",
|
||||||
|
headerName: "Процент скидки",
|
||||||
|
width: 120,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "active",
|
||||||
|
headerName: "Активна",
|
||||||
|
width: 120,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const DiscountManagement: React.FC = () => {
|
const DiscountManagement: React.FC = () => {
|
||||||
const discounts = useDiscountStore(state => state.discounts);
|
const discounts = useDiscountStore(state => state.discounts);
|
||||||
|
const selectedDiscountIds = useDiscountStore(state => state.selectedDiscountIds);
|
||||||
const [isInfinite, setIsInfinite] = useState<boolean>(false);
|
const [isInfinite, setIsInfinite] = useState<boolean>(false);
|
||||||
const [serviceType, setServiceType] = useState<ServiceType>("templategen");
|
const [serviceType, setServiceType] = useState<ServiceType>("templategen");
|
||||||
const [startDate, setStartDate] = useState<Date>(new Date());
|
const [startDate, setStartDate] = useState<Date>(new Date());
|
||||||
@ -127,14 +91,6 @@ const DiscountManagement: React.FC = () => {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateDiscounts() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
function deactivateDiscounts() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// const discountsArrayConverted = discounts.map((item) => {
|
// const discountsArrayConverted = discounts.map((item) => {
|
||||||
// const basketMorePerc = Math.round(Number(item.basketMore) * 100) + "%";
|
// const basketMorePerc = Math.round(Number(item.basketMore) * 100) + "%";
|
||||||
// const toTimePerc = Math.round(Number(item.toTime) * 100) + "%";
|
// const toTimePerc = Math.round(Number(item.toTime) * 100) + "%";
|
||||||
@ -173,16 +129,16 @@ const DiscountManagement: React.FC = () => {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
const discountsGridData: GridRowsProp = discounts.map(discount => {
|
const discountsGridData: GridRowsProp = discounts.map(discount => {
|
||||||
return { // TODO
|
return {
|
||||||
id: discount._id,
|
id: discount._id,
|
||||||
name: discount.name,
|
name: discount.name,
|
||||||
description: discount.description,
|
description: discount.description,
|
||||||
conditionType: discount.conditionType,
|
conditionType: discount.conditionType,
|
||||||
|
factor: formatDiscountFactor(findDiscountFactor(discount)),
|
||||||
|
active: discount.disabled ? "🚫" : "✅",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(discountsGridData);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
@ -263,10 +219,9 @@ const DiscountManagement: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem value={"Шаблонизатор"}>Шаблонизатор</MenuItem>
|
<MenuItem value={"templategen"}>Шаблонизатор</MenuItem>
|
||||||
<MenuItem value={"Опросник"}>Опросник</MenuItem>
|
<MenuItem value={"squiz"}>Опросник</MenuItem>
|
||||||
<MenuItem value={"Аналитика сокращателя"}>Аналитика сокращателя</MenuItem>
|
<MenuItem value={"dwarfener"}>Аналитика сокращателя</MenuItem>
|
||||||
<MenuItem value={"АБ тесты"}>АБ тесты</MenuItem>
|
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
@ -515,11 +470,13 @@ const DiscountManagement: React.FC = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box style={{ width: "80%", marginTop: "55px" }}>
|
<Box style={{ width: "80%", marginTop: "55px" }}>
|
||||||
<Box style={{ height: 400 }}>
|
<Box style={{ height: 600 }}>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
checkboxSelection={true}
|
checkboxSelection={true}
|
||||||
rows={discountsGridData}
|
rows={discountsGridData}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
selectionModel={selectedDiscountIds}
|
||||||
|
onSelectionModelChange={setSelectedDiscountIds}
|
||||||
sx={{
|
sx={{
|
||||||
color: theme.palette.secondary.main,
|
color: theme.palette.secondary.main,
|
||||||
"& .MuiDataGrid-iconSeparator": {
|
"& .MuiDataGrid-iconSeparator": {
|
||||||
@ -563,7 +520,7 @@ const DiscountManagement: React.FC = () => {
|
|||||||
}}>
|
}}>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={activateDiscounts}
|
onClick={deactivateDiscounts}
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: theme.palette.menu.main,
|
backgroundColor: theme.palette.menu.main,
|
||||||
width: "200px",
|
width: "200px",
|
||||||
@ -580,7 +537,7 @@ const DiscountManagement: React.FC = () => {
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={deactivateDiscounts}
|
onClick={activateDiscounts}
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: theme.palette.menu.main,
|
backgroundColor: theme.palette.menu.main,
|
||||||
width: "200px",
|
width: "200px",
|
||||||
@ -591,7 +548,7 @@ const DiscountManagement: React.FC = () => {
|
|||||||
backgroundColor: theme.palette.grayMedium.main
|
backgroundColor: theme.palette.grayMedium.main
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
Применить
|
Активировать
|
||||||
</Button>
|
</Button>
|
||||||
</BoxButton>
|
</BoxButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -1,49 +1,55 @@
|
|||||||
import { GridSelectionModel } from "@mui/x-data-grid";
|
import { GridSelectionModel } from "@mui/x-data-grid";
|
||||||
import { AnyDiscount } from "@root/model/cart";
|
import { AnyDiscount } from "@root/model/cart";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { devtools, persist } from "zustand/middleware";
|
import { devtools } from "zustand/middleware";
|
||||||
import { exampleCartValues } from "./mocks/exampleCartValues";
|
import { exampleCartValues } from "./mocks/exampleCartValues";
|
||||||
|
|
||||||
|
|
||||||
interface DiscountStore {
|
interface DiscountStore {
|
||||||
discounts: AnyDiscount[];
|
discounts: AnyDiscount[];
|
||||||
selectedDiscountIds: GridSelectionModel,
|
selectedDiscountIds: GridSelectionModel,
|
||||||
addDiscounts: (newDiscounts: AnyDiscount[]) => void;
|
|
||||||
deleteDiscounts: (discountIds: string[]) => void;
|
|
||||||
activateDiscounts: (discountIds: string[]) => void;
|
|
||||||
deactivateDiscounts: (discountIds: string[]) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDiscountStore = create<DiscountStore>()(
|
export const useDiscountStore = create<DiscountStore>()(
|
||||||
devtools(
|
devtools(
|
||||||
// persist(
|
(set, get) => ({
|
||||||
(set, get) => ({
|
discounts: exampleCartValues.discounts,
|
||||||
discounts: exampleCartValues.discounts,
|
selectedDiscountIds: [],
|
||||||
selectedDiscountIds: [],
|
}),
|
||||||
addDiscounts: newDiscounts => set(state => ({ discounts: [...state.discounts, ...newDiscounts] })),
|
|
||||||
deleteDiscounts: discountIdsToDelete => set(state => (
|
|
||||||
{ discounts: state.discounts.filter(discount => !discountIdsToDelete.includes(discount._id)) }
|
|
||||||
)),
|
|
||||||
activateDiscounts: discountIds => set(state => {
|
|
||||||
const filteredDiscounts = state.discounts.filter(discount => discountIds.includes(discount._id));
|
|
||||||
|
|
||||||
// TODO activate discounts, use immer js?
|
|
||||||
throw new Error("unimplemented");
|
|
||||||
}),
|
|
||||||
deactivateDiscounts: discountIds => set(state => {
|
|
||||||
const filteredDiscounts = state.discounts.filter(discount => discountIds.includes(discount._id));
|
|
||||||
|
|
||||||
// TODO deactivate discounts, use immer js?
|
|
||||||
throw new Error("unimplemented");
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
// {
|
|
||||||
// name: "discounts",
|
|
||||||
// getStorage: () => localStorage,
|
|
||||||
// }
|
|
||||||
// ),
|
|
||||||
{
|
{
|
||||||
name: "Discount store"
|
name: "Discount store"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const addDiscounts = (newDiscounts: AnyDiscount[]) => useDiscountStore.setState(state => ({ discounts: [...state.discounts, ...newDiscounts] }));
|
||||||
|
|
||||||
|
export const setSelectedDiscountIds = (selectedDiscountIds: DiscountStore["selectedDiscountIds"]) => useDiscountStore.setState({ selectedDiscountIds });
|
||||||
|
|
||||||
|
export const activateDiscounts = () => useDiscountStore.setState(state => {
|
||||||
|
const discounts: AnyDiscount[] = [];
|
||||||
|
state.discounts.forEach(discount => {
|
||||||
|
if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount);
|
||||||
|
|
||||||
|
discounts.push({
|
||||||
|
...discount,
|
||||||
|
disabled: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return { discounts };
|
||||||
|
});
|
||||||
|
|
||||||
|
export const deactivateDiscounts = () => useDiscountStore.setState(state => {
|
||||||
|
const discounts: AnyDiscount[] = [];
|
||||||
|
state.discounts.forEach(discount => {
|
||||||
|
if (!state.selectedDiscountIds.includes(discount._id)) return discounts.push(discount);
|
||||||
|
|
||||||
|
discounts.push({
|
||||||
|
...discount,
|
||||||
|
disabled: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return { discounts };
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user