import { useDispatch } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { getSession } from '../../Services/Others'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Messages } from '../../Components/Notifications/Messages'; import { changeBreadCrumb } from '../../Features/AppPage/CenterPage'; import { Tables } from '../../Components/Tables/Table'; import Search from '../../Components/Forms/Search'; import FormHeader from '../PageComponents/FormHeader'; import { Input, Form, DatePicker, Collapse, Tooltip } from 'antd'; import { IoEye } from 'react-icons/io5'; import './Dispatch.scss'; import "../../Styles/BookingScreen/Components/SelectionComponent/SelectionComponent.scss" import { DefaultModal } from '../../Components/Modal/DefaultModal'; import { getRequestedStockQty, postDispatchStock, getPendingAndCompletedDispatches, getDispatchSummary, } from '../../Features/StockTransfer/StockTransfer'; import { ArrowRightOutlined, PrinterFilled } from '@ant-design/icons'; import Buttons from '../../Components/Forms/Buttons'; import { isMobile } from 'react-device-detect'; import { printDiv } from '../../Services/WSOthers'; import { getPrintSelectionComponentData } from '../../Features/ThemeChange/ThemeChange'; import DeliveryPrint from '../DeliveryChallan/DeliveryPrint'; import { DCPrintStyleFunction } from '../DeliveryChallan/DCPrintStyleFunction'; // import { IoEye } from "react-icons/io5"; const subDirectory = import.meta.env.BASE_URL; const items = [ { name: 'Home', link: `${subDirectory}app-page/home`, }, { name: 'Stock Dispatch', link: `${subDirectory}setting/stock-dispatch`, }, ]; const Dispatch = () => { const formatDate = (dateString = '') => { const date = new Date(dateString); const day = date.getDate().toString().padStart(2, '0'); const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const month = months[date.getMonth()]; const year = date.getFullYear(); return day && month && year ? `${day}-${month}-${year}` : '-'; }; const formatTime12 = (dateString = '') => { if (!dateString) return '-'; const date = new Date(dateString); if (isNaN(date)) return '-'; let hours = date.getHours(); const minutes = date.getMinutes().toString().padStart(2, '0'); const ampm = hours >= 12 ? 'PM' : 'AM'; hours = hours % 12 || 12; return `${hours}:${minutes} ${ampm}`; }; const queueColumns = [ { title: 'SL.NO', dataIndex: 'slno', key: 'slno', align: 'center', width: '80px', render: (text, record, index) => ( {(page - 1) * 10 + index + 1} ), }, { title: 'Queue No', dataIndex: 'RequestId', key: 'RequestId', }, { title: 'Queue Date', dataIndex: 'CreatedDate', key: 'CreatedDate', render: (text) => formatDate(text), }, { title: 'Requested From', dataIndex: 'FromLocationName', key: 'FromLocationName', }, { title: 'Requested By', dataIndex: 'RequestByName', key: 'RequestByName', align: 'center', }, { title: 'View', dataIndex: 'view', key: 'view', align: 'center', render: (text, record) => ( {} : () => viewProductDetails(record.ProductDetail) } /> ), }, { title: 'Action', dataIndex: 'action', key: 'action', align: 'center', render: (text, record) => (
{} : () => openDispatchModal(record.ProductDetail, record) } > Dispatch
), }, ]; const dispatchedColumns = [ { title: 'SL.NO', dataIndex: 'slno', key: 'slno', align: 'center', width: '60px', render: (text, record, index) => index + 1, }, { title: 'Request Id', dataIndex: 'RequestId', key: 'RequestId', }, { title: 'Dispatch No', dataIndex: 'DispatchId', key: 'DispatchId', }, { title: 'Dispatch Date', dataIndex: 'CreatedDate', key: 'CreatedDate', render: (text) => formatDate(text), }, { title: 'Branch Name', dataIndex: 'ToBranchName', key: 'ToBranchName', }, { title: "Receiver's Name", dataIndex: 'ReceiverName', key: 'ReceiverName', align: 'center', }, { title: 'Total Items Accepted', dataIndex: 'TotalItemsAccepted', key: 'TotalItemsAccepted', align: 'center', render: (text, record, index) => record?.ProductDetails?.filter((prod) => prod?.AcceptedQty > 0)?.length, }, { title: 'Total Qty Accepted', dataIndex: 'TotalItemsAccepted', key: 'TotalItemsAccepted', align: 'center', render: (text, record) => record?.ProductDetails?.reduce( (acc, item) => acc + (Number(item?.AcceptedQty) || 0), 0 ) || 0, }, { title: 'View', dataIndex: 'view', key: 'view', align: 'center', render: (text, record) => ( openCompleteModal(record.ProductDetails)} /> ), }, ]; const navigate = useNavigate(); const dispatch = useDispatch(); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserId = getSession('UserId'); const UserType = getSession('UserType'); const formRef = useRef(null); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [dispatchData, setDispatchData] = useState([]); const [deliveryData, setDeliveryData] = useState(null); const totalQty = deliveryData?.ProductDetails?.reduce((sum, p) => sum + (p.DispatchedQty || 0), 0) || 0; console.log(dispatchData, 'dispatchData'); const [filteredInfo, setFilteredInfo] = useState({}); const [searchedText, setSearchedText] = useState(''); const [sortedInfo, setSortedInfo] = useState({}); const [page, setpage] = useState(1); const [prodDtlsPage, setProdDtlsPage] = useState(1); const [isDispatchQueue, setIsDispatchQueue] = useState('queue'); const [viewModalVisible, setViewModalVisible] = useState(false); const [dispatchModalVisible, setDispatchModalVisible] = useState(false); const [selectedProducts, setSelectedProducts] = useState([]); const [dispatchProducts, setDispatchProducts] = useState([]); const [allocatedDispatch, setAllocatedDispatch] = useState([]); const [dateRange, setDateRange] = useState([]); const [originalData, setOriginalData] = useState([]); const [count, setCount] = useState(null); const [printStyle, setPrintStyle] = useState(null); const [printTemplateDtl, setPrintTemplateDtl] = useState(null); const [transportMode, setTransportMode] = useState(''); const [vehicleNumber, setVehicleNumber] = useState(''); const [driverMobile, setDriverMobile] = useState(''); const [driverLicense, setDriverLicense] = useState(''); const [completeModalVisible, setCompleteModalVisible] = useState(false); const [completeProducts, setCompleteProducts] = useState([]); const [remarks, setRemarks] = useState({}); const [allocateModalVisible, setAllocateModalVisible] = useState(false); const [currentProduct, setCurrentProduct] = useState(null); const [currentProductIndex, setCurrentProductIndex] = useState(null); const [allocatedStocks, setAllocatedStocks] = useState({}); const [initialFetch, setInitialFetch] = useState(true); console.log(dateRange, 'dateRange'); useEffect(() => { try { dispatch(changeBreadCrumb({ items: items })); fetchData(); } catch (error) { console.log(error); } }, [isDispatchQueue]); // useEffect(() => { // if (!initialFetch) { // fetchData(); // } // }, [dateRange]) useEffect(() => { filterData(searchedText); }, [originalData]); useEffect(() => { getPrintData(); }, []); const onSearch = (value) => { setSearchedText(value); filterData(value); }; const onSearchChange = (e) => { const value = e?.target?.value; setSearchedText(value); filterData(value); }; const filterData = (searchText) => { if (!searchText) { setDispatchData(originalData); return; } const filtered = originalData.filter((item) => { const searchLower = searchText.toLowerCase(); // Filter by branch name const branchName = ( isDispatchQueue === 'queue' ? item.FromLocationName : item?.ToBranchName || '' ).toLowerCase(); if (branchName.includes(searchLower)) return true; // Filter by ID numbers based on current tab if (isDispatchQueue === 'queue') { const queueNo = ( item.RequestId || item.FromLocationName || '' ).toLowerCase(); if (queueNo.includes(searchLower)) return true; } else if (isDispatchQueue === 'transit') { const transitNo = ( item.RequestId || item.DispatchId || item?.ToBranchName || '' ).toLowerCase(); if (transitNo.includes(searchLower)) return true; } else if (isDispatchQueue === 'dispatched') { const dispatchNo = ( item.RequestId || item.DispatchId || item?.ToBranchName || '' ).toLowerCase(); if (dispatchNo.includes(searchLower)) return true; } return false; }); setpage(1); setDispatchData(filtered); }; const fetchData = async (fromDate = null, toDate = null) => { try { let data; if (isDispatchQueue === 'queue') { // Call dispatch queue API const response = await dispatch( getRequestedStockQty({ CompId, BranchId, AppId, UserId, UserType, fromDate, toDate, }) )?.unwrap(); if (response?.data?.statusCode === 1) { const filteredData = response?.data?.data?.filter((parent) => parent?.ProductDetail?.some((item) => Number(item?.PendingQty) >= 1) ); data = filteredData || response?.data?.data || []; } else { data = []; } // data = queueSampleData; } else if (isDispatchQueue === 'dispatched') { // Call dispatched API const response = await dispatch( getPendingAndCompletedDispatches({ CompId, BranchId, AppId, Type: 'C', fromDate, toDate, }) )?.unwrap(); if (response?.data?.statusCode === 1) { data = response?.data?.data || []; } else { data = []; } } else if (isDispatchQueue === 'transit') { const response = await dispatch( getPendingAndCompletedDispatches({ CompId, BranchId, AppId, Type: 'P', fromDate, toDate, }) )?.unwrap(); if (response?.data?.statusCode === 1) { data = response?.data?.data || []; } else { data = []; } } const res = await dispatch( getDispatchSummary({ CompId, BranchId, AppId, fromDate, toDate }) )?.unwrap(); if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) { console?.log(res?.data?.data, 'res?.data?.data'); setCount(res?.data?.data?.[0]); } else { setCount(null); } setOriginalData(data); setDispatchData(data); setInitialFetch(false); } catch (error) { console.log(error); } }; const handleToggleChange = (checked) => { setIsDispatchQueue(checked); }; const handleChange = (pagination, filters, sorter) => { setFilteredInfo(filters); setSortedInfo(sorter); }; const handlePageChange = (current) => { setpage(current); }; const handleProdDtlsPageChange = (current) => { setProdDtlsPage(current); }; const convertRangeToYYYYMMDD = (dates) => { if (!dates || dates.length !== 2) return []; return dates.map((d) => d?.format('YYYY-MM-DD')); }; const handleDateRangeChange = async (dates) => { setDateRange(dates); if (dates && dates.length === 2) { const [startDate, endDate] = convertRangeToYYYYMMDD(dates); if (startDate && endDate) { await fetchData(startDate, endDate); } // const dateField = // isDispatchQueue === 'queue' // ? 'CreatedDate' : isDispatchQueue === 'transit' // ? 'transit_date' // : 'dispatch_date'; // const start = new Date(startDate); // start.setHours(0, 0, 0, 0); // const end = new Date(endDate); // end.setHours(23, 59, 59, 999); // const filtered = originalData.filter(item => { // const itemDate = new Date(item[dateField]); // return itemDate >= start && itemDate <= end; // }); // setDispatchData(filtered); } else { await fetchData(); } }; const transitColumns = [ { title: 'SL.NO', dataIndex: 'slno', key: 'slno', align: 'center', width: '60px', render: (text, record, index) => index + 1, }, { title: 'Request Id', dataIndex: 'RequestId', key: 'RequestId', }, { title: 'Dispatch No', dataIndex: 'DispatchId', key: 'DispatchId', }, { title: 'Transit Date', dataIndex: 'CreatedDate', key: 'CreatedDate', align: 'center', render: (text) => formatDate(text), }, { title: 'Transit Time', dataIndex: 'CreatedDate', key: 'CreatedDate', align: 'right', render: (text) => formatTime12(text), }, { title: 'Dispatched To', dataIndex: 'ToBranchName', key: 'ToBranchName', align: 'center', }, { title: 'Dispatched By', dataIndex: 'DispatcherName', key: 'DispatcherName', }, { title: 'View', dataIndex: 'view', key: 'view', align: 'center', render: (text, record) => ( viewProductDetails(record.ProductDetails)} /> ), }, { title: 'Print', key: 'Print', dataIndex: 'Print', width: '60px', align: 'center', render: (_, record) => ( generateDeliveryChallan(record)} /> ), }, ]; const generateDeliveryChallan = async (record) => { setDeliveryData([{ ...record, dispatchPrint: true }]); const DCstyle = await DCPrintStyleFunction( (printStyle == undefined || printStyle === 'TaxInvoice') ? 'Style 13' : printStyle); const stylesMap = { 'Style 1': 'DCPrintStyle1', 'Style 2': 'DCPrintStyle2', 'Style 3': 'DCPrintStyle3', 'Style 4': 'DCPrintStyle4', 'Style 5': 'DCPrintStyle5', 'Style 6': 'DCPrintStyle6', 'Style 7': 'DCPrintStyle7', 'Style 8': 'DCPrintStyle8', 'Style 9': 'DCPrintStyle9', 'Style 10': 'DCPrintStyle10', 'Style 11': 'DCPrintStyle11', 'Style 12': 'DCPrintStyle12', 'Style 13': 'DC-Default-Print', A4: 'DCPrintStyleA4', A5: 'DCPrintStyleA5', A4Standard: 'DCPrintStyleA4Standard', }; const selectedStyle = stylesMap[ (printStyle == undefined || printStyle === 'TaxInvoice') ? 'Style 13' : printStyle ]; console.log(selectedStyle, DCstyle, 'selectedStyle'); setTimeout(() => { printDiv(`${selectedStyle}`, DCstyle); }, 100); }; const getPrintData = async () => { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, }; let response = await dispatch(getPrintSelectionComponentData(data)).unwrap(); if (response?.data?.statusCode === 1) { let DCPrintTemplate = response?.data?.data?.[0]?.ComponentDetails?.find( (item) => item.SetasDefault == 'Y' && item.PrintTypeName === 'Delivery Chalan' ); console.log(DCPrintTemplate, response?.data?.data?.[0]?.ComponentDetails?.find( (item) => item.SetasDefault == 'Y' && item.PrintTypeName === 'Delivery Chalan' ), 'DCPrintTemplate'); setPrintStyle(DCPrintTemplate?.StyleName); setPrintTemplateDtl(DCPrintTemplate); } }; const openCompleteModal = (products) => { setCompleteProducts(products); setCompleteModalVisible(true); }; const handleRemarksChange = (index, value) => { setRemarks((prev) => ({ ...prev, [index]: value })); }; const completeColumns = [ { title: 'S.No', dataIndex: 'slno', key: 'slno', align: 'center', width: '60px', render: (text, record, index) => index + 1, }, { title: 'Product Name', dataIndex: 'ProdName', key: 'ProdName', width: 150, }, { title: 'Variant Name', dataIndex: 'RequestVariantName', key: 'RequestVariantName', width: 150, }, { title: 'QTY', children: [ { title: 'Dispatched', dataIndex: 'DispatchedQty', key: 'DispatchedQty', align: 'right', width: 100, }, { title: 'Delivered', dataIndex: 'ReceivedQty', key: 'ReceivedQty', align: 'right', width: 100, }, { title: 'Accepted', dataIndex: 'AcceptedQty', key: 'AcceptedQty', align: 'right', width: 100, }, // { // title: 'Received', // dataIndex: 'receivedQty', // key: 'receivedQty', // align: 'right', // width: 100, // }, ], }, // { // title: 'Remarks', // dataIndex: 'remarks', // key: 'remarks', // width: 200, // render: (text, record, index) => ( // record.dispatchedQty !== record.acceptedQty ? // handleRemarksChange(index, e.target.value)} // /> : null // ) // } ]; const viewProductDetails = (products) => { const productDetails = isDispatchQueue === 'queue' ? products?.filter((prod) => prod?.PendingQty > 0) : products; setSelectedProducts(productDetails); setViewModalVisible(true); }; const openDispatchModal = (products, record) => { const productsWithDispatchQty = products ?.filter((prod) => prod?.PendingQty > 0) .map((product) => ({ ...product, requestId: record?.RequestId, toLocationId: record?.FromLocationId, })); setDispatchProducts(productsWithDispatchQty); setDispatchModalVisible(true); }; const openAllocateModal = (product, index) => { // Check if ProdVariantDetails is an array if (!Array.isArray(product?.ProdVariantDetails)) { console.error('ProdVariantDetails is not an array'); return; } // Check if at least one variant has StockDetails with length > 1 const hasValidStockDetails = product.ProdVariantDetails.some( (variant) => Array.isArray(variant?.StockDetails) && variant.StockDetails.length > 0 ); if (!hasValidStockDetails) { // console.error('No variant found with StockDetails length > 1'); setMessageData( 'This product cannot be allocated. No valid stock details found.' ); setMessageType('error'); // Optionally show a user-friendly message // alert('This product cannot be allocated. No valid stock details found.'); return; } // Proceed with setting state if validation passes setCurrentProduct({ ...product, ProdVariantDetails: product?.ProdVariantDetails?.map((variant) => ({ ...variant, RequestId: product?.requestId, })), }); setCurrentProductIndex(index); setAllocateModalVisible(true); }; const handleStockAllocation = (value, balanceQty, inwardDtlId, requestId) => { const numericValue = parseInt(value || 0, 10); if (isNaN(numericValue) || numericValue < 0) return; if (numericValue > balanceQty) { setMessageType('error'); setMessageData(`Cannot exceed available qty of ${balanceQty}`); return; } const productKey = `${currentProduct.ProdId}_${currentProductIndex}`; const updatedAllocations = { ...allocatedStocks }; if (!updatedAllocations[productKey]) { updatedAllocations[productKey] = {}; } const stockKey = `${requestId}_${inwardDtlId}`; updatedAllocations[productKey][stockKey] = numericValue; const totalAllocated = Object.values(updatedAllocations[productKey]).reduce( (sum, qty) => sum + qty, 0 ); if (totalAllocated > currentProduct.PendingQty) { setMessageType('error'); setMessageData( `Total allocated quantity cannot exceed pending quantity of ${currentProduct.PendingQty}` ); updatedAllocations[productKey][stockKey] = 0; return; } setAllocatedStocks(updatedAllocations); }; const submitAllocation = () => { const productKey = `${currentProduct.ProdId}_${currentProductIndex}`; const allocations = allocatedStocks[productKey] || {}; const totalAllocated = Object.values(allocations).reduce( (sum, qty) => sum + qty, 0 ); const updatedProducts = [...dispatchProducts]; updatedProducts[currentProductIndex].dispatchQty = totalAllocated; setDispatchProducts(updatedProducts); setAllocatedDispatch((prev) => { let updated = [...prev]; Object.entries(allocations).forEach(([key, qty]) => { const [, inwardDtlId] = key.split('_'); // take second part if (!inwardDtlId) return; const index = updated.findIndex( (item) => item.InwardDtlId === inwardDtlId ); if (index !== -1) { // update existing updated[index] = { ...updated[index], dispatchQty: qty, }; } else { // push new updated.push({ ProdId: currentProduct?.ProdId, InwardDtlId: inwardDtlId, CreatedBy: UserId, dispatchQty: qty, toLocationId: currentProduct?.toLocationId, RequestId: currentProduct?.requestId, }); } }); return updated; }); setAllocateModalVisible(false); setCurrentProduct(null); setCurrentProductIndex(null); }; const getTotalAllocatedQty = () => { if (!currentProduct) return 0; const productKey = `${currentProduct.ProdId}_${currentProductIndex}`; const allocations = allocatedStocks[productKey] || {}; return Object.values(allocations).reduce((sum, qty) => sum + qty, 0); }; const handleDispatchSubmit = async () => { try { if ( allocatedDispatch?.filter( (prod) => parseFloat(prod?.dispatchQty) || 0 > 0 )?.length === 0 ) { setMessageType('warning'); setMessageData('No products to dispatch'); return; } let data = { RequestId: allocatedDispatch?.[0]?.RequestId, AppId: AppId, CompId: CompId, FromLocationId: BranchId, ToLocationId: allocatedDispatch?.[0]?.toLocationId, DispatchStatus: '', DispatchStockDetails: allocatedDispatch ?.filter((prod) => parseFloat(prod?.dispatchQty) || 0 > 0) ?.map((prod) => ({ ProdId: prod?.ProdId, InwardDtlId: prod?.InwardDtlId, DispatchedQty: parseFloat(prod?.dispatchQty) || 0, CreatedBy: UserId, })), CreatedBy: UserId, }; console.log(data, 'dispatchingdata'); const res = await dispatch(postDispatchStock(data))?.unwrap(); if (res?.data?.statusCode === 1) { setMessageData(res?.data?.response); setMessageType('success'); } else { throw new Error(res?.data?.response); } console.log(res?.data, 'response'); await fetchData(); setDispatchModalVisible(false); setAllocatedDispatch([]); setAllocatedStocks({}); setCurrentProduct(null); setDispatchProducts([]); formRef?.current?.resetFields(); } catch (error) { console.log(error); setMessageType('error'); setMessageData('Failed to submit dispatch'); } }; const viewColumns = [ { title: 'SL.NO', dataIndex: 'index', key: 'index', align: 'center', width: '60px', render: (text, record, index) => ( {(prodDtlsPage - 1) * 10 + index + 1} ), }, { title: 'Product Name', dataIndex: 'ProdName', key: 'ProdName', }, { title: 'Requested Variant', dataIndex: 'RequestVariantName', key: 'RequestVariantName', }, { title: isDispatchQueue ? 'Requested Qty' : 'Requested Qty', dataIndex: isDispatchQueue === 'queue' ? 'RequestQty' : 'RequestedQty', key: isDispatchQueue === 'queue' ? 'RequestQty' : 'RequestedQty', align: 'right', }, ...(isDispatchQueue === 'queue' ? [ { title: isDispatchQueue ? 'Pending Qty' : 'Pending Qty', dataIndex: isDispatchQueue === 'queue' ? 'PendingQty' : 'PendingQty', key: isDispatchQueue === 'queue' ? 'PendingQty' : 'PendingQty', align: 'right', }, ] : []), ...(isDispatchQueue === 'queue' ? [] : [ { title: 'Dispatched Qty', dataIndex: 'DispatchedQty', key: 'DispatchedQty', align: 'right', }, ]), ]; const dispatchColumns = [ { title: 'SL.No', dataIndex: 'index', key: 'index', align: 'center', width: '60px', render: (text, record, index) => ( {(prodDtlsPage - 1) * 10 + index + 1} ), }, { title: 'Product Name', dataIndex: 'ProdName', key: 'ProdName', width: '200px', }, { title: 'Requested Variant', dataIndex: 'RequestVariantName', key: 'RequestVariantName', width: '200px', }, { title: 'Requested Qty', dataIndex: 'RequestQty', key: 'RequestQty', align: 'right', width: '130px', }, { title: 'Pending Qty', dataIndex: 'PendingQty', key: 'PendingQty', align: 'right', width: '130px', }, { title: 'Allocated Qty', dataIndex: 'dispatchQty', key: 'dispatchQty', align: 'center', width: '120px', render: (text, record, index) => ( {text || 0} ), }, { title: 'Qty Allocation', key: 'action', align: 'center', width: '120px', render: (text, record, index) => { if (record?.StockAvailable === 'Y') { return (
openAllocateModal(record, index)} > Allocate Qty
); } else if (record?.StockAvailable === 'N') { return ( { if (!value) { return Promise.resolve(); } if (Number(value) > record.RequestQty) { return Promise.reject( new Error( 'Dispatch quantity cannot be greater than requested quantity' ) ); } if (Number(value) < 0) { return Promise.reject( new Error('Dispatch quantity cannot be negative') ); } return Promise.resolve(); }, }, ]} > { let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); // Remove invalid characters const parts = cleanedValue.split('.'); if (cleanedValue.startsWith('.')) { cleanedValue = '0' + cleanedValue; } e.target.value = parts.length > 2 ? `${parts[0]}.${parts.slice(1).join('')}` : cleanedValue; }} min={0} max={record.RequestQty} value={text} onChange={(e) => handleDispatchQtyChange(index, e.target.value, record) } /> ); } }, }, ]; const handleDispatchQtyChange = (idx, value, record) => { const dispatchingQty = value > record?.PendingQty ? '' : value; if ((value || 0) > record?.PendingQty) { setMessageData( 'Dispatch quantity cannot be greater than requested quantity' ); setMessageType('error'); } setDispatchProducts((prevProducts) => { const updatedProducts = [...prevProducts]; updatedProducts[idx].dispatchQty = dispatchingQty; return updatedProducts; }); const inwardDtlId = record?.ProdVariantDetails?.[0]?.StockDetails?.[0]?.InwardDtlId; if (!inwardDtlId) return; setAllocatedDispatch((prev) => { const index = prev?.findIndex((item) => item.InwardDtlId === inwardDtlId); // If exists → update if (index !== -1) { const updated = [...prev]; updated[index] = { ...updated[index], dispatchQty: dispatchingQty, }; return updated; } // Else → push new return [ ...prev, { ProdId: record?.ProdId, InwardDtlId: inwardDtlId, CreatedBy: UserId, dispatchQty: dispatchingQty, toLocationId: record?.toLocationId, RequestId: record?.requestId, }, ]; }); formRef?.current?.setFieldsValue({ [`DispatchQty${record?.requestId}${idx}`]: dispatchingQty, }); }; const onComplete = useCallback(() => { setMessageType(null); setMessageData(null); }, []); return (
{ setDateRange([]); setIsDispatchQueue('queue'); setpage(1); setSearchedText(''); }} > Dispatch Queue {count?.RequestCount > 0 && ( {count?.RequestCount || 0} )}
{ setDateRange([]); setIsDispatchQueue('transit'); setpage(1); setSearchedText(''); }} > In-Transit {count?.PendingCount > 0 && ( {count?.PendingCount || 0} )}
{ setDateRange([]); setIsDispatchQueue('dispatched'); setpage(1); setSearchedText(''); }} > Completed
{/*
*/}
current && current > new Date()} />
{ setViewModalVisible(false); setProdDtlsPage(1); }} footer={null} width={600} children={
} /> { setDispatchModalVisible(false); setAllocatedStocks({}); setAllocatedDispatch([]); setProdDtlsPage(1); formRef?.current?.resetFields(); }} handleSubmit={handleDispatchSubmit} footer={true} width={750} children={ <>
{/*
setVehicleNumber(e.target.value)} />
setDriverMobile(e.target.value)} maxLength={10} /> setDriverLicense(e.target.value)} />
*/}
{ setAllocateModalVisible(false); setCurrentProduct(null); setCurrentProductIndex(null); }} footer={false} width={1000} children={ currentProduct && (
Requested Qty: {currentProduct.RequestQty}
Pending Qty: {currentProduct.PendingQty}
Allocated: {getTotalAllocatedQty()} / {currentProduct.PendingQty} {getTotalAllocatedQty() < currentProduct.RequestQty && ( (Remaining:{' '} {currentProduct.PendingQty - getTotalAllocatedQty()} ) )}
variant?.StockDetails?.length > 0 )?.map((variant, variantIndex) => ({ key: String(variantIndex), label: ( {variant.ProdVariantName} Total Available Qty: {variant.OverAllQty || 0} ), children: (
{variant.StockDetails?.map( (stock, stockIndex) => { const productKey = `${currentProduct.ProdId}_${currentProductIndex}`; const stockKey = `${variant?.RequestId}_${stock?.InwardDtlId}`; const currentValue = allocatedStocks[productKey]?.[stockKey] || 0; return (

Batch No:{' '} {stock.BatchRef || 'N/A'}

Available Qty:{' '} {stock.BalanceQty}

Expiry Date:{' '} {stock.ExpiryDate || 'N/A'}

Allocate Qty: handleStockAllocation( e.target.value, stock.BalanceQty, stock?.InwardDtlId, variant?.RequestId ) } />
); } )}
), })) || [] } />
} handleSubmit={submitAllocation} disabled={getTotalAllocatedQty() === 0} />
) } /> } /> { setCompleteModalVisible(false); setProdDtlsPage(1); }} footer={false} width={800} children={
} /> {deliveryData?.length > 0 &&
}
); }; export default Dispatch;