feat: deal barcodes printing, refactored ff module
This commit is contained in:
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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: {
|
||||||
|
|||||||
@ -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({
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user