feat: pallets and boxes for deals

This commit is contained in:
2024-12-09 16:45:48 +04:00
parent de4885274b
commit 2ee0ef3a52
32 changed files with 1208 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ export type { BillStatusUpdateRequest } from './models/BillStatusUpdateRequest';
export type { Body_upload_passport_image } from './models/Body_upload_passport_image'; export type { Body_upload_passport_image } from './models/Body_upload_passport_image';
export type { Body_upload_product_barcode_image } from './models/Body_upload_product_barcode_image'; export type { Body_upload_product_barcode_image } from './models/Body_upload_product_barcode_image';
export type { Body_upload_product_image } from './models/Body_upload_product_image'; export type { Body_upload_product_image } from './models/Body_upload_product_image';
export type { BoxSchema } from './models/BoxSchema';
export type { CancelDealBillRequest } from './models/CancelDealBillRequest'; export type { CancelDealBillRequest } from './models/CancelDealBillRequest';
export type { CancelDealBillResponse } from './models/CancelDealBillResponse'; export type { CancelDealBillResponse } from './models/CancelDealBillResponse';
export type { ClientCreateRequest } from './models/ClientCreateRequest'; export type { ClientCreateRequest } from './models/ClientCreateRequest';
@@ -45,11 +46,14 @@ export type { ClientUpdateRequest } from './models/ClientUpdateRequest';
export type { ClientUpdateResponse } from './models/ClientUpdateResponse'; export type { ClientUpdateResponse } from './models/ClientUpdateResponse';
export type { CreateBarcodeTemplateAttributeRequest } from './models/CreateBarcodeTemplateAttributeRequest'; export type { CreateBarcodeTemplateAttributeRequest } from './models/CreateBarcodeTemplateAttributeRequest';
export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse'; export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse';
export type { CreateBoxInDealSchema } from './models/CreateBoxInDealSchema';
export type { CreateBoxInPalletSchema } from './models/CreateBoxInPalletSchema';
export type { CreateDealBillRequest } from './models/CreateDealBillRequest'; export type { CreateDealBillRequest } from './models/CreateDealBillRequest';
export type { CreateDealBillResponse } from './models/CreateDealBillResponse'; export type { CreateDealBillResponse } from './models/CreateDealBillResponse';
export type { CreateExpenseTagRequest } from './models/CreateExpenseTagRequest'; export type { CreateExpenseTagRequest } from './models/CreateExpenseTagRequest';
export type { CreateMarketplaceRequest } from './models/CreateMarketplaceRequest'; export type { CreateMarketplaceRequest } from './models/CreateMarketplaceRequest';
export type { CreateMarketplaceResponse } from './models/CreateMarketplaceResponse'; export type { CreateMarketplaceResponse } from './models/CreateMarketplaceResponse';
export type { CreatePalletResponse } from './models/CreatePalletResponse';
export type { CreatePaymentRecordRequest } from './models/CreatePaymentRecordRequest'; export type { CreatePaymentRecordRequest } from './models/CreatePaymentRecordRequest';
export type { CreatePaymentRecordResponse } from './models/CreatePaymentRecordResponse'; export type { CreatePaymentRecordResponse } from './models/CreatePaymentRecordResponse';
export type { CreatePayRateRequest } from './models/CreatePayRateRequest'; export type { CreatePayRateRequest } from './models/CreatePayRateRequest';
@@ -61,6 +65,7 @@ export type { CreatePriceCategoryResponse } from './models/CreatePriceCategoryRe
export type { CreateServiceKitSchema } from './models/CreateServiceKitSchema'; export type { CreateServiceKitSchema } from './models/CreateServiceKitSchema';
export type { CreateServicesKitRequest } from './models/CreateServicesKitRequest'; export type { CreateServicesKitRequest } from './models/CreateServicesKitRequest';
export type { CreateServicesKitResponse } from './models/CreateServicesKitResponse'; export type { CreateServicesKitResponse } from './models/CreateServicesKitResponse';
export type { CreateShippingProductSchema } from './models/CreateShippingProductSchema';
export type { CreateShippingWarehouseRequest } from './models/CreateShippingWarehouseRequest'; export type { CreateShippingWarehouseRequest } from './models/CreateShippingWarehouseRequest';
export type { CreateShippingWarehouseResponse } from './models/CreateShippingWarehouseResponse'; export type { CreateShippingWarehouseResponse } from './models/CreateShippingWarehouseResponse';
export type { CreateTaskResponse } from './models/CreateTaskResponse'; export type { CreateTaskResponse } from './models/CreateTaskResponse';
@@ -133,10 +138,12 @@ export type { DealUpdateServiceQuantityRequest } from './models/DealUpdateServic
export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse'; export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse';
export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest'; export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest';
export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse'; export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse';
export type { DeleteBoxResponse } from './models/DeleteBoxResponse';
export type { DeleteExpenseResponse } from './models/DeleteExpenseResponse'; export type { DeleteExpenseResponse } from './models/DeleteExpenseResponse';
export type { DeleteExpenseTagResponse } from './models/DeleteExpenseTagResponse'; export type { DeleteExpenseTagResponse } from './models/DeleteExpenseTagResponse';
export type { DeleteMarketplaceRequest } from './models/DeleteMarketplaceRequest'; export type { DeleteMarketplaceRequest } from './models/DeleteMarketplaceRequest';
export type { DeleteMarketplaceResponse } from './models/DeleteMarketplaceResponse'; export type { DeleteMarketplaceResponse } from './models/DeleteMarketplaceResponse';
export type { DeletePalletResponse } from './models/DeletePalletResponse';
export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest'; export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest';
export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse'; export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse';
export type { DeletePayRateRequest } from './models/DeletePayRateRequest'; export type { DeletePayRateRequest } from './models/DeletePayRateRequest';
@@ -146,6 +153,7 @@ export type { DeletePositionResponse } from './models/DeletePositionResponse';
export type { DeletePriceCategoryRequest } from './models/DeletePriceCategoryRequest'; export type { DeletePriceCategoryRequest } from './models/DeletePriceCategoryRequest';
export type { DeletePriceCategoryResponse } from './models/DeletePriceCategoryResponse'; export type { DeletePriceCategoryResponse } from './models/DeletePriceCategoryResponse';
export type { DeleteShiftResponse } from './models/DeleteShiftResponse'; export type { DeleteShiftResponse } from './models/DeleteShiftResponse';
export type { DeleteShippingProductResponse } from './models/DeleteShippingProductResponse';
export type { DeleteShippingWarehouseRequest } from './models/DeleteShippingWarehouseRequest'; export type { DeleteShippingWarehouseRequest } from './models/DeleteShippingWarehouseRequest';
export type { DeleteShippingWarehouseResponse } from './models/DeleteShippingWarehouseResponse'; export type { DeleteShippingWarehouseResponse } from './models/DeleteShippingWarehouseResponse';
export type { ExpenseSchemaBase } from './models/ExpenseSchemaBase'; export type { ExpenseSchemaBase } from './models/ExpenseSchemaBase';
@@ -195,6 +203,7 @@ export type { MarketplaceCreateSchema } from './models/MarketplaceCreateSchema';
export type { MarketplaceSchema } from './models/MarketplaceSchema'; export type { MarketplaceSchema } from './models/MarketplaceSchema';
export type { NotificationChannel } from './models/NotificationChannel'; export type { NotificationChannel } from './models/NotificationChannel';
export type { PaginationInfoSchema } from './models/PaginationInfoSchema'; export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
export type { PalletSchema } from './models/PalletSchema';
export type { PassportImageSchema } from './models/PassportImageSchema'; export type { PassportImageSchema } from './models/PassportImageSchema';
export type { PaymentRecordCreateSchema } from './models/PaymentRecordCreateSchema'; export type { PaymentRecordCreateSchema } from './models/PaymentRecordCreateSchema';
export type { PaymentRecordGetSchema } from './models/PaymentRecordGetSchema'; export type { PaymentRecordGetSchema } from './models/PaymentRecordGetSchema';
@@ -248,6 +257,7 @@ export type { ServiceUpdateCategoryRequest } from './models/ServiceUpdateCategor
export type { ServiceUpdateCategoryResponse } from './models/ServiceUpdateCategoryResponse'; export type { ServiceUpdateCategoryResponse } from './models/ServiceUpdateCategoryResponse';
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest'; export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse'; export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
export type { ShippingProductSchema } from './models/ShippingProductSchema';
export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema'; export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema';
export type { StartPauseByShiftIdResponse } from './models/StartPauseByShiftIdResponse'; export type { StartPauseByShiftIdResponse } from './models/StartPauseByShiftIdResponse';
export type { StartPauseByUserIdResponse } from './models/StartPauseByUserIdResponse'; export type { StartPauseByUserIdResponse } from './models/StartPauseByUserIdResponse';
@@ -256,6 +266,9 @@ export type { SynchronizeMarketplaceRequest } from './models/SynchronizeMarketpl
export type { TaskInfoResponse } from './models/TaskInfoResponse'; export type { TaskInfoResponse } from './models/TaskInfoResponse';
export type { TimeTrackingData } from './models/TimeTrackingData'; export type { TimeTrackingData } from './models/TimeTrackingData';
export type { TimeTrackingRecord } from './models/TimeTrackingRecord'; export type { TimeTrackingRecord } from './models/TimeTrackingRecord';
export type { UpdateBoxRequest } from './models/UpdateBoxRequest';
export type { UpdateBoxResponse } from './models/UpdateBoxResponse';
export type { UpdateBoxSchema } from './models/UpdateBoxSchema';
export type { UpdateExpenseRequest } from './models/UpdateExpenseRequest'; export type { UpdateExpenseRequest } from './models/UpdateExpenseRequest';
export type { UpdateExpenseResponse } from './models/UpdateExpenseResponse'; export type { UpdateExpenseResponse } from './models/UpdateExpenseResponse';
export type { UpdateExpenseSchema } from './models/UpdateExpenseSchema'; export type { UpdateExpenseSchema } from './models/UpdateExpenseSchema';
@@ -270,6 +283,9 @@ export type { UpdatePriceCategoryResponse } from './models/UpdatePriceCategoryRe
export type { UpdateServiceKitSchema } from './models/UpdateServiceKitSchema'; export type { UpdateServiceKitSchema } from './models/UpdateServiceKitSchema';
export type { UpdateServicesKitRequest } from './models/UpdateServicesKitRequest'; export type { UpdateServicesKitRequest } from './models/UpdateServicesKitRequest';
export type { UpdateServicesKitResponse } from './models/UpdateServicesKitResponse'; export type { UpdateServicesKitResponse } from './models/UpdateServicesKitResponse';
export type { UpdateShippingProductRequest } from './models/UpdateShippingProductRequest';
export type { UpdateShippingProductResponse } from './models/UpdateShippingProductResponse';
export type { UpdateShippingProductSchema } from './models/UpdateShippingProductSchema';
export type { UpdateShippingWarehouseRequest } from './models/UpdateShippingWarehouseRequest'; export type { UpdateShippingWarehouseRequest } from './models/UpdateShippingWarehouseRequest';
export type { UpdateShippingWarehouseResponse } from './models/UpdateShippingWarehouseResponse'; export type { UpdateShippingWarehouseResponse } from './models/UpdateShippingWarehouseResponse';
export type { UpdateTimeTrackingRecordRequest } from './models/UpdateTimeTrackingRecordRequest'; export type { UpdateTimeTrackingRecordRequest } from './models/UpdateTimeTrackingRecordRequest';
@@ -296,6 +312,7 @@ export { PositionService } from './services/PositionService';
export { ProductService } from './services/ProductService'; export { ProductService } from './services/ProductService';
export { RoleService } from './services/RoleService'; export { RoleService } from './services/RoleService';
export { ServiceService } from './services/ServiceService'; export { ServiceService } from './services/ServiceService';
export { ShippingService } from './services/ShippingService';
export { ShippingWarehouseService } from './services/ShippingWarehouseService'; export { ShippingWarehouseService } from './services/ShippingWarehouseService';
export { StatisticsService } from './services/StatisticsService'; export { StatisticsService } from './services/StatisticsService';
export { TaskService } from './services/TaskService'; export { TaskService } from './services/TaskService';

View File

@@ -0,0 +1,13 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ProductSchema } from './ProductSchema';
export type BoxSchema = {
id: number;
quantity: number;
product: ProductSchema;
palletId: (number | null);
dealId: (number | null);
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreateBoxInDealSchema = {
productId: (number | null);
quantity: (number | null);
dealId: (number | null);
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreateBoxInPalletSchema = {
productId: (number | null);
quantity: (number | null);
palletId: (number | null);
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreatePalletResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreateShippingProductSchema = {
productId: (number | null);
quantity: (number | null);
palletId: number;
};

View File

@@ -2,12 +2,14 @@
/* istanbul ignore file */ /* istanbul ignore file */
/* tslint:disable */ /* tslint:disable */
/* eslint-disable */ /* eslint-disable */
import type { BoxSchema } from './BoxSchema';
import type { ClientSchema } from './ClientSchema'; import type { ClientSchema } from './ClientSchema';
import type { DealBillRequestSchema } from './DealBillRequestSchema'; import type { DealBillRequestSchema } from './DealBillRequestSchema';
import type { DealGroupSchema } from './DealGroupSchema'; import type { DealGroupSchema } from './DealGroupSchema';
import type { DealProductSchema } from './DealProductSchema'; import type { DealProductSchema } from './DealProductSchema';
import type { DealServiceSchema } from './DealServiceSchema'; import type { DealServiceSchema } from './DealServiceSchema';
import type { DealStatusHistorySchema } from './DealStatusHistorySchema'; import type { DealStatusHistorySchema } from './DealStatusHistorySchema';
import type { PalletSchema } from './PalletSchema';
import type { ServicePriceCategorySchema } from './ServicePriceCategorySchema'; import type { ServicePriceCategorySchema } from './ServicePriceCategorySchema';
import type { ShippingWarehouseSchema } from './ShippingWarehouseSchema'; import type { ShippingWarehouseSchema } from './ShippingWarehouseSchema';
import type { UserSchema } from './UserSchema'; import type { UserSchema } from './UserSchema';
@@ -30,6 +32,8 @@ export type DealSchema = {
category?: (ServicePriceCategorySchema | null); category?: (ServicePriceCategorySchema | null);
group?: (DealGroupSchema | null); group?: (DealGroupSchema | null);
manager?: (UserSchema | null); manager?: (UserSchema | null);
pallets?: Array<PalletSchema>;
boxes?: Array<BoxSchema>;
deliveryDate?: (string | null); deliveryDate?: (string | null);
receivingSlotDate?: (string | null); receivingSlotDate?: (string | null);
}; };

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DeleteBoxResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DeletePalletResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DeleteShippingProductResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,12 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { BoxSchema } from './BoxSchema';
import type { ShippingProductSchema } from './ShippingProductSchema';
export type PalletSchema = {
id: number;
boxes: Array<BoxSchema>;
shippingProducts: Array<ShippingProductSchema>;
};

View File

@@ -0,0 +1,12 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ProductSchema } from './ProductSchema';
export type ShippingProductSchema = {
id: number;
quantity: number;
product: ProductSchema;
palletId: number;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { CreateBoxInDealSchema } from './CreateBoxInDealSchema';
import type { CreateBoxInPalletSchema } from './CreateBoxInPalletSchema';
import type { UpdateBoxSchema } from './UpdateBoxSchema';
export type UpdateBoxRequest = {
data: (CreateBoxInDealSchema | CreateBoxInPalletSchema | UpdateBoxSchema);
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UpdateBoxResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UpdateBoxSchema = {
productId: (number | null);
quantity: (number | null);
boxId: (number | null);
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { CreateShippingProductSchema } from './CreateShippingProductSchema';
import type { UpdateShippingProductSchema } from './UpdateShippingProductSchema';
export type UpdateShippingProductRequest = {
data: (CreateShippingProductSchema | UpdateShippingProductSchema);
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UpdateShippingProductResponse = {
ok: boolean;
message: string;
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UpdateShippingProductSchema = {
productId: (number | null);
quantity: (number | null);
shippingProductId: number;
};

View File

@@ -0,0 +1,183 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { CreatePalletResponse } from '../models/CreatePalletResponse';
import type { DeleteBoxResponse } from '../models/DeleteBoxResponse';
import type { DeletePalletResponse } from '../models/DeletePalletResponse';
import type { DeleteShippingProductResponse } from '../models/DeleteShippingProductResponse';
import type { UpdateBoxRequest } from '../models/UpdateBoxRequest';
import type { UpdateBoxResponse } from '../models/UpdateBoxResponse';
import type { UpdateShippingProductRequest } from '../models/UpdateShippingProductRequest';
import type { UpdateShippingProductResponse } from '../models/UpdateShippingProductResponse';
import type { CancelablePromise } from '../core/CancelablePromise';
import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
export class ShippingService {
/**
* Create Pallet
* @returns CreatePalletResponse Successful Response
* @throws ApiError
*/
public static createPallet({
dealId,
}: {
dealId: number,
}): CancelablePromise<CreatePalletResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/shipping/pallet/{deal_id}',
path: {
'deal_id': dealId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Delete Pallet
* @returns DeletePalletResponse Successful Response
* @throws ApiError
*/
public static deletePallet({
palletId,
}: {
palletId: number,
}): CancelablePromise<DeletePalletResponse> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/shipping/pallet/{pallet_id}',
path: {
'pallet_id': palletId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Update Shipping Product
* @returns UpdateShippingProductResponse Successful Response
* @throws ApiError
*/
public static updateShippingProduct({
requestBody,
}: {
requestBody: UpdateShippingProductRequest,
}): CancelablePromise<UpdateShippingProductResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/shipping/product',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* Delete Shipping Product
* @returns DeleteShippingProductResponse Successful Response
* @throws ApiError
*/
public static deleteShippingProduct({
shippingProductId,
}: {
shippingProductId: number,
}): CancelablePromise<DeleteShippingProductResponse> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/shipping/product/{shipping_product_id}',
path: {
'shipping_product_id': shippingProductId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Update Box
* @returns UpdateBoxResponse Successful Response
* @throws ApiError
*/
public static updateBox({
requestBody,
}: {
requestBody: UpdateBoxRequest,
}): CancelablePromise<UpdateBoxResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/shipping/box',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* Delete Box
* @returns DeleteBoxResponse Successful Response
* @throws ApiError
*/
public static deleteBox({
boxId,
}: {
boxId: number,
}): CancelablePromise<DeleteBoxResponse> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/shipping/box/{box_id}',
path: {
'box_id': boxId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Generate Deal Qr Code
* @returns any Successful Response
* @throws ApiError
*/
public static getDealQrCodePdf({
dealId,
}: {
dealId: number,
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'GET',
url: '/shipping/pdf/deal/{deal_id}',
path: {
'deal_id': dealId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Generate Deal Qr Code
* @returns any Successful Response
* @throws ApiError
*/
public static getPalletsPdf({
dealId,
}: {
dealId: number,
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'GET',
url: '/shipping/pdf/pallets/{deal_id}',
path: {
'deal_id': dealId,
},
errors: {
422: `Validation Error`,
},
});
}
}

View File

@@ -24,6 +24,7 @@ import ServicePriceCategoryForm from "../pages/ServicesPage/modals/ServicePriceC
import ScanningModal from "./ScanningModal/ScanningModal.tsx"; import ScanningModal from "./ScanningModal/ScanningModal.tsx";
import ExpenseFormModal from "../pages/AdminPage/tabs/Expenses/modals/ExpenseFormModal.tsx"; import ExpenseFormModal from "../pages/AdminPage/tabs/Expenses/modals/ExpenseFormModal.tsx";
import ExpenseTagsModal from "../pages/AdminPage/tabs/Expenses/modals/ExpenseTagsModal.tsx"; import ExpenseTagsModal from "../pages/AdminPage/tabs/Expenses/modals/ExpenseTagsModal.tsx";
import ShippingProductModal from "../pages/LeadsPage/tabs/ShippingTab/modals/ShippingProductModal.tsx";
export const modals = { export const modals = {
enterDeadline: EnterDeadlineModal, enterDeadline: EnterDeadlineModal,
@@ -52,4 +53,5 @@ export const modals = {
scanningModal: ScanningModal, scanningModal: ScanningModal,
expenseFormModal: ExpenseFormModal, expenseFormModal: ExpenseFormModal,
expenseTagsModal: ExpenseTagsModal, expenseTagsModal: ExpenseTagsModal,
shippingProductModal: ShippingProductModal,
}; };

View File

@@ -1,13 +1,14 @@
import { Box, Drawer, rem, Tabs } from "@mantine/core"; import { Box, Drawer, rem, Tabs } from "@mantine/core";
import { FC, useEffect } from "react"; import { FC, useEffect } from "react";
import { useDealPageContext } from "../../contexts/DealPageContext.tsx"; import { useDealPageContext } from "../../contexts/DealPageContext.tsx";
import { IconBox, IconCalendarUser, IconSettings, IconUser } from "@tabler/icons-react"; import { IconBox, IconCalendarUser, IconCubeSend, IconSettings, IconUser } from "@tabler/icons-react";
import DealStatusChangeTable from "../../components/DealStatusChangeTable/DealStatusChangeTable.tsx"; import DealStatusChangeTable from "../../components/DealStatusChangeTable/DealStatusChangeTable.tsx";
import DealEditDrawerGeneralTab from "./tabs/DealEditDrawerGeneralTab.tsx"; import DealEditDrawerGeneralTab from "./tabs/DealEditDrawerGeneralTab.tsx";
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
import ProductAndServiceTab from "../../tabs/ProductAndServiceTab/ProductAndServiceTab.tsx"; import ProductAndServiceTab from "../../tabs/ProductAndServiceTab/ProductAndServiceTab.tsx";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import ClientTab from "./tabs/ClientTab.tsx"; import ClientTab from "./tabs/ClientTab.tsx";
import ShippingTab from "../../tabs/ShippingTab/ShippingTab.tsx";
// import styles from './DealEditDrawer.module.css'; // import styles from './DealEditDrawer.module.css';
// const useDealServicesTableState = () => { // const useDealServicesTableState = () => {
@@ -348,6 +349,11 @@ const DealEditDrawer: FC = () => {
leftSection={<IconBox />}> leftSection={<IconBox />}>
Товары и услуги Товары и услуги
</Tabs.Tab> </Tabs.Tab>
<Tabs.Tab
value={"shipment"}
leftSection={<IconCubeSend />}>
Отгрузка
</Tabs.Tab>
</Tabs.List> </Tabs.List>
<Tabs.Panel value={"general"}> <Tabs.Panel value={"general"}>
<motion.div <motion.div
@@ -392,6 +398,16 @@ const DealEditDrawer: FC = () => {
</Box> </Box>
</motion.div> </motion.div>
</Tabs.Panel> </Tabs.Panel>
<Tabs.Panel value={"shipment"}>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}>
<Box p={rem(10)}>
<ShippingTab />
</Box>
</motion.div>
</Tabs.Panel>
</Tabs> </Tabs>
</Drawer> </Drawer>
); );

View File

@@ -0,0 +1,51 @@
import ShippingTree from "./components/ShippingTree.tsx";
import { Button, Group, rem, ScrollArea, Stack } from "@mantine/core";
import useShipping from "./hooks/useShipping.tsx";
import useShippingQrs from "./hooks/useShippingQrs.tsx";
import { IconPrinter, IconQrcode } from "@tabler/icons-react";
import { ReactNode } from "react";
const ShippingTab = () => {
const {
onCreateBoxInDealClick,
onCreatePalletClick,
} = useShipping();
const {
onGetDealQrPdfClick,
onGetPalletsPdfClick,
onGetBoxesPdfClick,
} = useShippingQrs();
const getButton = (label: string, func: () => void, icon?: ReactNode) => {
return (
<Button
variant={"default"}
onClick={func}
>
<Group gap={rem(10)}>
{icon}
{label}
</Group>
</Button>
);
};
return (
<Stack h={"94vh"}>
<Group>
{getButton("Добавить паллет", onCreatePalletClick)}
{getButton("Добавить короб", onCreateBoxInDealClick)}
{getButton("Сделка", onGetDealQrPdfClick, <IconQrcode />)}
{getButton("Паллеты", onGetPalletsPdfClick, <IconPrinter />)}
{getButton("Короба", onGetBoxesPdfClick, <IconPrinter />)}
</Group>
<ScrollArea>
<ShippingTree />
</ScrollArea>
</Stack>
);
};
export default ShippingTab;

View File

@@ -0,0 +1,87 @@
import useShippingTableColumns from "../hooks/shippingTableColumns.tsx";
import { BaseTable } from "../../../../../components/BaseTable/BaseTable.tsx";
import { BoxSchema, ShippingService } from "../../../../../client";
import { ActionIcon, Flex, Tooltip } from "@mantine/core";
import { IconEdit, IconTrash } from "@tabler/icons-react";
import { MRT_TableOptions } from "mantine-react-table";
import { modals } from "@mantine/modals";
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import useUpdateDeal from "../hooks/useUpdateDeal.tsx";
import { notifications } from "../../../../../shared/lib/notifications.ts";
type Props = {
items: BoxSchema[];
}
const BoxesTable = ({ items }: Props) => {
const columns = useShippingTableColumns<BoxSchema>();
const { update } = useUpdateDeal();
const { selectedDeal: deal } = useDealPageContext();
const onDeleteClick = (box: BoxSchema) => {
ShippingService.deleteBox({
boxId: box.id,
})
.then(({ ok, message }) => {
notifications.guess(ok, { message });
if (ok) update();
})
.catch(err => console.log(err));
};
const onEditClick = (box: BoxSchema) => {
if (!deal) return;
modals.openContextModal({
modal: "shippingProductModal",
title: "Редактирование короба",
withCloseButton: false,
innerProps: {
deal,
updateOnSubmit: update,
isBox: true,
shippingData: {
boxId: box.id,
productId: box.product.id,
quantity: box.quantity,
},
},
});
};
return (
<BaseTable
data={items}
columns={columns}
restProps={
{
enableSorting: false,
enableColumnActions: false,
enableRowActions: true,
enableRowNumbers: true,
positionActionsColumn: "last",
renderRowActions: ({ row }) => (
<Flex gap="md">
<Tooltip label="Удалить">
<ActionIcon
onClick={() => onDeleteClick(row.original)}
variant={"default"}>
<IconTrash />
</ActionIcon>
</Tooltip>
<Tooltip label="Редактировать">
<ActionIcon
onClick={() => onEditClick(row.original)}
variant={"default"}>
<IconEdit />
</ActionIcon>
</Tooltip>
</Flex>
),
} as MRT_TableOptions<BoxSchema>
}
/>
);
};
export default BoxesTable;

View File

@@ -0,0 +1,87 @@
import useShippingTableColumns from "../hooks/shippingTableColumns.tsx";
import { BaseTable } from "../../../../../components/BaseTable/BaseTable.tsx";
import { ShippingProductSchema, ShippingService } from "../../../../../client";
import { ActionIcon, Flex, Tooltip } from "@mantine/core";
import { IconEdit, IconTrash } from "@tabler/icons-react";
import { MRT_TableOptions } from "mantine-react-table";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import useUpdateDeal from "../hooks/useUpdateDeal.tsx";
import { modals } from "@mantine/modals";
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
type Props = {
items: ShippingProductSchema[];
}
const ShippingProductsTable = ({ items }: Props) => {
const columns = useShippingTableColumns<ShippingProductSchema>();
const { update } = useUpdateDeal();
const { selectedDeal: deal } = useDealPageContext();
const onDeleteClick = (shippingProduct: ShippingProductSchema) => {
ShippingService.deleteShippingProduct({
shippingProductId: shippingProduct.id,
})
.then(({ ok, message }) => {
notifications.guess(ok, { message });
update();
})
.catch(err => console.log(err));
};
const onEditClick = (shippingProduct: ShippingProductSchema) => {
if (!deal) return;
modals.openContextModal({
modal: "shippingProductModal",
title: "Редактирование товара на паллете",
withCloseButton: false,
innerProps: {
deal,
updateOnSubmit: update,
isBox: false,
shippingData: {
shippingProductId: shippingProduct.id,
productId: shippingProduct.product.id,
quantity: shippingProduct.quantity,
}
},
});
};
return (
<BaseTable
data={items}
columns={columns}
restProps={
{
enableSorting: false,
enableColumnActions: false,
enableRowActions: true,
enableRowNumbers: true,
positionActionsColumn: "last",
renderRowActions: ({ row }) => (
<Flex gap="md">
<Tooltip label="Удалить">
<ActionIcon
onClick={() => onDeleteClick(row.original)}
variant={"default"}>
<IconTrash />
</ActionIcon>
</Tooltip>
<Tooltip label="Редактировать">
<ActionIcon
onClick={() => onEditClick(row.original)}
variant={"default"}>
<IconEdit />
</ActionIcon>
</Tooltip>
</Flex>
),
} as MRT_TableOptions<ShippingProductSchema>
}
/>
);
};
export default ShippingProductsTable;

View File

@@ -0,0 +1,151 @@
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import { Accordion, ActionIcon, Button, Center, Group, rem, Stack, Title, Tooltip } from "@mantine/core";
import { BoxSchema, PalletSchema, ShippingProductSchema } from "../../../../../client";
import ShippingProductsTable from "./ShippingProductsTable.tsx";
import BoxesTable from "./BoxesTable.tsx";
import { IconBox, IconPlus, IconSpace, IconTrash } from "@tabler/icons-react";
import useShipping from "../hooks/useShipping.tsx";
const ShippingTree = () => {
const { selectedDeal: deal } = useDealPageContext();
const {
onCreateBoxInPallet,
onCreateShippingProduct,
onDeletePalletClick,
palletIds,
} = useShipping();
const sortById = (data?: PalletSchema[] | BoxSchema[] | ShippingProductSchema[]) => {
return data?.sort((a, b) => a.id - b.id);
};
const getPallets = () => {
const sortedPallets = sortById(deal?.pallets) as PalletSchema[];
const pallets = sortedPallets?.map(((pallet, index) => {
palletIds.push(pallet.id.toString());
return (
<Accordion.Item key={pallet.id} value={pallet.id.toString()}>
<Center>
<Accordion.Control icon={<IconSpace />}>
Паллет {index + 1}
</Accordion.Control>
{removePalletButton(pallet.id)}
</Center>
<Accordion.Panel>
{getPalletContent(pallet)}
</Accordion.Panel>
</Accordion.Item>
);
})) ?? [];
if (deal?.boxes && deal?.boxes.length > 0) {
const boxes = deal?.boxes.sort((b1, b2) => (b1.id - b2.id));
const itemValue = "noPallets";
const boxesWithoutPallet = (
<Accordion.Item key={-1} value={itemValue}>
<Accordion.Control icon={<IconBox />}>
Короба без паллетов
</Accordion.Control>
<Accordion.Panel>
<BoxesTable items={boxes} />
</Accordion.Panel>
</Accordion.Item>
);
pallets.unshift(boxesWithoutPallet);
palletIds.push(itemValue);
}
return pallets;
};
const removePalletButton = (palletId: number) => {
return (
<Tooltip label="Удалить паллет">
<ActionIcon
variant={"default"}
onClick={() => onDeletePalletClick(palletId)}
mx={"md"}
>
<IconTrash />
</ActionIcon>
</Tooltip>
);
};
const createBoxOrShippingProductButton = (palletId: number, isBox: boolean) => {
const createButtonLabel = isBox ? "Добавить короб" : "Добавить товар";
return (
<Button
variant={"default"}
onClick={() => {
if (isBox) {
onCreateBoxInPallet(palletId);
} else {
onCreateShippingProduct(palletId);
}
}}
>
<Group gap={rem(5)}>
<IconPlus />
{createButtonLabel}
</Group>
</Button>
);
};
const getPalletContent = (pallet: PalletSchema) => {
const isEmpty = pallet.boxes.length === 0 && pallet.shippingProducts.length === 0;
const isBox = pallet.boxes.length > 0;
const title = isEmpty ? "Пустой" : isBox ? "Короба" : "Товары";
let palletButtons;
if (isEmpty) {
palletButtons = [
createBoxOrShippingProductButton(pallet.id, true),
createBoxOrShippingProductButton(pallet.id, false),
];
} else {
palletButtons = [
createBoxOrShippingProductButton(pallet.id, isBox),
];
}
const boxes = sortById(pallet.boxes) as BoxSchema[];
const shippingProducts = sortById(pallet.shippingProducts) as ShippingProductSchema[];
let table;
if (!isEmpty) {
if (isBox) {
table = (<BoxesTable items={boxes} />);
} else {
table = (<ShippingProductsTable items={shippingProducts} />);
}
}
return (
<Stack gap={rem(5)}>
<Group justify={"space-between"}>
<Title order={6}>{title}</Title>
<Group gap={rem(10)}>
{...palletButtons}
</Group>
</Group>
{table}
</Stack>
);
};
return (
<Accordion
multiple={true}
defaultValue={palletIds}
bd={"solid 1px gray"}
>
{getPallets()}
</Accordion>
);
};
export default ShippingTree;

View File

@@ -0,0 +1,28 @@
import { useMemo } from "react";
import { MRT_ColumnDef, MRT_RowData } from "mantine-react-table";
const useShippingTableColumns = <T extends MRT_RowData>() => {
return useMemo<MRT_ColumnDef<T>[]>(
() => [
{
header: "Название",
accessorKey: "product.name",
},
{
header: "Артикул",
accessorKey: "product.article",
},
{
header: "Размер",
accessorKey: "product.size",
},
{
header: "Количество",
accessorKey: "quantity",
},
],
[],
);
};
export default useShippingTableColumns;

View File

@@ -0,0 +1,108 @@
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import { ShippingService } from "../../../../../client";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { modals } from "@mantine/modals";
import { Text } from "@mantine/core";
import useUpdateDeal from "./useUpdateDeal.tsx";
const useShipping = () => {
const { selectedDeal: deal } = useDealPageContext();
const { update } = useUpdateDeal();
const palletIds: string[] = [];
const onCreatePalletClick = () => {
if (!deal) return;
ShippingService.createPallet({
dealId: deal.id,
})
.then(({ ok, message }) => {
notifications.guess(ok, { message });
update();
})
.catch(err => console.log(err));
};
const onDeletePallet = (palletId: number) => {
ShippingService.deletePallet({
palletId: palletId,
})
.then(({ ok, message }) => {
if (!ok) notifications.guess(ok, { message });
update();
})
.catch(err => console.log(err));
};
const onDeletePalletClick = (palletId: number) => {
if (!deal) return;
modals.openConfirmModal({
title: "Удаление паллета",
children: <Text size="sm">Вы уверены что хотите удалить паллет?</Text>,
labels: { confirm: "Да", cancel: "Нет" },
confirmProps: { color: "red" },
onConfirm: () => onDeletePallet(palletId),
});
};
const openShippingModal = (
title: string,
isBox: boolean,
palletId?: number,
dealId?: number,
) => {
if (!deal) return;
modals.openContextModal({
modal: "shippingProductModal",
title,
withCloseButton: false,
innerProps: {
deal,
updateOnSubmit: update,
isBox,
shippingData: {
dealId,
palletId,
productId: null,
quantity: null,
},
},
});
};
const onCreateBoxInDealClick = () => {
openShippingModal(
"Добавление короба",
true,
undefined,
deal?.id,
);
};
const onCreateBoxInPallet = (palletId: number) => {
openShippingModal(
"Добавление короба",
true,
palletId,
);
};
const onCreateShippingProduct = (palletId: number) => {
openShippingModal(
"Добавление товара на паллет",
false,
palletId,
);
};
return {
onCreateBoxInDealClick,
onCreateBoxInPallet,
onCreateShippingProduct,
onCreatePalletClick,
onDeletePalletClick,
palletIds,
};
};
export default useShipping;

View File

@@ -0,0 +1,35 @@
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
const useShippingQrs = () => {
const { selectedDeal: deal } = useDealPageContext();
const basePdfUrl = `${import.meta.env.VITE_API_URL}/shipping/pdf`;
const getPdf = (url: string) => {
if (!deal) return;
const pdfWindow = window.open(url);
if (!pdfWindow) return;
pdfWindow.print();
};
const onGetDealQrPdfClick = () => {
getPdf(`${basePdfUrl}/deal/${deal?.id}`);
};
const onGetPalletsPdfClick = () => {
getPdf(`${basePdfUrl}/pallets/${deal?.id}`);
};
const onGetBoxesPdfClick = () => {
getPdf(`${basePdfUrl}/boxes/${deal?.id}`);
};
return {
onGetDealQrPdfClick,
onGetPalletsPdfClick,
onGetBoxesPdfClick,
};
};
export default useShippingQrs;

View File

@@ -0,0 +1,18 @@
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import { DealService } from "../../../../../client";
const useUpdateDeal = () => {
const { selectedDeal: deal, setSelectedDeal } = useDealPageContext();
const update = () => {
if (!deal) return;
DealService.getDealById({ dealId: deal.id })
.then(data => {
setSelectedDeal(data);
});
};
return { update };
};
export default useUpdateDeal;

View File

@@ -0,0 +1,156 @@
import { useForm } from "@mantine/form";
import { ContextModalProps } from "@mantine/modals";
import { Button, Flex, NumberInput, rem, Select, Text } from "@mantine/core";
import getRestProducts from "../utils/getRestProducts.tsx";
import {
CreateBoxInDealSchema,
CreateBoxInPalletSchema,
CreateShippingProductSchema,
DealProductSchema,
DealSchema,
ShippingService,
UpdateBoxSchema,
UpdateShippingProductSchema,
} from "../../../../../client";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { ShippingData, ShippingModalForm, ShippingProductOption } from "../types/ShippingProductData.tsx";
import { useEffect, useState } from "react";
type Props = {
updateOnSubmit: () => void;
deal: DealSchema;
isBox: boolean;
shippingData: Partial<ShippingData>;
}
const ShippingProductModal = ({
context,
id,
innerProps,
}: ContextModalProps<Props>) => {
const [restProducts, setRestProducts] = useState<Map<number, DealProductSchema>>(new Map());
const [restProductsSelectData, setRestProductSelectData] = useState<ShippingProductOption[]>([]);
const getRestProductQuantity = () => {
if (form.values.productId) {
const restProduct = restProducts.get(Number(form.values.productId));
if (restProduct) {
return restProduct.quantity;
}
}
return 10000;
};
const initialValues: ShippingModalForm = {
quantity: innerProps.shippingData.quantity ?? 0,
productId: innerProps.shippingData.productId,
};
const form = useForm<ShippingModalForm>({
initialValues,
validate: {
productId: productId => !productId && "Необходимо выбрать товар",
quantity: quantity => quantity > getRestProductQuantity() ? "Слишком много товара" :
quantity === 0 && "Слишком мало товара",
},
});
useEffect(() => {
const data = getRestProducts({
deal: innerProps.deal,
unaccountedValues: innerProps.shippingData as UpdateShippingProductSchema | UpdateBoxSchema,
});
setRestProducts(data.restProducts);
setRestProductSelectData(data.restProductsSelectData);
}, [innerProps.deal]);
const updateBox = () => {
const data = {
...innerProps.shippingData,
...form.values,
} as CreateBoxInPalletSchema | CreateBoxInDealSchema | UpdateBoxSchema;
ShippingService.updateBox({
requestBody: { data },
})
.then(({ ok, message }) => {
notifications.guess(ok, { message: message });
innerProps.updateOnSubmit();
if (ok) context.closeContextModal(id);
})
.catch(err => console.log(err));
};
const updateShippingProduct = () => {
const data = {
...innerProps.shippingData,
...form.values,
} as CreateShippingProductSchema | UpdateShippingProductSchema;
ShippingService.updateShippingProduct({
requestBody: { data },
})
.then(({ ok, message }) => {
notifications.guess(ok, { message: message });
innerProps.updateOnSubmit();
if (ok) context.closeContextModal(id);
})
.catch(err => console.log(err));
};
const onSubmit = () => {
if (innerProps.isBox) {
updateBox();
} else {
updateShippingProduct();
}
};
const getRestQuantityText = () => {
if (!form.values.productId) return;
const restQuantityInDeal = getRestProductQuantity();
const restQuantity = restQuantityInDeal - form.values.quantity;
if (restQuantity >= 0) {
return <Text>Осталось распределить {restQuantity} шт.</Text>;
}
return <Text>Введено слишком большое количество.<br />Доступно {restQuantityInDeal} шт.</Text>;
};
return (
<form onSubmit={form.onSubmit(() => onSubmit())}>
<Flex
direction={"column"}
gap={rem(10)}
>
<Select
data={restProductsSelectData}
label={"Товар"}
placeholder={"Выберите товар"}
{...form.getInputProps("productId")}
value={form.values.productId?.toString()}
/>
{getRestQuantityText()}
<NumberInput
label={"Количество"}
hideControls
{...form.getInputProps("quantity")}
min={0}
/>
<Button
variant={"default"}
type={"submit"}
>
Сохранить
</Button>
</Flex>
</form>
);
};
export default ShippingProductModal;

View File

@@ -0,0 +1,24 @@
import {
CreateBoxInDealSchema,
CreateBoxInPalletSchema,
CreateShippingProductSchema,
UpdateBoxSchema,
UpdateShippingProductSchema,
} from "../../../../../client";
export type ShippingModalForm = {
quantity: number;
productId?: number | null;
}
export type ShippingProductOption = {
value: string;
label: string;
}
export type ShippingData =
CreateBoxInDealSchema
| CreateBoxInPalletSchema
| UpdateBoxSchema
| CreateShippingProductSchema
| UpdateShippingProductSchema;

View File

@@ -0,0 +1,78 @@
import { ShippingProductOption } from "../types/ShippingProductData.tsx";
import { DealProductSchema, DealSchema, ProductSchema } from "../../../../../client";
type UnaccountedValues = {
boxId?: number | null;
shippingProductId?: number | null;
}
type Props = {
deal?: DealSchema;
unaccountedValues: UnaccountedValues;
}
const getRestProducts = ({
deal,
unaccountedValues,
}: Props) => {
const totalProducts = new Map(
deal?.products.map(product => [product.product.id, product]),
);
const distributedProducts = new Map();
const accountProduct = (product: ProductSchema, quantity: number) => {
const productId = product.id;
if (distributedProducts.has(productId)) {
const prodData = distributedProducts.get(productId);
distributedProducts.set(productId, { product, quantity: quantity + prodData.quantity });
} else {
distributedProducts.set(productId, { product, quantity });
}
};
deal?.boxes?.forEach((box) => {
if (box.id === unaccountedValues.boxId) return;
accountProduct(box.product, box.quantity);
});
deal?.pallets?.forEach(pallet => {
pallet.shippingProducts.forEach(shippingProduct => {
if (shippingProduct.id === unaccountedValues.shippingProductId) return;
accountProduct(shippingProduct.product, shippingProduct.quantity);
});
pallet.boxes.forEach((box) => {
if (box.id === unaccountedValues.boxId) return;
accountProduct(box.product, box.quantity);
});
});
const restProducts = new Map<number, DealProductSchema>();
totalProducts.entries().forEach(([key, product]) => {
const distributedProduct = distributedProducts.get(key);
if (distributedProduct) {
if (product.quantity > distributedProduct.quantity) {
const restQuantity = product.quantity - distributedProduct.quantity;
restProducts.set(key, { ...product, quantity: restQuantity });
}
} else {
restProducts.set(key, product);
}
});
const restProductsSelectData: ShippingProductOption[] = [];
restProducts.forEach(
(restProduct, id) => {
restProductsSelectData.push({ value: String(id), label: restProduct.product.name });
},
);
return {
restProducts,
restProductsSelectData,
};
};
export default getRestProducts;