feat: total services amount and recalculating

This commit is contained in:
2024-10-22 19:31:51 +03:00
parent aa6f0364b5
commit bb34f12274
10 changed files with 153 additions and 43 deletions

View File

@@ -10,7 +10,7 @@ import { ContextModalProps } from "@mantine/modals";
import { useForm, UseFormReturnType } from "@mantine/form";
import { isNil, isNumber } from "lodash";
import ServiceWithPriceInput from "../../../components/ServiceWithPriceInput/ServiceWithPriceInput.tsx";
import { Flex } from "@mantine/core";
import { Checkbox, Flex, rem } from "@mantine/core";
import { ServiceType } from "../../../shared/enums/ServiceType.ts";
import { useSelector } from "react-redux";
import { RootState } from "../../../redux/store.ts";
@@ -23,20 +23,21 @@ type RestProps = {
type Props = CreateEditFormProps<DealProductServiceSchema> & RestProps;
const ProductServiceFormModal = ({
context,
id,
innerProps,
}: ContextModalProps<Props>) => {
context,
id,
innerProps,
}: ContextModalProps<Props>) => {
const authState = useSelector((state: RootState) => state.auth);
const isEditing = "onChange" in innerProps;
const initialValues: Partial<DealProductServiceSchema> = isEditing
? innerProps.element
: {
service: undefined,
price: undefined,
employees: [],
};
service: undefined,
price: undefined,
employees: [],
isFixedPrice: false,
};
const form = useForm<Partial<DealProductServiceSchema>>({
initialValues,
validate: {
@@ -57,7 +58,7 @@ const ProductServiceFormModal = ({
closeOnSubmit>
<BaseFormModal.Body>
<>
<Flex w={"100%"}>
<Flex w={"100%"} direction={"column"} gap={rem(10)}>
<ServiceWithPriceInput
category={innerProps.category}
serviceProps={{
@@ -85,6 +86,11 @@ const ProductServiceFormModal = ({
lockOnEdit={isEditing}
quantity={innerProps.quantity}
/>
<Checkbox
{...form.getInputProps("isFixedPrice", { type: "checkbox" })}
label={"Зафиксировать цену"}
placeholder={"Зафиксировать цену"}
/>
</Flex>
</>
</BaseFormModal.Body>

View File

@@ -1,21 +1,7 @@
import { CRUDTableProps } from "../../../../../../types/CRUDTable.tsx";
import {
DealServiceSchema,
GetServiceKitSchema,
UserSchema,
} from "../../../../../../client";
import { DealServiceSchema, GetServiceKitSchema, UserSchema } from "../../../../../../client";
import { FC, useState } from "react";
import {
ActionIcon,
Button,
Flex,
Modal,
NumberInput,
rem,
Text,
Title,
Tooltip,
} from "@mantine/core";
import { ActionIcon, Button, Flex, Modal, NumberInput, rem, Text, Title, Tooltip } from "@mantine/core";
import { IconTrash, IconUsersGroup } from "@tabler/icons-react";
import { modals } from "@mantine/modals";
import { isNumber } from "lodash";
@@ -24,18 +10,19 @@ import { ServiceType } from "../../../../../../shared/enums/ServiceType.ts";
import { useSelector } from "react-redux";
import { RootState } from "../../../../../../redux/store.ts";
import useDealProductAndServiceTabState from "../../hooks/useProductAndServiceTabState.tsx";
import LockCheckbox from "../../../../../../components/LockCheckbox/LockCheckbox.tsx";
type RestProps = {
onKitAdd?: (kit: GetServiceKitSchema) => void;
};
type Props = CRUDTableProps<DealServiceSchema> & RestProps;
const DealServicesTable: FC<Props> = ({
items,
onDelete,
onCreate,
onChange,
onKitAdd,
}) => {
items,
onDelete,
onCreate,
onChange,
onKitAdd,
}) => {
const authState = useSelector((state: RootState) => state.auth);
const { dealState } = useDealProductAndServiceTabState();
@@ -78,7 +65,13 @@ const DealServicesTable: FC<Props> = ({
price,
});
};
const onLockChange = (item: DealServiceSchema, isLocked: boolean) => {
if (!onChange) return;
onChange({
...item,
isFixedPrice: isLocked,
});
};
const onEmployeeClick = (item: DealServiceSchema) => {
if (!onChange) return;
setCurrentService(item);
@@ -91,7 +84,7 @@ const DealServicesTable: FC<Props> = ({
const getCurrentEmployees = (): UserSchema[] => {
if (!currentService) return [];
const item = items.find(
i => i.service.id === currentService.service.id
i => i.service.id === currentService.service.id,
);
if (!item) return [];
return item.employees;
@@ -169,7 +162,9 @@ const DealServicesTable: FC<Props> = ({
isNumber(event) &&
onQuantityChange(service, event)
}
value={service.quantity}
/>
<NumberInput
flex={1}
@@ -179,7 +174,22 @@ const DealServicesTable: FC<Props> = ({
}
suffix={"₽"}
value={service.price}
disabled={authState.isGuest || isLocked}
disabled={authState.isGuest || isLocked || service.isFixedPrice}
rightSectionProps={{
style: {
display: "flex",
cursor: "pointer",
pointerEvents: "auto",
},
}}
rightSection={
<LockCheckbox
label={"Зафиксировать цену"}
variant={"default"}
value={service.isFixedPrice}
onChange={value => onLockChange(service, value)}
/>
}
/>
</Flex>
))}
@@ -192,7 +202,7 @@ const DealServicesTable: FC<Props> = ({
Итог:{" "}
{items.reduce(
(acc, item) => acc + item.price * item.quantity,
0
0,
)}
</Title>

View File

@@ -8,13 +8,24 @@ import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import { notifications } from "../../../../../shared/lib/notifications.ts";
const useDealState = () => {
const { selectedDeal, setSelectedDeal } = useDealPageContext();
const recalculate = async () => {
return DealService.recalculateDealPrice({
requestBody: {
dealId: selectedDeal?.id || -1,
},
});
};
const refetch = async () => {
if (!selectedDeal) return;
const { ok, message } = await recalculate();
if (!ok) notifications.guess(ok, { message });
return DealService.getDealById({ dealId: selectedDeal.id }).then(
deal => {
setSelectedDeal(deal);
}
},
);
};
return {
@@ -25,6 +36,9 @@ const useDealState = () => {
const useDealServicesState = (): CRUDTableProps<DealServiceSchema> => {
const { deal, refetch } = useDealState();
const refetchAndRecalculate = async () => {
await refetch();
};
const onCreate = (item: DealServiceSchema) => {
if (!deal) return;
DealService.addDealService({
@@ -36,7 +50,7 @@ const useDealServicesState = (): CRUDTableProps<DealServiceSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
const onDelete = (item: DealServiceSchema) => {
@@ -48,7 +62,7 @@ const useDealServicesState = (): CRUDTableProps<DealServiceSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
const onChange = (item: DealServiceSchema) => {
@@ -60,7 +74,7 @@ const useDealServicesState = (): CRUDTableProps<DealServiceSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
return {
@@ -73,6 +87,9 @@ const useDealServicesState = (): CRUDTableProps<DealServiceSchema> => {
const useDealProductsState = (): CRUDTableProps<DealProductSchema> => {
const { deal, refetch } = useDealState();
const refetchAndRecalculate = async () => {
await refetch();
};
const onCreate = (item: DealProductSchema) => {
if (!deal) return;
DealService.addDealProduct({
@@ -82,7 +99,7 @@ const useDealProductsState = (): CRUDTableProps<DealProductSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
const onDelete = (item: DealProductSchema) => {
@@ -94,7 +111,7 @@ const useDealProductsState = (): CRUDTableProps<DealProductSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
const onChange = (item: DealProductSchema) => {
@@ -106,7 +123,7 @@ const useDealProductsState = (): CRUDTableProps<DealProductSchema> => {
},
}).then(async ({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
if (ok) await refetch();
if (ok) await refetchAndRecalculate();
});
};
return {