feat: deal barcodes printing, refactored ff module

This commit is contained in:
2025-11-01 14:15:11 +04:00
parent 4370684c58
commit 69bf7848e1
15 changed files with 458 additions and 228 deletions

View File

@ -61,6 +61,7 @@ import {
getBaseMarketplaces, getBaseMarketplaces,
getBoards, getBoards,
getClients, getClients,
getDealBarcodesPdf,
getDealModuleAttributes, getDealModuleAttributes,
getDealProducts, getDealProducts,
getDeals, getDeals,
@ -240,6 +241,9 @@ import type {
GetBaseMarketplacesData, GetBaseMarketplacesData,
GetBoardsData, GetBoardsData,
GetClientsData, GetClientsData,
GetDealBarcodesPdfData,
GetDealBarcodesPdfError,
GetDealBarcodesPdfResponse2,
GetDealModuleAttributesData, GetDealModuleAttributesData,
GetDealProductsData, GetDealProductsData,
GetDealsData, GetDealsData,
@ -2902,6 +2906,57 @@ export const getProductBarcodePdfMutation = (
return mutationOptions; return mutationOptions;
}; };
export const getDealBarcodesPdfQueryKey = (
options: Options<GetDealBarcodesPdfData>
) => createQueryKey("getDealBarcodesPdf", options);
/**
* Get Deal Barcodes Pdf
*/
export const getDealBarcodesPdfOptions = (
options: Options<GetDealBarcodesPdfData>
) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await getDealBarcodesPdf({
...options,
...queryKey[0],
signal,
throwOnError: true,
});
return data;
},
queryKey: getDealBarcodesPdfQueryKey(options),
});
};
/**
* Get Deal Barcodes Pdf
*/
export const getDealBarcodesPdfMutation = (
options?: Partial<Options<GetDealBarcodesPdfData>>
): UseMutationOptions<
GetDealBarcodesPdfResponse2,
AxiosError<GetDealBarcodesPdfError>,
Options<GetDealBarcodesPdfData>
> => {
const mutationOptions: UseMutationOptions<
GetDealBarcodesPdfResponse2,
AxiosError<GetDealBarcodesPdfError>,
Options<GetDealBarcodesPdfData>
> = {
mutationFn: async localOptions => {
const { data } = await getDealBarcodesPdf({
...options,
...localOptions,
throwOnError: true,
});
return data;
},
};
return mutationOptions;
};
export const uploadProductBarcodeImageQueryKey = ( export const uploadProductBarcodeImageQueryKey = (
options: Options<UploadProductBarcodeImageData> options: Options<UploadProductBarcodeImageData>
) => createQueryKey("uploadProductBarcodeImage", options); ) => createQueryKey("uploadProductBarcodeImage", options);

View File

@ -154,6 +154,9 @@ import type {
GetClientsData, GetClientsData,
GetClientsErrors, GetClientsErrors,
GetClientsResponses, GetClientsResponses,
GetDealBarcodesPdfData,
GetDealBarcodesPdfErrors,
GetDealBarcodesPdfResponses,
GetDealModuleAttributesData, GetDealModuleAttributesData,
GetDealModuleAttributesErrors, GetDealModuleAttributesErrors,
GetDealModuleAttributesResponses, GetDealModuleAttributesResponses,
@ -380,6 +383,8 @@ import {
zGetBoardsResponse2, zGetBoardsResponse2,
zGetClientsData, zGetClientsData,
zGetClientsResponse2, zGetClientsResponse2,
zGetDealBarcodesPdfData,
zGetDealBarcodesPdfResponse2,
zGetDealModuleAttributesData, zGetDealModuleAttributesData,
zGetDealModuleAttributesResponse2, zGetDealModuleAttributesResponse2,
zGetDealProductsData, zGetDealProductsData,
@ -2271,6 +2276,33 @@ export const getProductBarcodePdf = <ThrowOnError extends boolean = false>(
}); });
}; };
/**
* Get Deal Barcodes Pdf
*/
export const getDealBarcodesPdf = <ThrowOnError extends boolean = false>(
options: Options<GetDealBarcodesPdfData, ThrowOnError>
) => {
return (options.client ?? _heyApiClient).post<
GetDealBarcodesPdfResponses,
GetDealBarcodesPdfErrors,
ThrowOnError
>({
requestValidator: async data => {
return await zGetDealBarcodesPdfData.parseAsync(data);
},
responseType: "json",
responseValidator: async data => {
return await zGetDealBarcodesPdfResponse2.parseAsync(data);
},
url: "/crm/v1/fulfillment-base/product/barcode/for-deal/get-pdf",
...options,
headers: {
"Content-Type": "application/json",
...options.headers,
},
});
};
/** /**
* Upload Product Barcode Image * Upload Product Barcode Image
*/ */

View File

@ -1613,6 +1613,34 @@ export type GetClientsResponse = {
items: Array<ClientSchema>; items: Array<ClientSchema>;
}; };
/**
* GetDealBarcodesPdfRequest
*/
export type GetDealBarcodesPdfRequest = {
/**
* Dealid
*/
dealId: number;
};
/**
* GetDealBarcodesPdfResponse
*/
export type GetDealBarcodesPdfResponse = {
/**
* Base64String
*/
base64String: string;
/**
* Filename
*/
filename: string;
/**
* Mimetype
*/
mimeType: string;
};
/** /**
* GetDealModuleAttributesResponse * GetDealModuleAttributesResponse
*/ */
@ -5233,6 +5261,33 @@ export type GetProductBarcodePdfResponses = {
export type GetProductBarcodePdfResponse2 = export type GetProductBarcodePdfResponse2 =
GetProductBarcodePdfResponses[keyof GetProductBarcodePdfResponses]; GetProductBarcodePdfResponses[keyof GetProductBarcodePdfResponses];
export type GetDealBarcodesPdfData = {
body: GetDealBarcodesPdfRequest;
path?: never;
query?: never;
url: "/crm/v1/fulfillment-base/product/barcode/for-deal/get-pdf";
};
export type GetDealBarcodesPdfErrors = {
/**
* Validation Error
*/
422: HttpValidationError;
};
export type GetDealBarcodesPdfError =
GetDealBarcodesPdfErrors[keyof GetDealBarcodesPdfErrors];
export type GetDealBarcodesPdfResponses = {
/**
* Successful Response
*/
200: GetDealBarcodesPdfResponse;
};
export type GetDealBarcodesPdfResponse2 =
GetDealBarcodesPdfResponses[keyof GetDealBarcodesPdfResponses];
export type UploadProductBarcodeImageData = { export type UploadProductBarcodeImageData = {
body: BodyUploadProductBarcodeImage; body: BodyUploadProductBarcodeImage;
path: { path: {

View File

@ -1149,6 +1149,22 @@ export const zGetClientsResponse = z.object({
items: z.array(zClientSchema), items: z.array(zClientSchema),
}); });
/**
* GetDealBarcodesPdfRequest
*/
export const zGetDealBarcodesPdfRequest = z.object({
dealId: z.int(),
});
/**
* GetDealBarcodesPdfResponse
*/
export const zGetDealBarcodesPdfResponse = z.object({
base64String: z.string(),
filename: z.string(),
mimeType: z.string(),
});
/** /**
* GetDealModuleAttributesResponse * GetDealModuleAttributesResponse
*/ */
@ -2743,6 +2759,17 @@ export const zGetProductBarcodePdfData = z.object({
*/ */
export const zGetProductBarcodePdfResponse2 = zGetProductBarcodePdfResponse; export const zGetProductBarcodePdfResponse2 = zGetProductBarcodePdfResponse;
export const zGetDealBarcodesPdfData = z.object({
body: zGetDealBarcodesPdfRequest,
path: z.optional(z.never()),
query: z.optional(z.never()),
});
/**
* Successful Response
*/
export const zGetDealBarcodesPdfResponse2 = zGetDealBarcodesPdfResponse;
export const zUploadProductBarcodeImageData = z.object({ export const zUploadProductBarcodeImageData = z.object({
body: zBodyUploadProductBarcodeImage, body: zBodyUploadProductBarcodeImage,
path: z.object({ path: z.object({

View File

@ -1,72 +1,30 @@
import { FC } from "react"; import { FC } from "react";
import { Button, Flex } from "@mantine/core"; import { IconCubePlus, IconPencilPlus } from "@tabler/icons-react";
import { modals } from "@mantine/modals"; import { Flex } from "@mantine/core";
import { notifications } from "@/lib/notifications"; import InlineButton from "@/components/ui/InlineButton/InlineButton";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; import useDealProductActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useDealProductActions";
import useProductActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductActions";
const ProductsActions: FC = () => { const ProductsActions: FC = () => {
const { deal, dealProductsList, productsCrud, dealProductsCrud } = const { onCreateClick: onCreateDealProductClick } = useDealProductActions();
useFulfillmentBaseContext(); const { onCreateClick: onCreateProductClick } = useProductActions();
const onCreateProductClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
modals.openContextModal({
modal: "productEditorModal",
title: "Создание товара",
withCloseButton: false,
innerProps: {
onCreate: productsCrud.onCreate,
isEditing: false,
clientId: deal.client.id,
refetchProducts: dealProductsList.refetch,
},
});
};
const onCreateDealProductClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
const productIdsToExclude = dealProductsList.dealProducts.map(
product => product.product.id
);
modals.openContextModal({
modal: "dealProductEditorModal",
title: "Добавление товара",
withCloseButton: false,
innerProps: {
onCreate: values =>
dealProductsCrud.onCreate({ ...values, dealId: deal.id }),
productIdsToExclude,
isEditing: false,
clientId: deal.client.id,
},
});
};
return ( return (
<Flex <Flex
w={"100%"} w={"100%"}
gap={"sm"}> gap={"sm"}>
<Button <InlineButton
variant={"default"}
fullWidth fullWidth
onClick={onCreateProductClick}> onClick={onCreateProductClick}>
<IconPencilPlus />
Создать товар Создать товар
</Button> </InlineButton>
<Button <InlineButton
variant={"default"}
fullWidth fullWidth
onClick={onCreateDealProductClick}> onClick={onCreateDealProductClick}>
<IconCubePlus />
Добавить товар Добавить товар
</Button> </InlineButton>
</Flex> </Flex>
); );
}; };

View File

@ -1,67 +1,41 @@
import { Button, Flex } from "@mantine/core"; import { IconBarcode, IconTextPlus } from "@tabler/icons-react";
import { modals } from "@mantine/modals"; import { Flex, Tooltip } from "@mantine/core";
import { addKitToDeal, ServicesKitSchema } from "@/lib/client"; import InlineButton from "@/components/ui/InlineButton/InlineButton";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; import useBarcodePrintActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useBarcodePrintActions";
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service"; import useServiceActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useServiceActions";
const ServicesActions = () => { const ServicesActions = () => {
const { dealServicesList, dealServicesCrud, deal } = const { onCreateClick, onAddKitClick } = useServiceActions();
useFulfillmentBaseContext(); const { onPrintDealBarcodesClick } = useBarcodePrintActions();
const onCreateClick = () => {
const serviceIdsToExclude = dealServicesList.dealServices.map(
service => service.service.id
);
modals.openContextModal({
modal: "dealServiceEditorModal",
innerProps: {
onCreate: values =>
dealServicesCrud.onCreate({ ...values, dealId: deal.id }),
serviceIdsToExclude,
isEditing: false,
},
withCloseButton: false,
});
};
const onServicesKitAdd = (servicesKit: ServicesKitSchema) => {
addKitToDeal({
body: {
dealId: deal.id,
kitId: servicesKit.id,
},
})
.then(() => dealServicesList.refetch())
.catch(err => console.error(err));
};
const onAddKitClick = () => {
modals.openContextModal({
modal: "servicesKitSelectModal",
innerProps: {
onSelect: onServicesKitAdd,
serviceType: ServiceType.DEAL_SERVICE,
},
withCloseButton: false,
});
};
return ( return (
<Flex <Flex
gap={"sm"} gap={"sm"}
mt={"auto"}> mt={"auto"}>
<Button <Tooltip label={"Добавить услугу в сделку"}>
onClick={onCreateClick} <InlineButton
fullWidth onClick={onCreateClick}
variant={"default"}> fullWidth>
Добавить услугу <IconTextPlus />
</Button> Услуга
<Button </InlineButton>
onClick={onAddKitClick} </Tooltip>
fullWidth <Tooltip label={"Добавить набор услуг в сделку"}>
variant={"default"}> <InlineButton
Добавить набор услуг onClick={onAddKitClick}
</Button> fullWidth>
<IconTextPlus />
Набор
</InlineButton>
</Tooltip>
<Tooltip label={"Печать всех штрихкодов сделки"}>
<InlineButton
fullWidth
onClick={onPrintDealBarcodesClick}>
<IconBarcode />
Печать
</InlineButton>
</Tooltip>
</Flex> </Flex>
); );
}; };

View File

@ -1,50 +1,20 @@
import { FC } from "react"; import { FC } from "react";
import { IconBarcode, IconEdit, IconTrash } from "@tabler/icons-react"; import { IconBarcode, IconEdit, IconTrash } from "@tabler/icons-react";
import { Flex } from "@mantine/core"; import { Flex } from "@mantine/core";
import { modals } from "@mantine/modals";
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip"; import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
import { DealProductSchema } from "@/lib/client"; import { DealProductSchema } from "@/lib/client";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
import useBarcodePrintActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useBarcodePrintActions";
import useProductActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductActions";
type Props = { type Props = {
dealProduct: DealProductSchema; dealProduct: DealProductSchema;
}; };
const ProductViewActions: FC<Props> = ({ dealProduct }) => { const ProductViewActions: FC<Props> = ({ dealProduct }) => {
const { dealProductsCrud, dealProductsList, productsCrud } = const { dealProductsCrud } = useFulfillmentBaseContext();
useFulfillmentBaseContext(); const { onChangeClick } = useProductActions();
const { onPrintProductBarcodeClick } = useBarcodePrintActions();
const onProductEditClick = () => {
modals.openContextModal({
modal: "productEditorModal",
title: "Редактирование товара",
withCloseButton: false,
innerProps: {
onChange: values =>
productsCrud.onUpdate(
dealProduct.productId,
values,
dealProductsList.refetch
),
entity: dealProduct.product,
isEditing: true,
clientId: dealProduct.product.clientId,
refetchProducts: dealProductsList.refetch,
},
});
};
const onPrintBarcodeClick = () => {
modals.openContextModal({
modal: "printBarcodeModal",
title: "Печать штрихкода",
withCloseButton: true,
innerProps: {
product: dealProduct.product,
defaultQuantity: dealProduct.quantity,
},
});
};
return ( return (
<Flex <Flex
@ -52,12 +22,12 @@ const ProductViewActions: FC<Props> = ({ dealProduct }) => {
ml={"auto"} ml={"auto"}
gap={"sm"}> gap={"sm"}>
<ActionIconWithTip <ActionIconWithTip
onClick={onPrintBarcodeClick} onClick={() => onPrintProductBarcodeClick(dealProduct)}
tipLabel="Печать штрихкода"> tipLabel="Печать штрихкода">
<IconBarcode /> <IconBarcode />
</ActionIconWithTip> </ActionIconWithTip>
<ActionIconWithTip <ActionIconWithTip
onClick={onProductEditClick} onClick={() => onChangeClick(dealProduct)}
tipLabel="Редактировать товар"> tipLabel="Редактировать товар">
<IconEdit /> <IconEdit />
</ActionIconWithTip> </ActionIconWithTip>

View File

@ -1,40 +1,13 @@
import { FC } from "react"; import { FC } from "react";
import { IconPlus } from "@tabler/icons-react"; import { IconPlus } from "@tabler/icons-react";
import { ButtonProps, Text } from "@mantine/core"; import { ButtonProps, Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import InlineButton from "@/components/ui/InlineButton/InlineButton"; import InlineButton from "@/components/ui/InlineButton/InlineButton";
import { notifications } from "@/lib/notifications"; import useDealProductActions from "../../../shared/hooks/utils/useDealProductActions";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
type Props = ButtonProps; type Props = ButtonProps;
const AddDealProductButton: FC<Props> = props => { const AddDealProductButton: FC<Props> = props => {
const { dealProductsList, dealProductsCrud, deal } = const { onCreateClick } = useDealProductActions();
useFulfillmentBaseContext();
const onCreateClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
const productIdsToExclude = dealProductsList.dealProducts.map(
product => product.product.id
);
modals.openContextModal({
modal: "dealProductEditorModal",
title: "Добавление товара",
withCloseButton: false,
innerProps: {
onCreate: values =>
dealProductsCrud.onCreate({ ...values, dealId: deal.id }),
productIdsToExclude,
isEditing: false,
clientId: deal.client.id,
},
});
};
return ( return (
<InlineButton <InlineButton

View File

@ -1,31 +1,13 @@
import { FC } from "react"; import { FC } from "react";
import { IconPlus } from "@tabler/icons-react"; import { IconPlus } from "@tabler/icons-react";
import { ButtonProps, Text } from "@mantine/core"; import { ButtonProps, Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import InlineButton from "@/components/ui/InlineButton/InlineButton"; import InlineButton from "@/components/ui/InlineButton/InlineButton";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; import useServiceActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useServiceActions";
type Props = ButtonProps; type Props = ButtonProps;
const AddDealServiceButton: FC<Props> = props => { const AddDealServiceButton: FC<Props> = props => {
const { dealServicesList, dealServicesCrud, deal } = const { onCreateClick } = useServiceActions();
useFulfillmentBaseContext();
const onCreateClick = () => {
const serviceIdsToExclude = dealServicesList.dealServices.map(
service => service.service.id
);
modals.openContextModal({
modal: "dealServiceEditorModal",
innerProps: {
onCreate: values =>
dealServicesCrud.onCreate({ ...values, dealId: deal.id }),
serviceIdsToExclude,
isEditing: false,
},
withCloseButton: false,
});
};
return ( return (
<InlineButton <InlineButton

View File

@ -9,13 +9,12 @@ import {
Text, Text,
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { modals } from "@mantine/modals";
import { DealProductSchema } from "@/lib/client"; import { DealProductSchema } from "@/lib/client";
import { notifications } from "@/lib/notifications";
import ProductFieldsList from "@/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductFieldsList"; import ProductFieldsList from "@/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductFieldsList";
import ProductMenu from "@/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductMenu/ProductMenu"; import ProductMenu from "@/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductMenu/ProductMenu";
import ProductServicesTable from "@/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable"; import ProductServicesTable from "@/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
import useDealProductActions from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useDealProductActions";
import styles from "../../../FulfillmentBase.module.css"; import styles from "../../../FulfillmentBase.module.css";
type Props = { type Props = {
@ -23,31 +22,8 @@ type Props = {
}; };
const DealProductView: FC<Props> = ({ dealProduct }) => { const DealProductView: FC<Props> = ({ dealProduct }) => {
const { dealProductsCrud, deal } = useFulfillmentBaseContext(); const { dealProductsCrud } = useFulfillmentBaseContext();
const { onChangeClick } = useDealProductActions();
const onChangeDealProductClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
modals.openContextModal({
modal: "dealProductEditorModal",
title: "Добавление товара",
withCloseButton: false,
innerProps: {
onChange: values =>
dealProductsCrud.onUpdate(
dealProduct.dealId,
dealProduct.productId,
values
),
entity: dealProduct,
isEditing: true,
clientId: deal.client.id,
},
});
};
return ( return (
<Box <Box
@ -83,7 +59,7 @@ const DealProductView: FC<Props> = ({ dealProduct }) => {
<Title order={3}>{dealProduct.product.name}</Title> <Title order={3}>{dealProduct.product.name}</Title>
<ProductMenu <ProductMenu
value={dealProduct} value={dealProduct}
onChange={onChangeDealProductClick} onChange={onChangeClick}
onDelete={dealProductsCrud.onDelete} onDelete={dealProductsCrud.onDelete}
/> />
</Group> </Group>

View File

@ -0,0 +1,55 @@
import { useMutation } from "@tanstack/react-query";
import { modals } from "@mantine/modals";
import { DealProductSchema } from "@/lib/client";
import { getDealBarcodesPdfMutation } from "@/lib/client/@tanstack/react-query.gen";
import { notifications } from "@/lib/notifications";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
import base64ToBlob from "@/utils/base64ToBlob";
const useBarcodePrintActions = () => {
const { deal } = useFulfillmentBaseContext();
const onPrintProductBarcodeClick = (dealProduct: DealProductSchema) => {
modals.openContextModal({
modal: "printBarcodeModal",
title: "Печать штрихкода",
withCloseButton: true,
innerProps: {
product: dealProduct.product,
defaultQuantity: dealProduct.quantity,
},
});
};
const getBarcodePdfMutation = useMutation({
...getDealBarcodesPdfMutation(),
onSuccess: response => {
const pdfBlob = base64ToBlob(
response.base64String,
response.mimeType
);
const pdfUrl = URL.createObjectURL(pdfBlob);
const pdfWindow = window.open(pdfUrl);
if (!pdfWindow) {
notifications.error({ message: "Ошибка" });
return;
}
pdfWindow.onload = () => pdfWindow.print();
},
});
const onPrintDealBarcodesClick = () => {
getBarcodePdfMutation.mutate({
body: {
dealId: deal.id,
},
});
};
return {
onPrintProductBarcodeClick,
onPrintDealBarcodesClick,
};
};
export default useBarcodePrintActions;

View File

@ -0,0 +1,64 @@
import { modals } from "@mantine/modals";
import { DealProductSchema } from "@/lib/client";
import { notifications } from "@/lib/notifications";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
const useDealProductActions = () => {
const { dealProductsList, dealProductsCrud, deal } =
useFulfillmentBaseContext();
const onCreateClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
const productIdsToExclude = dealProductsList.dealProducts.map(
product => product.product.id
);
modals.openContextModal({
modal: "dealProductEditorModal",
title: "Добавление товара",
withCloseButton: false,
innerProps: {
onCreate: values =>
dealProductsCrud.onCreate({ ...values, dealId: deal.id }),
productIdsToExclude,
isEditing: false,
clientId: deal.client.id,
},
});
};
const onChangeClick = (dealProduct: DealProductSchema) => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
modals.openContextModal({
modal: "dealProductEditorModal",
title: "Добавление товара",
withCloseButton: false,
innerProps: {
onChange: values =>
dealProductsCrud.onUpdate(
dealProduct.dealId,
dealProduct.productId,
values
),
entity: dealProduct,
isEditing: true,
clientId: deal.client.id,
},
});
};
return {
onCreateClick,
onChangeClick,
};
};
export default useDealProductActions;

View File

@ -0,0 +1,55 @@
import { modals } from "@mantine/modals";
import { notifications } from "@/lib/notifications";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
import { DealProductSchema } from "@/lib/client";
const useProductActions = () => {
const { deal, dealProductsList, productsCrud } =
useFulfillmentBaseContext();
const onCreateClick = () => {
if (!deal.client) {
notifications.error({ message: "Выберите клиента для сделки" });
return;
}
modals.openContextModal({
modal: "productEditorModal",
title: "Создание товара",
withCloseButton: false,
innerProps: {
onCreate: productsCrud.onCreate,
isEditing: false,
clientId: deal.client.id,
refetchProducts: dealProductsList.refetch,
},
});
};
const onChangeClick = (dealProduct: DealProductSchema) => {
modals.openContextModal({
modal: "productEditorModal",
title: "Редактирование товара",
withCloseButton: false,
innerProps: {
onChange: values =>
productsCrud.onUpdate(
dealProduct.productId,
values,
dealProductsList.refetch
),
entity: dealProduct.product,
isEditing: true,
clientId: dealProduct.product.clientId,
refetchProducts: dealProductsList.refetch,
},
});
};
return {
onCreateClick,
onChangeClick,
};
};
export default useProductActions;

View File

@ -0,0 +1,54 @@
import { modals } from "@mantine/modals";
import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext";
import { addKitToDeal, ServicesKitSchema } from "@/lib/client";
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
const useServiceActions = () => {
const { dealServicesList, dealServicesCrud, deal } =
useFulfillmentBaseContext();
const onCreateClick = () => {
const serviceIdsToExclude = dealServicesList.dealServices.map(
service => service.service.id
);
modals.openContextModal({
modal: "dealServiceEditorModal",
innerProps: {
onCreate: values =>
dealServicesCrud.onCreate({ ...values, dealId: deal.id }),
serviceIdsToExclude,
isEditing: false,
},
withCloseButton: false,
});
};
const onServicesKitAdd = (servicesKit: ServicesKitSchema) => {
addKitToDeal({
body: {
dealId: deal.id,
kitId: servicesKit.id,
},
})
.then(() => dealServicesList.refetch())
.catch(err => console.error(err));
};
const onAddKitClick = () => {
modals.openContextModal({
modal: "servicesKitSelectModal",
innerProps: {
onSelect: onServicesKitAdd,
serviceType: ServiceType.DEAL_SERVICE,
},
withCloseButton: false,
});
};
return {
onCreateClick,
onAddKitClick,
};
};
export default useServiceActions;

View File

@ -38,10 +38,10 @@ const PrintBarcodeModal = ({ innerProps }: ContextModalProps<Props>) => {
}); });
const printBarcode = () => { const printBarcode = () => {
if (!barcode) return; if (!barcode && !product.barcodeImageUrl) return;
getBarcodePdfMutation.mutate({ getBarcodePdfMutation.mutate({
body: { body: {
barcode, barcode: barcode ?? "",
quantity, quantity,
productId: product.id, productId: product.id,
}, },