import React, { useState, useRef, useEffect, useContext, useCallback, } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { read, utils } from 'xlsx'; import ExcelJS from 'exceljs'; import { Table, Form, Input, Button, Tooltip, Modal } from 'antd'; import { emptyExcelData, excelDataSelector, excelFileSelector, excelFileErrorSelector, fileInputRefSelector, uploadExcel, } from '../../Features/ExcelUploadPage/ExcelUploadPage.js'; import '../../Styles/Stock/StockBulkUpload.scss'; import { AiFillDelete } from 'react-icons/ai'; import upldimg from '../../Images/upldimg.png'; import { FiDelete, FiDownload } from 'react-icons/fi'; import { MdOutlineAppRegistration } from 'react-icons/md'; import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; import Buttons from '../../Components/Forms/Buttons.jsx'; import { IoClose } from 'react-icons/io5'; import { ArrowRightOutlined } from '@ant-design/icons'; import { ApplicationPreferences } from '../../Features/BrachLogin/BranchLogin.js'; import FormHeader from '../PageComponents/FormHeader.jsx'; import { DropDowns } from '../../Components/Forms/DropDown.jsx'; import { getSession } from '../../Services/Others.js'; import { getFieldSetupData, postFieldSetup, } from '../../Features/ProductPage/ProductPage.js'; import { Messages } from '../../Components/Notifications/Messages.jsx'; import { getPurchaseSupplierAndWareHouseData } from '../../Features/PurchaseOrder/PurchaseOrder.js'; import { getSupplaierIdwithTypeBasedProducts } from '../../Features/SupplierProductMapping/SupplierProductMapping.js'; const allowedExcelTypes = [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx 'application/vnd.ms-excel', // .xls ]; const StockExcel = ({ handleSubmit, SupplierNames, ProductId, ProductName, VarientName, InwardDtlIds, StockProductId, TaxDatas, Allproductdatas, ProductSize, ProductUomName, }) => { // const formatted_list = ProductName.slice(0,13).map((item, index) => { // return item; // }); // const formatted_list = ProductName.map((item, index) => { // return item; // }); const dispatch = useDispatch(); const AppId = getSession('AppId'); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const UserId = getSession('UserId'); const formRef = useRef(null); const fileInputRef = useRef(fileInputRefSelector); const excelData = useSelector(excelDataSelector); const excelFile = useSelector(excelFileSelector); const excelFileError = useSelector(excelFileErrorSelector); const ApplicationPreferenceData = useSelector(ApplicationPreferences); const purchaseReceiptBulkUploadCatId = ApplicationPreferenceData?.find( (p) => p?.PreferredCatName?.toLowerCase() === 'purchase receipt bulk' )?.PreferredCatId; const [worksheet1, setWorksheet1] = useState(null); const [editdelete, seteditdelete] = useState(''); const [Datas, setDatas] = useState(); console.log(Datas, 'Datas'); const [showSupplierModal, setShowSupplierModal] = useState(false); const [suppliers, setSuppliers] = useState([]); const [selectedSupplier, setSelectedSupplier] = useState(null); const [selectedSupplierData, setSelectedSupplierData] = useState(null); const [supplierProducts, setSupplierProducts] = useState([]); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [fieldSetup, setFieldSetup] = useState(false); const [FieldValues, setFieldValues] = useState([]); const [tableFieldPreferences, setTableFieldPreferences] = useState([]); const [selectedFields, setSelectedFields] = useState([]); const handleTableChange = (pagination, filters, sorter) => { setCurrentPage(pagination.current); }; useEffect(() => { getFieldSetup(); }, [purchaseReceiptBulkUploadCatId]); const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); const getFieldSetup = async () => { try { const response = await dispatch( getFieldSetupData({ AppId, CompId, BranchId, categoryId: purchaseReceiptBulkUploadCatId, Type: 'EB', }) ).unwrap(); if (response?.data?.statusCode === 1) { console.log(response?.data?.data?.[0]?.ConfigDtl, 'Field Setup Data'); setSelectedFields( response?.data?.data?.[0]?.ConfigDtl?.filter( (c) => c.ConfigId && c.Access === 'Y' )?.map((c) => c.ConfigId) || [] ); setTableFieldPreferences( response?.data?.data?.[0]?.ConfigDtl?.map((c) => ({ value: c.ConfigId, label: c.ConfigName, access: c.Access, })) || [] ); setFieldValues(response?.data?.data?.[0]?.ConfigDtl); } else { setMessageType('error'); setMessageData('Failed to fetch field setup'); } } catch (error) { console.error('Error fetching field setup:', error); } }; useEffect(() => { if (excelData && excelData.length > 0) { let ExcelToJsConversion = []; let slicedData = excelData.slice(1); // Skip header row slicedData.forEach((item, index) => { // Skip empty rows if (!item || Object.values(item).every((val) => !val)) return; const rowData = { key: index, InwardDate: item['0'], Supplier: item['1'], InvoiceDeliveryChallan: item['3'], SupplierInvoiceNumber: item['4'], SupplierInvoiceDate: item['5'], DeliveryChallanNo: item['6'], DeliveryInvoiceDate: item['7'], PaymentType: item['8'], PaymentMode: item['9'], PaymentAmount: item['10'], DueDate: item['11'], ProductName: item['12'], VariantName: item['13'], Quantity: item['14'], PurchaseRate: item['15'], Amount: item['16'], ReceivedQty: item['17'], AcceptedQty: item['18'], MRP: item['19'], SalesPrice: item['20'], AmountPerPiece: item['21'], NumberofPieceInside: item['22'], }; // Handle conditional 'Own / With Paid' column const supplierValue = item['1']; if (String(supplierValue).trim() === 'Self') { rowData.OwnWithPaid = item['2']; // Shift all subsequent columns by 1 Object.keys(rowData).forEach((key) => { if ( !['key', 'InwardDate', 'Supplier', 'OwnWithPaid'].includes(key) ) { const currentIndex = parseInt(Object.keys(rowData).indexOf(key)); rowData[key] = item[currentIndex.toString()]; } }); } // Add optional fields based on column presence let currentColIndex = 23; // Check for optional fields in order they appear in handleDownload const optionalFields = [ { key: 'ManufactureDate', header: 'Manufacture Date' }, { key: 'ExpireDate', header: 'Expire Date' }, { key: 'BatchNo', header: 'Batch No.' }, { key: 'ModelNo', header: 'Model No.' }, { key: 'RejectedQty', header: 'Rejected Qty' }, { key: 'FreeQty', header: 'Free Qty' }, { key: 'WholesalePrice', header: 'Wholesale Price' }, ]; // Get headers from first row to determine which optional fields exist const headers = excelData[0]; optionalFields.forEach((field) => { if (headers.includes(field.header)) { rowData[field.key] = item[currentColIndex.toString()]; currentColIndex++; } }); if ( rowData?.PurchaseRate && rowData?.Amount && rowData?.MRP && rowData?.SalesPrice && rowData?.ProductName && rowData?.PaymentAmount ) { ExcelToJsConversion.push(rowData); } }); setDatas(ExcelToJsConversion); } }, [excelData]); useEffect(() => { if (Datas) { handleSubmit(Datas); } }, [Datas, handleSubmit]); useEffect(() => { if (supplierProducts?.length > 0 && selectedSupplierData) { handleDownload(); } }, [supplierProducts, selectedSupplierData]); const handleFileUpload = (e) => { const file = e.target.files[0]; if (file) { const isAllowed = allowedExcelTypes.includes(file.type); if (!isAllowed) { Modal.error({ title: 'Invalid File Type', content: 'Only Excel files (.xls, .xlsx) are allowed.', }); handleCancelData(); } else { uploadAndProcessExcel(file); } } else { dispatch(emptyExcelData()); } }; const handleClick = () => { // Programmatically trigger the file input click event fileInputRef.current.click(); }; const uploadAndProcessExcel = (file) => { const reader = new FileReader(); reader.onload = (e) => { const data = new Uint8Array(e.target.result); const workbook = read(data, { type: 'array' }); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; const jsonData = utils.sheet_to_json(worksheet, { header: 1, raw: false, dateNF: 'DD/MM/YY', }); const nonEmptyRows = jsonData.filter((row) => row.some((cell) => cell !== '') ); const header = nonEmptyRows[0]; const rows = nonEmptyRows.slice(1); const dateFields = ['Manufacture Date', 'Expire Date', 'Stock Date']; function convertToDisplayFormat(dateString) { const date = new Date(dateString); const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear().toString(); return `${day}-${month}-${year}`; } const formattedData = rows.map((row) => { let rowData = header.reduce((acc, col, columnIndex) => { if (dateFields.includes(col)) { acc[col] = convertToDisplayFormat(row[columnIndex]); } else { acc[col] = row[columnIndex]; } return acc; }, {}); return rowData; }); dispatch(uploadExcel({ file, jsonData: nonEmptyRows })); setWorksheet1(worksheet1); setDatas(formattedData); }; reader.readAsArrayBuffer(file); }; // ...existing code... const handleDownload = async () => { try { if ( !supplierProducts || supplierProducts.length === 0 || !selectedSupplierData ) { setMessageData('No products available to generate Excel.'); setMessageType('warning'); return; } const supplierDisplayName = getSupplierDisplayName(selectedSupplierData) || 'Supplier'; // Fetch excelColumns config (optional fields access) let excelColumns = []; try { const response = await dispatch( getFieldSetupData({ AppId, CompId, BranchId, categoryId: purchaseReceiptBulkUploadCatId, Type: 'EB', }) ).unwrap(); if (response?.data?.statusCode === 1) { excelColumns = response?.data?.data?.[0]?.ConfigDtl || []; } } catch (err) { console.warn( 'Failed to fetch excelColumns config, proceeding with defaults', err ); excelColumns = []; } const isOptionalFieldAllowed = (name) => { const found = excelColumns.find( (c) => String(c.ConfigName).trim() === String(name).trim() ); return found ? found.Access === 'Y' : false; }; const addNumberValidation = (cell, allowBlank = true, minValue = 0) => { cell.dataValidation = { type: 'decimal', operator: 'greaterThanOrEqual', formulae: [minValue], allowBlank: allowBlank, showErrorMessage: true, errorTitle: 'Invalid Number', error: 'Please enter a valid number', }; }; const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet('Sheet1'); const hiddenSheet = workbook.addWorksheet('ProductVariantMap'); workbook.addWorksheet('ValidationHelper'); const requiredBg = 'FF2929'; const headerFontColor = { argb: 'FF000000' }; const columns = []; const pushCol = (header, key, required = true) => { columns.push({ header, key, required }); }; pushCol('Inward Date', 'InwardDate', true); pushCol('Supplier', 'Supplier', true); if (String(selectedSupplierData?.SuppName).trim() === 'Self') { pushCol('Own / With Paid', 'OwnWithPaid', true); } pushCol('Invoice / Delivery Challan', 'InvoiceDeliveryChallan', true); pushCol('Supplier Invoice Number', 'SupplierInvoiceNumber', true); pushCol('Supplier Invoice Date', 'SupplierInvoiceDate', true); pushCol('Delivery Challan No.', 'DeliveryChallanNo', true); pushCol('Delivery Challan Date', 'DeliveryInvoiceDate', true); pushCol('Payment Type', 'PaymentType', true); pushCol('Payment Mode', 'PaymentMode', true); pushCol('Payment Amount', 'PaymentAmount', true); pushCol('Due Date', 'DueDate', true); pushCol('Product Name', 'ProdName', true); pushCol('Variant Name', 'VariantName', true); pushCol('Quantity', 'Quantity', true); pushCol('Purchase Rate', 'PurchaseRate', true); pushCol('Amount', 'Amount', true); pushCol('Received Qty', 'ReceivedQty', true); pushCol('Accepted Qty', 'AcceptedQty', true); pushCol('MRP', 'MRP', true); pushCol('Sales Price', 'SalesPrice', true); pushCol('Amount Per Piece', 'AmountPerPiece', true); pushCol('Number of Piece Inside', 'NumberofPieceInside', true); if (isOptionalFieldAllowed('Manufacture Date')) pushCol('Manufacture Date', 'ManufDate', false); if (isOptionalFieldAllowed('Expire Date')) pushCol('Expire Date', 'ExpDate', false); if (isOptionalFieldAllowed('Batch No.')) pushCol('Batch No.', 'BatchNo', false); if (isOptionalFieldAllowed('Model No.')) pushCol('Model No.', 'ModelNo', false); if (isOptionalFieldAllowed('Rejected Qty')) pushCol('Rejected Qty', 'RejectedQty', false); if (isOptionalFieldAllowed('Free Qty')) pushCol('Free Qty', 'FreeQty', false); if (isOptionalFieldAllowed('Wholesale Price')) pushCol('Wholesale Price', 'WholesalePrice', false); worksheet.columns = columns.map((c) => ({ header: c.header, key: c.key, width: c.key === 'ProdName' || c.key === 'VariantName' ? 40 : c.key === 'Quantity' ? 10 : c.key === 'Supplier' || c.key === 'InvoiceDeliveryChallan' || c.key === 'SupplierInvoiceNumber' ? 30 : 20, })); worksheet.getRow(1).eachCell((cell, colNumber) => { const col = columns[colNumber - 1]; const bgColor = col.required ? requiredBg : 'FF52C41A'; cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: bgColor }, }; cell.font = { bold: true, color: headerFontColor }; cell.alignment = { horizontal: 'center', vertical: 'middle' }; cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' }, }; }); hiddenSheet.addRow([ 'ProductName', 'VariantName', 'MRP', 'SellPrice', 'Number of Piece Inside', 'Amount Per Piece', ]); let currentRow = 2; const productNames = supplierProducts.map((p) => p.ProdName); supplierProducts.forEach((product) => { const activeVariants = (product.ProdVariantPriceDetails || []).filter( (v) => v.ActiveStatus === 'A' ); const uniqueVariantsMap = new Map(); activeVariants.forEach((variant) => { const variantName = variant.ProdVariantName; if (!uniqueVariantsMap.has(variantName)) { uniqueVariantsMap.set(variantName, variant); } }); const uniqueVariants = Array.from(uniqueVariantsMap.values()); if (uniqueVariants.length === 0) return; const startRow = currentRow; uniqueVariants.forEach((variant) => { hiddenSheet.addRow([ product.ProdName, variant.ProdVariantName, variant.MRP || 0, variant.SellPrice || 0, variant.NoOfPcs || 0, variant.OnePcsPrice || 0, ]); currentRow++; }); const endRow = currentRow - 1; let safeName = String(product.ProdName || '') .trim() .replace(/[^A-Za-z0-9_]/g, '_') .replace(/^(\d)/, '_$1'); if (!safeName) safeName = `Product_${Math.random().toString(36).slice(2, 8)}`; const rangeRef = `ProductVariantMap!$B$${startRow}:$B$${endRow}`; try { workbook.definedNames.add(rangeRef, safeName); } catch (err) { console.warn(`Could not add named range for ${safeName}`, err); } }); const startDataRow = 2; const today = new Date(); // Pre-populate all products and variants as rows supplierProducts.forEach((product) => { const activeVariants = (product.ProdVariantPriceDetails || []).filter( (v) => v.ActiveStatus === 'A' ); const uniqueVariantsMap = new Map(); activeVariants.forEach((variant) => { const variantName = variant.ProdVariantName; if (!uniqueVariantsMap.has(variantName)) { uniqueVariantsMap.set(variantName, variant); } }); const uniqueVariants = Array.from(uniqueVariantsMap.values()); uniqueVariants.forEach((variant) => { const rowData = { InwardDate: today, Supplier: supplierDisplayName, ProdName: product.ProdName, VariantName: variant.ProdVariantName, MRP: variant.MRP || 0, SalesPrice: variant.SellPrice || 0, NumberofPieceInside: variant.NoOfPcs || 0, AmountPerPiece: variant.OnePcsPrice || 0, }; if (String(selectedSupplierData?.SuppName).trim() === 'Self') { rowData.OwnWithPaid = ''; } worksheet.addRow(rowData); }); }); const colKeyToIndex = {}; worksheet.columns.forEach((c, idx) => { colKeyToIndex[c.key] = idx + 1; }); const colIndex = (key) => colKeyToIndex[key]; const colLetter = (idx) => { let s = ''; let n = idx; while (n > 0) { const m = (n - 1) % 26; s = String.fromCharCode(65 + m) + s; n = Math.floor((n - 1) / 26); } return s; }; const inwardDateCol = colIndex('InwardDate'); const numberOfRows = worksheet.rowCount; for (let r = startDataRow; r <= numberOfRows; r++) { if (colIndex('ProdName')) { const cIdx = colIndex('ProdName'); const cell = worksheet.getCell(r, cIdx); cell.protection = { locked: true }; } if (colIndex('VariantName')) { const cIdx = colIndex('VariantName'); const cell = worksheet.getCell(r, cIdx); cell.protection = { locked: true }; } if (colIndex('Quantity')) { const cIdx = colIndex('Quantity'); const letter = colLetter(cIdx); const cell = worksheet.getCell(`${letter}${r}`); cell.protection = { locked: false }; addNumberValidation(cell, false, 0.01); } if (colIndex('PurchaseRate')) { const cIdx = colIndex('PurchaseRate'); const letter = colLetter(cIdx); const pCell = worksheet.getCell(`${letter}${r}`); pCell.protection = { locked: false }; addNumberValidation(pCell, false, 0); pCell.numFmt = '#,##0.00'; } if (colIndex('RejectedQty')) { const cIdx = colIndex('RejectedQty'); const letter = colLetter(cIdx); const rejCell = worksheet.getCell(`${letter}${r}`); const qtyLetter = colLetter(colIndex('Quantity')); rejCell.dataValidation = { type: 'decimal', allowBlank: true, formulae: [`${letter}${r}<${qtyLetter}${r}`], showErrorMessage: true, errorTitle: 'Invalid Rejected Quantity', error: 'Must be a valid number and less than total quantity', showInputMessage: true, promptTitle: 'Rejected Qty', prompt: 'Enter rejected quantity (must be less than total quantity)', }; rejCell.protection = { locked: false }; } if (colIndex('FreeQty')) { const cIdx = colIndex('FreeQty'); const letter = colLetter(cIdx); const cell = worksheet.getCell(`${letter}${r}`); cell.protection = { locked: false }; addNumberValidation(cell, true, 0); } if (inwardDateCol) { const letter = colLetter(inwardDateCol); const dCell = worksheet.getCell(`${letter}${r}`); dCell.numFmt = 'yyyy-mm-dd'; dCell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; dCell.protection = { locked: false }; } if (colIndex('Supplier')) { const cIdx = colIndex('Supplier'); const cell = worksheet.getCell(r, cIdx); cell.protection = { locked: true }; } if (colIndex('OwnWithPaid')) { const cIdx = colIndex('OwnWithPaid'); const cell = worksheet.getCell(r, cIdx); cell.dataValidation = { type: 'list', formulae: ['"Own,With Paid"'], allowBlank: true }; if (!cell.value) { cell.value = 'Own'; } cell.protection = { locked: false }; } if (colIndex('InvoiceDeliveryChallan')) { const cIdx = colIndex('InvoiceDeliveryChallan'); const cell = worksheet.getCell(r, cIdx); cell.dataValidation = { type: 'list', formulae: ['"Invoice,Delivery Challan"'], allowBlank: true, }; // ✅ Default value if (!cell.value) { cell.value = 'Invoice'; } cell.protection = { locked: false }; } if (colIndex('SupplierInvoiceNumber')) { worksheet.getCell(r, colIndex('SupplierInvoiceNumber')).protection = { locked: false, }; } if (colIndex('SupplierInvoiceDate')) { const cell = worksheet.getCell(r, colIndex('SupplierInvoiceDate')); cell.value = today; cell.numFmt = 'yyyy-mm-dd'; cell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; cell.protection = { locked: false }; } if (colIndex('DeliveryChallanNo')) { worksheet.getCell(r, colIndex('DeliveryChallanNo')).protection = { locked: false, }; } if (colIndex('DeliveryInvoiceDate')) { const cell = worksheet.getCell(r, colIndex('DeliveryInvoiceDate')); cell.value = today; cell.numFmt = 'yyyy-mm-dd'; cell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; cell.protection = { locked: false }; } if (colIndex('MRP')) { const mrpCol = colIndex('MRP'); const mrpCell = worksheet.getCell(r, mrpCol); mrpCell.numFmt = '#,##0.00'; mrpCell.protection = { locked: false }; } if (colIndex('SalesPrice')) { const spCol = colIndex('SalesPrice'); const spCell = worksheet.getCell(r, spCol); spCell.numFmt = '#,##0.00'; spCell.protection = { locked: false }; } if (colIndex('NumberofPieceInside')) { const nopCol = colIndex('NumberofPieceInside'); const nopCell = worksheet.getCell(r, nopCol); nopCell.numFmt = '#,##0'; nopCell.protection = { locked: false }; } if (colIndex('AmountPerPiece')) { const appCol = colIndex('AmountPerPiece'); const appCell = worksheet.getCell(r, appCol); appCell.numFmt = '#,##0.00'; appCell.protection = { locked: false }; } if (colIndex('PaymentType')) { const cIdx = colIndex('PaymentType'); const letter = colLetter(cIdx); const pCell = worksheet.getCell(`${letter}${r}`); pCell.dataValidation = { type: 'list', allowBlank: false, formulae: ['"Credit,Paid"'], }; pCell.protection = { locked: false }; } // Payment Mode - Fixed to show list based on Payment Type if (colIndex('PaymentMode')) { const cIdx = colIndex('PaymentMode'); const letter = colLetter(cIdx); const pmCell = worksheet.getCell(`${letter}${r}`); const paymentTypeLetter = colLetter(colIndex('PaymentType')); // Create named range for payment mode options in ValidationHelper sheet const validationHelper = workbook.getWorksheet('ValidationHelper'); if (r === startDataRow) { // Add payment mode options to ValidationHelper sheet (only once) validationHelper.getCell('A1').value = 'Cash'; validationHelper.getCell('A2').value = 'Credit'; validationHelper.getCell('A3').value = 'UPI'; } // Use IF formula to show list based on Payment Type pmCell.dataValidation = { type: 'list', allowBlank: true, formulae: [ `IF(${paymentTypeLetter}${r}="Paid",ValidationHelper!$A$1:$A$3,"")`, ], showErrorMessage: true, errorTitle: 'Invalid Payment Mode', error: 'Select Cash, Credit, or UPI when Payment Type is Paid', showInputMessage: true, promptTitle: 'Payment Mode', prompt: 'If Payment Type is Credit, leave empty. If Paid, select: Cash, Credit, or UPI', }; pmCell.protection = { locked: false }; } if (colIndex('DueDate')) { const cIdx = colIndex('DueDate'); const letter = colLetter(cIdx); const dueCell = worksheet.getCell(`${letter}${r}`); dueCell.numFmt = 'yyyy-mm-dd'; dueCell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; dueCell.protection = { locked: false }; } if (colIndex('ManufDate')) { const cIdx = colIndex('ManufDate'); const letter = colLetter(cIdx); const manufCell = worksheet.getCell(`${letter}${r}`); manufCell.numFmt = 'yyyy-mm-dd'; manufCell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; manufCell.protection = { locked: false }; } if (colIndex('ExpDate')) { const cIdx = colIndex('ExpDate'); const letter = colLetter(cIdx); const expCell = worksheet.getCell(`${letter}${r}`); expCell.numFmt = 'yyyy-mm-dd'; expCell.dataValidation = { type: 'date', operator: 'greaterThan', formulae: [new Date(1900, 0, 1)], showErrorMessage: true, errorTitle: 'Invalid Date', error: 'Please enter a valid date', }; expCell.protection = { locked: false }; } if (colIndex('ReceivedQty') && colIndex('Quantity')) { const rIdx = colIndex('ReceivedQty'); const qIdx = colIndex('Quantity'); const rLetter = colLetter(rIdx); const qLetter = colLetter(qIdx); const recCell = worksheet.getCell(`${rLetter}${r}`); recCell.value = { formula: `IF(${qLetter}${r}="","",${qLetter}${r})`, }; addNumberValidation(recCell, true, 0); } if (colIndex('AcceptedQty') && colIndex('Quantity')) { const aIdx = colIndex('AcceptedQty'); const qIdx = colIndex('Quantity'); const rjIdx = colIndex('RejectedQty'); const aLetter = colLetter(aIdx); const qLetter = colLetter(qIdx); const rejLetter = rjIdx ? colLetter(rjIdx) : null; const formulaCell = worksheet.getCell(`${aLetter}${r}`); if (rejLetter) { formulaCell.value = { formula: `IF(${qLetter}${r}="","",MAX(0,${qLetter}${r}-IF(${rejLetter}${r}="",0,${rejLetter}${r})))`, }; } else { formulaCell.value = { formula: `IF(${qLetter}${r}="","",${qLetter}${r})`, }; } addNumberValidation(formulaCell, true, 0); formulaCell.protection = { locked: true }; } if ( colIndex('PaymentAmount') && colIndex('Quantity') && colIndex('PurchaseRate') ) { const payIdx = colIndex('PaymentAmount'); const qIdx = colIndex('Quantity'); const pIdx = colIndex('PurchaseRate'); const rejIdx = colIndex('RejectedQty'); const payLetter = colLetter(payIdx); const qLetter = colLetter(qIdx); const pLetter = colLetter(pIdx); const rejLetter = rejIdx ? colLetter(rejIdx) : null; const formulaCell = worksheet.getCell(`${payLetter}${r}`); if (rejLetter) { formulaCell.value = { formula: `IF(${qLetter}${r}="","",IF(${rejLetter}${r}="",(${qLetter}${r})*${pLetter}${r},(${qLetter}${r}-${rejLetter}${r})*${pLetter}${r}))`, }; } else { formulaCell.value = { formula: `IF(${qLetter}${r}="","",(${qLetter}${r})*${pLetter}${r})`, }; } formulaCell.numFmt = '#,##0.00'; addNumberValidation(formulaCell, true, 0); } if ( colIndex('Amount') && colIndex('Quantity') && colIndex('PurchaseRate') ) { const amtIdx = colIndex('Amount'); const qIdx = colIndex('Quantity'); const pIdx = colIndex('PurchaseRate'); const rejIdx = colIndex('RejectedQty'); const amtLetter = colLetter(amtIdx); const qLetter = colLetter(qIdx); const pLetter = colLetter(pIdx); const rejLetter = rejIdx ? colLetter(rejIdx) : null; const amtCell = worksheet.getCell(`${amtLetter}${r}`); if (rejLetter) { amtCell.value = { formula: `IF(${qLetter}${r}="","",IF(${rejLetter}${r}="",(${qLetter}${r})*${pLetter}${r},(${qLetter}${r}-${rejLetter}${r})*${pLetter}${r}))`, }; } else { amtCell.value = { formula: `IF(${qLetter}${r}="","",(${qLetter}${r})*${pLetter}${r})`, }; } amtCell.numFmt = '#,##0.00'; addNumberValidation(amtCell, true, 0); } if (colIndex('WholesalePrice')) { const cIdx = colIndex('WholesalePrice'); const letter = colLetter(cIdx); const cell = worksheet.getCell(`${letter}${r}`); cell.protection = { locked: false }; cell.numFmt = '#,##0.00'; addNumberValidation(cell, true, 0); } } await worksheet.protect('', { selectLockedCells: false, selectUnlockedCells: true, formatCells: false, formatColumns: false, formatRows: false, insertColumns: false, insertRows: false, insertHyperlinks: false, deleteColumns: false, deleteRows: false, }); const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); const filename = `PurchaseEntry_${supplierDisplayName}_${Date.now()}.xlsx`; const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; link.click(); setSupplierProducts([]); setSelectedSupplierData(null); handleModalCancel(); } catch (err) { console.error('Failed to generate Purchase Entry Excel', err); setMessageData('Failed to generate Excel. Check console for details.'); setMessageType('error'); } }; const getSupplierDisplayName = useCallback((supplierData) => { if (!supplierData) return ''; if (supplierData.Type === 'Supplier') { return supplierData.SuppName || supplierData.label; } else { // For Branch or WareHouse return `${supplierData.SuppName}-${supplierData.SuppAppId}-${supplierData.SuppCompId}-${supplierData.SuppBranchId}-${supplierData?.Type === 'Branch' ? 'B' : 'W'}`; } }, []); const handleFileSubmit = (e) => { e.preventDefault(); if (excelFile === null) { excelFileError('Please select an Excel file.'); } else { handleSubmit(Datas); } }; const handleCancelData = () => { dispatch(emptyExcelData()); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const smallIconColumnTitle = 'SmallIcon'; const columns = [ { title: 'Inward Date', dataIndex: 'InwardDate', key: 'InwardDate', editable: true, }, { title: 'Supplier', dataIndex: 'Supplier', key: 'Supplier', editable: true, }, { title: 'Own / With Paid', dataIndex: 'OwnWithPaid', key: 'OwnWithPaid', editable: true, }, { title: 'Invoice / Delivery Challan', dataIndex: 'InvoiceDeliveryChallan', key: 'InvoiceDeliveryChallan', editable: true, }, { title: 'Supplier Invoice Number', dataIndex: 'SupplierInvoiceNumber', key: 'SupplierInvoiceNumber', editable: true, }, { title: 'Supplier Invoice Date', dataIndex: 'SupplierInvoiceDate', key: 'SupplierInvoiceDate', editable: true, }, { title: 'Delivery Challan No.', dataIndex: 'DeliveryChallanNo', key: 'DeliveryChallanNo', editable: true, }, { title: 'Delivery Challan Date', dataIndex: 'DeliveryInvoiceDate', key: 'DeliveryInvoiceDate', editable: true, }, { title: 'Payment Type', dataIndex: 'PaymentType', key: 'PaymentType', editable: true, }, { title: 'Payment Mode', dataIndex: 'PaymentMode', key: 'PaymentMode', editable: true, }, { title: 'Payment Amount', dataIndex: 'PaymentAmount', key: 'PaymentAmount', editable: true, }, { title: 'Due Date', dataIndex: 'DueDate', key: 'DueDate', editable: true, }, { title: 'Product Name', dataIndex: 'ProductName', key: 'ProductName', editable: true, }, { title: 'Variant Name', dataIndex: 'VariantName', key: 'VariantName', editable: true, }, { title: 'Quantity', dataIndex: 'Quantity', key: 'Quantity', editable: true, }, { title: 'Purchase Rate', dataIndex: 'PurchaseRate', key: 'PurchaseRate', editable: true, }, { title: 'Amount', dataIndex: 'Amount', key: 'Amount', editable: true, }, { title: 'Received Qty', dataIndex: 'ReceivedQty', key: 'ReceivedQty', editable: true, }, { title: 'Accepted Qty', dataIndex: 'AcceptedQty', key: 'AcceptedQty', editable: true, }, { title: 'MRP', dataIndex: 'MRP', key: 'MRP', editable: true, }, { title: 'Sales Price', dataIndex: 'SalesPrice', key: 'SalesPrice', editable: true, }, { title: 'Amount Per Piece', dataIndex: 'AmountPerPiece', key: 'AmountPerPiece', editable: true, }, { title: 'Number of Piece Inside', dataIndex: 'NumberofPieceInside', key: 'NumberofPieceInside', editable: true, }, { title: 'Manufacture Date', dataIndex: 'ManufactureDate', key: 'ManufactureDate', editable: true, }, { title: 'Expire Date', dataIndex: 'ExpireDate', key: 'ExpireDate', editable: true, }, { title: 'Batch No.', dataIndex: 'BatchNo', key: 'BatchNo', editable: true, }, { title: 'Model No.', dataIndex: 'ModelNo', key: 'ModelNo', editable: true, }, { title: 'Rejected Qty', dataIndex: 'RejectedQty', key: 'RejectedQty', editable: true, }, { title: 'Free Qty', dataIndex: 'FreeQty', key: 'FreeQty', editable: true, }, { title: 'Wholesale Price', dataIndex: 'WholesalePrice', key: 'WholesalePrice', editable: true, }, ]; const column = columns?.map((col) => { if (!col.editable) { return col; } let onClickHandler = null; if (editdelete === 'Delete') { onClickHandler = (record) => removeFromTable(record); } return { ...col, onCell: (record) => ({ record, editable: col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, onClick: () => onClickHandler(record), }), }; }); const EditableContext = React.createContext(null); const EditableRow = ({ index, ...props }) => { const [form] = Form.useForm(); return (
); }; const EditableCell = ({ title, editable, children, dataIndex, record, handleSave, ...restProps }) => { const [editing, setEditing] = useState(false); const inputRef = useRef(null); const form = useContext(EditableContext); useEffect(() => { if (editing) { inputRef?.current?.focus(); } }, [editing]); const toggleEdit = () => { setEditing(!editing); form.setFieldsValue({ [dataIndex]: record[dataIndex], }); }; const save = async () => { try { const values = await form.validateFields(); toggleEdit(); handleSave({ ...record, ...values, }); } catch (errInfo) { } }; let childNode = children; if (editable) { childNode = editing ? (