From 63d682e1512d1a343425261fded4ef0ca271c1fe Mon Sep 17 00:00:00 2001 From: Tamilselvan Date: Fri, 6 Feb 2026 14:27:37 +0530 Subject: [PATCH] Optimizationstockform --- src/Components/Menu/PozoMenu.jsx | 16 +- src/Pages/StockMaster/AddAllProductGrid.jsx | 151 + .../StockMaster/SettingsIconWithModal.jsx | 99 + src/Pages/StockMaster/StockForm.jsx | 4783 ++++++----------- src/Pages/StockMaster/StockList.jsx | 9 +- src/Pages/StockMaster/UseDebounce.jsx | 16 + src/Pages/StockMaster/VirtualizedTable.jsx | 171 + src/Styles/Stock/StockMaster.scss | 47 +- 8 files changed, 2147 insertions(+), 3145 deletions(-) create mode 100644 src/Pages/StockMaster/AddAllProductGrid.jsx create mode 100644 src/Pages/StockMaster/SettingsIconWithModal.jsx create mode 100644 src/Pages/StockMaster/UseDebounce.jsx create mode 100644 src/Pages/StockMaster/VirtualizedTable.jsx diff --git a/src/Components/Menu/PozoMenu.jsx b/src/Components/Menu/PozoMenu.jsx index b9d861e..fa56b0d 100644 --- a/src/Components/Menu/PozoMenu.jsx +++ b/src/Components/Menu/PozoMenu.jsx @@ -1,5 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react'; -import { AppstoreOutlined, MailOutlined, SettingOutlined, } from '@ant-design/icons'; +import { useState, useRef, useEffect } from 'react'; import { FaCaretRight } from "react-icons/fa"; import './PozoMenu.scss'; @@ -8,7 +7,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse const [openKeys, setOpenKeys] = useState([]); const [selectedKey, setSelectedKey] = useState(''); const [dropdownPositions, setDropdownPositions] = useState({}); - console.log(dropdownPositions, "dropdownPositions") const [isMobile, setIsMobile] = useState(window.innerWidth <= 768); const menuRef = useRef(); @@ -115,7 +113,7 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse // Image 2: No space on right, space on left - open to LEFT position.left = rect.left - dropdownWidth - gap + scrollX; position.direction = 'left'; - console.log('✅ Opening LEFT - no space on right'); + } else { // Edge case: Limited space on both sides if (spaceRight >= spaceLeft) { @@ -245,7 +243,7 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse // Calculate position and add to dropdown positions const position = calculatePosition(event.currentTarget, parentKeys.length); - console.log('🎯 Setting position for', itemKey, ':', position); + setDropdownPositions(prev => { // Remove positions for closed items @@ -254,7 +252,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse if (prev[key]) newPos[key] = prev[key]; }); newPos[itemKey] = position; - console.log('🎯 Updated dropdown positions:', newPos); return newPos; }); @@ -276,11 +273,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse }); } - console.log('Menu item clicked:', { - key: item.key, - keyPath: [...parentKeys, item.key], - label: item.label - }); } }; @@ -415,8 +407,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse }, [items, openKeys]); - console.log(submenuRefs, "menuRef") - return (
{ + // This function just returns a prepared product object, no state changes + + const ProductDropDownChange = async ( + VariantName, + ProdId, + option, + productsList, + extractedProduct = false, + extractedItem + ) => { + const ProductData1 = (productsList || productData)?.find( + (p) => p.ProdId === ProdId && p.ProdVariantName === VariantName + ); + if (!ProductData1) return null; + + const DefaultVariant = ProductData1?.ProdVariantPriceDetails?.find( + (item) => item?.DefaultVariant === 'Y' && item?.ReceivedQty === 0 + )?.DefaultVariant; + + const qty = extractedProduct + ? parseFloat(extractedItem?.parsedData?.qty) || 0 + : 0; + const acceptedQty = extractedProduct + ? parseFloat(extractedItem?.parsedData?.qty) || 0 + : 0; + const rate = extractedProduct + ? parseFloat(extractedItem?.parsedData?.rate) || 0 + : 0; + + return { + DefaultVariant, + ProdId: ProductData1.ProdId, + MRP: ProductData1.MRP, + ProdName: ProductData1.ProdName, + UomName: ProductData1.UomName, + SellPrice: ProductData1.SellPrice, + StockAvailable: ProductData1.StockAvailable, + OnePcsAvailable: ProductData1.OnePcsAvailable, + OnePcsPrice: ProductData1.OnePcsPrice, + NoOfPcs: ProductData1.NoOfPcs, + TaxId: ProductData1.TaxId, + TaxPercentage: ProductData1.TaxPercentage, + ProdVariantName: ProductData1.ProdVariantName, + PurchaseTax: parseFloat(extractedItem?.parsedData?.tax) || 0, + BalanceQty: qty, + InwardPrice: rate, + PurcDisc: 0, + Amount: isNaN(rate) || isNaN(acceptedQty) ? 0 : rate * acceptedQty, + WhSalePrice: 0, + ReceivedQty: qty, + AcceptedQty: acceptedQty, + RejectedQty: qty - acceptedQty, + OfferPrice: 0, + SpecialPrice: 0, + FreeItem: 0, + TaxAmt: 0, + TaxType: SelectedPurcTaxType || 0, + PurcDiscType: 'P', + refImage: extractedItem?.parsedData?.image, + PurchaseHSNCode: extractedItem?.parsedData?.hsn || '', + localId: uuidv4(), + }; + }; + + const handleAddAll = async () => { + try { + setIsLoading(true); + setLoadingText('Adding products...'); + + // allow UI paint + await new Promise((r) => requestAnimationFrame(r)); + + const allValidProducts = []; + const allFormValues = {}; + + for (let i = 0; i < productData.length; i += batchSize) { + const batch = productData.slice(i, i + batchSize); + + setLoadingText( + `Processing ${Math.min(i + batchSize, productData.length)} / ${ + productData.length + }` + ); + + const batchProducts = await Promise.all( + batch.map((product) => + ProductDropDownChange( + product.ProdVariantName, + product.ProdId, + { + label: `${product.ProdName} (${product.Size} ${product.UomName})${ + product.BrandName ? ` - ${product.BrandName}` : '' + }`, + }, + productData + ) + ) + ); + + const valid = batchProducts.filter(Boolean); + allValidProducts.push(...valid); + + valid.forEach((p) => { + const id = p.localId; + allFormValues[`SellPrice${id}`] = p.SellPrice; + allFormValues[`PurchaseTax${id}`] = p.PurchaseTax; + allFormValues[`BalanceQty${id}`] = p.BalanceQty; + allFormValues[`ReceivedQty${id}`] = p.ReceivedQty; + allFormValues[`AcceptedQty${id}`] = p.AcceptedQty; + allFormValues[`RejectedQty${id}`] = p.RejectedQty; + allFormValues[`InwardPrice${id}`] = p.InwardPrice; + allFormValues[`Amount${id}`] = p.Amount; + }); + + await new Promise((r) => setTimeout(r, 0)); + } + + // ✅ ONE state update + setPurchaseData((prev) => [...allValidProducts, ...prev]); + + // ✅ ONE form update + form?.setFieldsValue(allFormValues); + } finally { + setIsLoading(false); + setLoadingText(''); + } + }; + + return ( + + + + ); +}; + +export default AddAllProductsButton; diff --git a/src/Pages/StockMaster/SettingsIconWithModal.jsx b/src/Pages/StockMaster/SettingsIconWithModal.jsx new file mode 100644 index 0000000..2b673c9 --- /dev/null +++ b/src/Pages/StockMaster/SettingsIconWithModal.jsx @@ -0,0 +1,99 @@ +import React, { useState } from 'react'; +import { Tooltip } from '@mui/material'; +import { IoSettingsOutline } from 'react-icons/io5'; +import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; + + +const SettingsIconWithModal = ({ + tooltipTitle = 'Add Fields', + tableFieldPreferences = [], + selectedAdditionalColumn = [], + onSubmit, +}) => { + const [open, setOpen] = useState(false); + const [selectedFields, setSelectedFields] = useState([]); + const [tempSelectedColumns, setTempSelectedColumns] = useState([]); + + const handleIconClick = () => { + // map labels → values + const mappedFields = selectedAdditionalColumn + .map( + (col) => + tableFieldPreferences.find((pref) => pref.label === col)?.value + ) + .filter(Boolean); + + setSelectedFields(mappedFields); + setTempSelectedColumns([...selectedAdditionalColumn]); + setOpen(true); + }; + + const handleCancel = () => { + setOpen(false); + setTempSelectedColumns([]); + }; + + const handleApply = () => { + onSubmit({ + selectedFields, + tempSelectedColumns, + closeModal: () => setOpen(false), + resetTemp: () => setTempSelectedColumns([]), + }); + }; + + return ( + <> + {/* ⚙️ ICON ONLY */} + + + + + {/* MODAL */} + +
+ {tableFieldPreferences.map((option) => ( +
+ +
+ ))} +
+
+ + ); +}; + +export default SettingsIconWithModal; diff --git a/src/Pages/StockMaster/StockForm.jsx b/src/Pages/StockMaster/StockForm.jsx index e4b86f9..882b2a7 100644 --- a/src/Pages/StockMaster/StockForm.jsx +++ b/src/Pages/StockMaster/StockForm.jsx @@ -11,20 +11,10 @@ import { useDispatch, useSelector } from 'react-redux'; import { ArrowRightOutlined, PlusCircleOutlined, - InfoCircleOutlined, SearchOutlined, } from '@ant-design/icons'; -import { - Form, - Tooltip, - Table, - Input, - Collapse, - AutoComplete, - Switch, -} from 'antd'; -import { IoAddCircleSharp, IoSettingsOutline } from 'react-icons/io5'; -import { ScannerInputField } from '../../Components/Forms/ScannerInputField.jsx'; +import { Form, Tooltip, Table, Input, AutoComplete, Switch } from 'antd'; +import { IoAddCircleSharp } from 'react-icons/io5'; import { InputField } from '../../Components/Forms/InputField.jsx'; import Buttons from '../../Components/Forms/Buttons.jsx'; import { Modal } from 'antd'; @@ -35,69 +25,56 @@ import FormHeader from '../PageComponents/FormHeader.jsx'; import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; import { getSession, validateSafeInput } from '../../Services/Others.js'; import { DatePicProd } from '../../Components/Forms/DatePickerProduct.jsx'; -import { DatePic } from '../../Components/Forms/DatePicker.jsx'; import { RadioGrpButton } from '../../Components/Forms/RadioGroup.jsx'; -import Imageupload from '../../Components/Forms/Upload.jsx'; import moment from 'moment'; -import barcodeimg from '../../Images/barcodeimg.png'; import { DropDowns } from '../../Components/Forms/DropDown.jsx'; import { BsUpcScan } from 'react-icons/bs'; import { debounce } from 'lodash'; import { - SupplierDataSelector, - productDataSelector, getProductData, getSupplierData, - getVariantData, getPurchaseTypeData, getPurchaseTaxTypeData, postPurchaseData, - getProdvaraiantdata, + putStockData, } from '../../Features/StockMaster/StockMaster.js'; import '../../Styles/Stock/StockMaster.scss'; import { getAdmin, - prodTaxDataSelector, - taxSelector, getUomData, getProdCatData, - getProdSubCatData, - getBrandData, uomDataSelector, - prodCatDataSelector, - prodSubCatDataSelector, - brandDataSelector, - postProductData, - getConfigTypeData, - postTax, postSupplier, - getQrcodeData, - getsingleQrcodeData, - productTypeDataSelector, getProductTypeData, bulkpostdata, postFieldSetup, getFieldSetupData, } from '../../Features/ProductPage/ProductPage.js'; -import { postConfiguration } from '../../Features/ConfigMasterPage/ConfigMasterPage.js'; import SupplierProductMappingForm from '../SupplierProductMapping/SuplierProductMappingForm.jsx'; import { getPurchaseSupplierAndWareHouseData } from '../../Features/PurchaseOrder/PurchaseOrder.js'; import FloatLabel from '../../Components/Forms/FloatLabel/index.jsx'; -import { FaLink, FaEye, FaUpload } from 'react-icons/fa'; +import { FaLink, FaEye } from 'react-icons/fa'; +import { TbUpload } from 'react-icons/tb'; import { getSupplaierIdBasedProducts, getSupplaierIdwithTypeBasedProducts, postSupplaierProducts, } from '../../Features/SupplierProductMapping/SupplierProductMapping.js'; -import { ApplicationPreferences, getCommonAppPreference } from '../../Features/BrachLogin/BranchLogin.js'; +import { + ApplicationPreferences, + getCommonAppPreference, +} from '../../Features/BrachLogin/BranchLogin.js'; import { getConfigType, getPaymentOptionFeatureApi, PendingOrdersPE, } from '../../Features/BookingScreen/BookingData/BookingData.js'; import InvoiceImageExtractorModal from './InvoiceImageExtractor.jsx'; -import { color } from 'highcharts'; import { v4 as uuidv4 } from 'uuid'; +import AddAllProductsButton from './AddAllProductGrid.jsx'; +import SettingsIconWithModal from './SettingsIconWithModal.jsx'; +import VirtualizedTable from './VirtualizedTable.jsx'; +import { useDebounce } from './UseDebounce.jsx'; const subDirectory = import.meta.env.BASE_URL; const EditableContext = React.createContext(null); @@ -161,12 +138,6 @@ const EditableCell = ({ margin: 0, }} name={dataIndex} - // rules={[ - // (dataIndex == "imei1" || dataIndex == "imei2") && { - // pattern: /^[0-9]{15}$/, - // message: 'IMEI must be a 15-digit number' - // } - // ]} > - { - const { Panel } = Collapse; + console.log('counttesttttttttttttttttttt'); const formRef = useRef(null); const productAddInfoRef = useRef(null); const formProductRef = useRef(null); - const formCategoryRef = useRef(null); - const formSubCategoryRef = useRef(null); - const formBrandRef = useRef(null); - const formTaxRef = useRef(null); + const formSupplierRef = useRef(null); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -222,112 +188,61 @@ const StockForm = ({ formType }) => { const [index, setindex] = useState(); const state = location?.state; const editstate = state?.editstate; + const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); - const [SupplierAppId, setSupplierAppId] = useState(getSession('AppId')); - const [SupplierBranchId, setSupplierBranchId] = useState( - getSession('BranchId') - ); - const [SupplierCompId, setSupplierCompId] = useState(getSession('CompId')); - const UserId = getSession('UserId'); - const ProdCatData = useSelector(prodCatDataSelector); - const ProdSubCatData = useSelector(prodSubCatDataSelector); - const ProdTaxData = useSelector(prodTaxDataSelector); - const TaxData = useSelector(taxSelector); - const BrandData = useSelector(brandDataSelector); const UomData = useSelector(uomDataSelector); - const ProductTypeData = useSelector(productTypeDataSelector); - const appPreferences = useSelector(ApplicationPreferences) + const appPreferences = useSelector(ApplicationPreferences); const [applicationRestrictedFields, setApplicationRestrictedFields] = useState({ DatesAndExpiry: false, BatchAndModelDetails: false, AmountPerPieceDetail: false, }); + + const [editingQty, setEditingQty] = useState({}); const [selectedAdditionalColumn, setSelectedAdditionalColumn] = useState([]); - console.log(selectedAdditionalColumn, "selectedAdditionalColumn") - const [showColumnModal, setShowColumnModal] = useState(false); - const [tempSelectedColumns, setTempSelectedColumns] = useState([]); const [tableFieldPreferences, setTableFieldPreferences] = useState([]); - const [selectedFields, setSelectedFields] = useState([]); const [SupplierData, setSupplierData] = useState([]); - const [StockOpen, setStockOpen] = useState('N'); const [SupplierOpen, setSupplierOpen] = useState('own'); const [purchaseOrderList, setPurchaseOrderList] = useState([]); const [selectedSupplierName, setSelectedSupplierName] = useState(); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); - const [productName, setProductName] = useState(null); const [searchText, setSearchText] = useState(null); const [productSearchText, setProductSearchText] = useState(''); const [selectedInvoice, setSelectedInvoice] = useState(null); const [orderType, setOrderType] = useState(true); - const [invoiceNo, setInvoiceNo] = useState(null); const [PurchaseTypeData, setPurchaseTypeData] = useState(null); const [SelectedPurchaseType, setSelectedPurchaseType] = useState(null); - const [PurcTaxTypeData, setPurcTaxTypeData] = useState(null); const [SelectedPurcTaxType, setSelectedPurcTaxType] = useState(null); - const [SelectedUom, setSelectedUom] = useState(null); - const [SelectedBrand, setSelectedBrand] = useState(null); - const [SelectedProdCat, setSelectedProdCat] = useState(null); - const [SelectedProdSubCat, setSelectedProdSubCat] = useState(null); - const [SelectedTaxId, setSelectedTaxId] = useState(null); - const [SelectedCategory, setSelectedCategory] = useState(null); - const [SelectedSubCategory, setSelectedSubCategory] = useState(null); - const [SelectedTaxNameId, setSelectedTaxNameId] = useState(null); - const [OpenAdd, setOpenAdd] = useState(false); - const [imageCategoryUrl, setCategoryImageUrl] = useState(''); - const [imageSubCategoryUrl, setSubCategoryImageUrl] = useState(''); - const [imageBrandUrl, setBrandImageUrl] = useState(''); const [PurchaseData, setPurchaseData] = useState([]); - console.log(PurchaseData, "PurchaseData") const [additionalInfoModal, setAdditionalInfoModal] = useState(false); const [selectedRowIndex, setSelectedRowIndex] = useState(null); const [selectedRowRecord, setSelectedRowRecord] = useState({}); const [purchaseOrderId, setPurchaseOrderId] = useState(); - const [VariantData1, setVariantData1] = useState([]); - const [selectedProductData, setSelectedProductData] = useState(null); - const [selectedProductVariantData, setselectedProductVariantData] = - useState(null); + const [selectedProductName, setSelectedProductName] = useState(null); const [scanner, setScanner] = useState(false); - const [Variants, setVariants] = useState(); const [Delete, setDelete] = useState(false); const [selectedSupplierData, setSelectedSupplierData] = useState(null); const [inwardDate, setInwardDate] = useState(new Date().toJSON()); - const [selectedVariantName, setSelectedVariantName] = useState(null); - const [SelInvoiceAmount, setSelInvoiceAmount] = useState(null); - const [TotalTaxAmount, setTotalTaxAmount] = useState(null); + const [SuppInvoiceDate, setSuppInvoiceDate] = useState(); const [invoiceType, setInvoiceType] = useState('I'); - const [InvoiceDate, setInvoiceDate] = useState(); const [PurchaseDate, setPurchaseDate] = useState(); const [paymentAmount, setPaymentAmount] = useState(null); - const [AddProductDetail, setAddProductDetail] = useState(); - const [OpenCategoryModel, setOpenCategoryModel] = useState(false); - const [OpenSubCategoryModel, setOpenSubCategoryModel] = useState(false); - const [OpenBrandModel, setOpenBrandModel] = useState(false); - const [OpenTaxModel, setOpenTaxModel] = useState(false); + const [OpenSupplierModel, setOpenSupplierModel] = useState(false); const [zipCodeData, setZipCodeData] = useState(false); - const [expandCollapseActive, setExpandCollapseActive] = useState('1'); - const [TokenOpen, setTokenOpen] = useState('N'); - const [QrcodeAuto, setQrcodeAuto] = useState('N'); - const [QrcodeAutoSingle, setQrcodeAutoSingle] = useState('N'); - const [AmountPerPieceAvailable, setAmountPerPieceAvailable] = useState('N'); - const [QrcodeFinalVal, setQrcodeFinalVal] = useState(); - const [QrcodeSingleFinalVal, setQrcodeSingleFinalVal] = useState(); - const [QrcodeExistsVal, setQrcodeExistsVal] = useState(); - const [QrcodeSingleExistsVal, setQrcodeSingleExistsVal] = useState(); const [imeiSerialOpen, setimeiSerialOpen] = useState(false); const [dataSource, setDataSource] = useState([]); const [dataSourceBackup, setDataSourceBackup] = useState([]); const [purchaseStatus, setPurchaseStatus] = useState('P'); const [isModalOpen, setIsModalOpen] = useState(false); const [productData, setProductData] = useState([]); - console.log(productData, 'productData'); const [message, setMessage] = useState({ type: null, data: null }); const [initialLoad, setInitialLoad] = useState(true); @@ -350,24 +265,32 @@ const StockForm = ({ formType }) => { const [extractorData, setExtractorData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [loadingText, setLoadingText] = useState(''); - const [filteredPurchaseData, setFilteredPurchaseData] = useState([]); + // const [filteredPurchaseData, setFilteredPurchaseData] = useState([]); const [searchValue, setSearchValue] = useState(''); const isSearching = Boolean(searchValue?.trim()); - useEffect(() => { - if (searchValue?.trim()) { - const search = searchValue.toLowerCase(); - const filtered = PurchaseData.filter(item => - item?.ProdName?.toLowerCase().includes(search) - ); + const SelInvoiceAmount = useMemo(() => { + const total = PurchaseData?.reduce( + (acc, item) => acc + Number(item?.Amount || 0), + 0 + ); + return !isNaN(total) && total !== 0 ? total : null; + }, [PurchaseData]); - setFilteredPurchaseData(filtered); - } else { - setFilteredPurchaseData([]); - } + const TotalTaxAmount = useMemo(() => { + return PurchaseData?.reduce( + (acc, item) => acc + Number(item?.TaxAmt || 0), + 0 + ); + }, [PurchaseData]); + + const filteredPurchaseData = useMemo(() => { + if (!searchValue?.trim()) return PurchaseData; + return PurchaseData.filter((item) => + item?.ProdName?.toLowerCase().includes(searchValue.toLowerCase()) + ); }, [PurchaseData, searchValue]); - const items = [ { name: 'Home', @@ -384,7 +307,7 @@ const StockForm = ({ formType }) => { }, ]; const categoryId = appPreferences?.find( - p => p?.PreferredCatName?.toLowerCase() === "purchase entry" + (p) => p?.PreferredCatName?.toLowerCase() === 'purchase entry' )?.PreferredCatId; useEffect(() => { dispatch(changeBreadCrumb({ items: items })); @@ -396,49 +319,18 @@ const StockForm = ({ formType }) => { dispatch(getProdCatData({ AppId: AppId })); dispatch(getUomData()); applicationApplicableFields(); - getPurchaseOrders(); getPurchaseType(); getPurchaseTaxType(); deliveryPerformance(); discountLevel(); qualityofSupp(); getSuplaierApi({}); - const fetchPaymentOptions = async () => { - try { - const response = await dispatch( - getPaymentOptionFeatureApi({ CompId, BranchId, AppId }) - ).unwrap(); - if (response?.data?.statusCode === 1) { - const paymentDetails = - response?.data?.data?.[0]?.PaymentDetails?.find( - (item) => item.FlowName === 'Sales' - )?.OptionDetails?.[0]?.ModeDetails?.filter( - (filter) => - filter.ModeName?.toLowerCase() === 'cash' || - filter.ModeName?.toLowerCase() === 'upi' || - filter.ModeName?.toLowerCase() === 'credit' - ); - setPaymentOptions(paymentDetails); - const modeId = paymentDetails?.find( - (item) => item.ModeName === 'Cash' - )?.ModeId; - setSelectedPaymentMode(modeId); - formRef.current?.setFieldsValue({ PaymentMode: modeId }); - } - } catch (error) { - setMessage({ - type: 'error', - data: error?.message || 'Failed to fetch payment options.', - }); - } - }; - fetchPaymentOptions(); if (formType == 'add') { formRef.current?.setFieldsValue({ SuppInvoiceDate: new Date().toJSON() }); setSuppInvoiceDate(new Date().toJSON()); formRef.current?.setFieldsValue({ InvoiceDate: new Date().toJSON() }); - setInvoiceDate(new Date().toJSON()); + // setInvoiceDate(new Date().toJSON()); formRef.current?.setFieldsValue({ DueDate: new Date().toJSON() }); setPurchaseDate(new Date().toJSON()); formRef.current?.setFieldsValue({ InvoiceDate: new Date().toJSON() }); @@ -458,23 +350,71 @@ const StockForm = ({ formType }) => { }); } handleSupplierBasedProduct(editstate?.SuppId); - setSelectedProductData(editstate?.ProdId); + // setSelectedProductData(editstate?.ProdId); setSelectedSupplierData(editstate?.SuppId); - setSelectedVariantName(editstate?.ProdVariantName); } }, []); useEffect(() => { - let UomId = UomData?.filter( - (item) => item.ConfigName?.toLowerCase() === 'pcs' - )?.[0]?.['ConfigId']; - formProductRef.current?.setFieldsValue({ UOM: UomId }); - setSelectedUom(UomId); - }, [UomData, AddProductDetail]); + if (SupplierOpen !== 'own') { + getPurchaseOrders(); + fetchPaymentOptions(); + } + }, [SupplierOpen]); + useEffect(() => { - let x = productData?.filter((e) => e.ProdId == selectedProductData); - setVariantData1(x?.[0]?.ProdVariantPriceDetails); - }, [selectedProductData]); + getFieldSetup(); + }, [categoryId]); + + useEffect(() => { + if (initialLoad && SupplierData?.length > 0) { + SetSelfSupplier(); + setInitialLoad(false); + } + }, [SupplierData]); + + useEffect(() => { + if (extractorData && selectedSupplierData) { + if ( + extractorData?.invoiceNo !== null && + extractorData?.invoiceNo !== '' + ) { + formRef?.current?.setFieldsValue({ + SuppInvoiceNo: extractorData?.invoiceNo, + }); + } + + formRef?.current?.setFieldsValue({ + PaymentAmount: extractorData?.TotalAmtData, + }); + setPaymentAmount(extractorData?.TotalAmtData); + onSuppInvoiceDateChange( + extractorData?.date, + extractorData?.date?.format('DD-MM-YYYY') || '' + ); + } + }, [selectedSupplierData]); + + useEffect(() => { + return () => { + debouncedScannerSearch.cancel(); + }; + }, []); + + const SetSelfSupplier = async () => { + let SupplierId = SupplierData?.filter( + (item) => item.SuppName?.toLowerCase() === 'self' + )?.[0]?.['SuppId']; + let SupplierName = SupplierData?.filter( + (item) => item.SuppName?.toLowerCase() === 'self' + )?.[0]?.['SuppName']; + formRef.current?.setFieldsValue({ CustSuppId: SupplierId }); + setSelectedSupplierData(SupplierId); + handleSupplierBasedProduct(SupplierId); + SupplierName === 'Self' + ? setSelectedSupplierName(false) + : setSelectedSupplierName(true); + }; const getSuplaierApi = async ({ dataReturn = false }) => { const response = await dispatch( @@ -494,81 +434,6 @@ const StockForm = ({ formType }) => { } }; - useEffect(() => { - if (formType == 'add') { - let ProductCatId = ProdCatData?.filter( - (item) => item.ConfigName?.toLowerCase() === 'general' - )?.[0]?.['ConfigId']; - dispatch(getProdSubCatData({ ConfigId: ProductCatId })); - formProductRef.current?.setFieldsValue({ ProdCat: ProductCatId }); - setSelectedProdCat(ProductCatId); - } - }, [ProdCatData, AddProductDetail]); - - useEffect(() => { - if (formType == 'add') { - let ProductSubCatId = ProdSubCatData?.filter( - (item) => item.ConfigName?.toLowerCase() === 'general' - )?.[0]?.['ConfigId']; - formProductRef.current?.setFieldsValue({ ProdSubCat: ProductSubCatId }); - setSelectedProdSubCat(ProductSubCatId); - } - }, [ProdSubCatData, AddProductDetail]); - - useEffect(() => { - if (formType == 'add') { - let TaxId = TaxData?.filter( - (item) => item.TaxIdName?.toLowerCase() === 'nil' - )?.[0]?.['TaxId']; - formRef.current?.setFieldsValue({ TaxId: TaxId }); - setSelectedTaxId(TaxId); - } - }, [TaxData, AddProductDetail]); - - useEffect(() => { - if (initialLoad && SupplierData?.length > 0) { - SetSelfSupplier(); - setInitialLoad(false); - } - }, [SupplierData]); - - const SetSelfSupplier = async () => { - let SupplierId = SupplierData?.filter( - (item) => item.SuppName?.toLowerCase() === 'self' - )?.[0]?.['SuppId']; - let SupplierName = SupplierData?.filter( - (item) => item.SuppName?.toLowerCase() === 'self' - )?.[0]?.['SuppName']; - formRef.current?.setFieldsValue({ CustSuppId: SupplierId }); - setSelectedSupplierData(SupplierId); - handleSupplierBasedProduct(SupplierId); - SupplierName === 'Self' - ? setSelectedSupplierName(false) - : setSelectedSupplierName(true); - }; - - useEffect(() => { - const total = PurchaseData?.reduce((acc, item) => { - return acc + Number(item?.Amount || 0); - }, 0); - - const invoiceAmount = - !isNaN(total) && total !== 0 ? total : null; - - setSelInvoiceAmount(invoiceAmount); - - formRef.current?.setFieldsValue({ - InvoiceAmount: invoiceAmount, - }); - - const totalTax = PurchaseData?.reduce((acc, item) => { - return acc + Number(item?.TaxAmt || 0); - }, 0); - - setTotalTaxAmount(totalTax); - }, [PurchaseData]); - - const getPurchaseOrders = async () => { const { data: res } = await dispatch( PendingOrdersPE({ CompId, AppId, BranchId }) @@ -587,10 +452,37 @@ const StockForm = ({ formType }) => { } }; + const fetchPaymentOptions = async () => { + try { + const response = await dispatch( + getPaymentOptionFeatureApi({ CompId, BranchId, AppId }) + ).unwrap(); + if (response?.data?.statusCode === 1) { + const paymentDetails = response?.data?.data?.[0]?.PaymentDetails?.find( + (item) => item.FlowName === 'Sales' + )?.OptionDetails?.[0]?.ModeDetails?.filter( + (filter) => + filter.ModeName?.toLowerCase() === 'cash' || + filter.ModeName?.toLowerCase() === 'upi' || + filter.ModeName?.toLowerCase() === 'credit' + ); + setPaymentOptions(paymentDetails); + const modeId = paymentDetails?.find( + (item) => item.ModeName === 'Cash' + )?.ModeId; + setSelectedPaymentMode(modeId); + formRef.current?.setFieldsValue({ PaymentMode: modeId }); + } + } catch (error) { + setMessage({ + type: 'error', + data: error?.message || 'Failed to fetch payment options.', + }); + } + }; + const findMatchingSuppliers = async (name, mobile, supplierData) => { let list = []; - console.log(name, mobile, 'listlistlist', supplierData); - // 1️⃣ Mobile number takes full priority if (mobile) { const m = mobile; list = supplierData.filter((x) => @@ -612,21 +504,25 @@ const StockForm = ({ formType }) => { ); return { mappedSupplierProducts, SuppId: finalList?.[0]?.SuppId }; }; - useEffect(() => { - getFieldSetup(); - }, [categoryId]) + const getFieldSetup = async () => { try { - const response = await dispatch(getFieldSetupData({ AppId, CompId, BranchId, categoryId, Type: "PE" })).unwrap(); + const response = await dispatch( + getFieldSetupData({ AppId, CompId, BranchId, categoryId, Type: 'PE' }) + ).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) || []); - setSelectedAdditionalColumn(response?.data?.data?.[0]?.ConfigDtl?.filter(c => c.ConfigId && c.Access === 'Y')?.map(c => c.ConfigName) || []) - setTableFieldPreferences(response?.data?.data?.[0]?.ConfigDtl?.map(c => ({ - value: c.ConfigId, - label: c.ConfigName, - access: c.Access - })) || []); + setSelectedAdditionalColumn( + response?.data?.data?.[0]?.ConfigDtl?.filter( + (c) => c.ConfigId && c.Access === 'Y' + )?.map((c) => c.ConfigName) || [] + ); + setTableFieldPreferences( + response?.data?.data?.[0]?.ConfigDtl?.map((c) => ({ + value: c.ConfigId, + label: c.ConfigName, + access: c.Access, + })) || [] + ); } } catch (error) { console.error('Error fetching field setup:', error); @@ -634,9 +530,9 @@ const StockForm = ({ formType }) => { }; const AddSupplierimg = async (subSupplierData) => { const addSupplierData = { - CompId: getSession('CompId'), - AppId: getSession('AppId'), - BranchId: getSession('BranchId'), + CompId: CompId, + AppId: AppId, + BranchId: BranchId, SuppName: subSupplierData?.SuppName, SuppGSTIN: subSupplierData?.SuppGSTIN, SuppPOC: subSupplierData?.SuppPOC, @@ -685,7 +581,6 @@ const StockForm = ({ formType }) => { setIsLoading(true); setLoadingText('Processing extracted data...'); setExtractorData(data); - console.log('mohan Extractor data received:', data); let supplierProducts = []; let suppId = null; if (data?.supplierSuggestions?.length > 0) { @@ -712,7 +607,6 @@ const StockForm = ({ formType }) => { suppId = SuppId; supplierProducts = mappedSupplierProducts; } - console.log(supplierProducts, 'supplierProductssupplierProducts'); // check if the products from extractor exist in the supplier's products setLoadingText('Matching products with supplier...'); @@ -743,8 +637,8 @@ const StockForm = ({ formType }) => { const allSupplierProducts = response?.data?.data || []; const matchingProdIds = []; - const NewImageProducts = [] - console.log(unmatchedProducts, "unmatchedProductsunmatchedProducts") + const NewImageProducts = []; + console.log(unmatchedProducts, 'unmatchedProductsunmatchedProducts'); // check if the unmatched products exists in our products list unmatchedProducts.forEach((item) => { const match = allSupplierProducts?.[0]?.ProductDetails.find( @@ -754,55 +648,52 @@ const StockForm = ({ formType }) => { ); if (match) { matchingProdIds.push(match.ProdId); - } - else { + } else { NewImageProducts.push(item?.parsedData); } }); - console.log(NewImageProducts, "NewImageProductsNewImageProducts") // Bulk upload new image products if (NewImageProducts.length > 0) { - const newProductsData = NewImageProducts.map(product => ({ + const newProductsData = NewImageProducts.map((product) => ({ AppId: AppId || 0, - CompId: CompId || "", - BranchId: BranchId || "", + CompId: CompId || '', + BranchId: BranchId || '', CreatedBy: UserId || 0, - ProdName: product.description?.trim() || "", - ProdVariantName: "", - Size: 1 || "", - UOM: product.unit || "", + ProdName: product.description?.trim() || '', + ProdVariantName: '', + Size: 1 || '', + UOM: product.unit || '', MRP: parseFloat(product.rate) || 0, WhSalePrice: 0, SellPrice: parseFloat(product.rate) || 0, - ProdCat: "General", - ProdSubCat: "", - Brand: "", - AutoGenerateQr: "", - QRCode: "", + ProdCat: 'General', + ProdSubCat: '', + Brand: '', + AutoGenerateQr: '', + QRCode: '', StockAvailable: 'No', - TaxId: "", - HSNCode: "", - PartNumber: "", + HSNCode: '', + PartNumber: '', Rack: 0, - ManufDate: "", - ExpDate: "", - AvailableFrom: "", - AvailableTo: "", - ProdLogo: "", - OnePcsAvailable: "No", + ManufDate: '', + ExpDate: '', + AvailableFrom: '', + AvailableTo: '', + ProdLogo: '', + OnePcsAvailable: 'No', AutoGenerateSingleQr: 'No', TaxId: 'NIL - 0%', - OnePcQR: "", + OnePcQR: '', TokenAvailable: 'No', OpeningQty: 0, - QtyBasedPrice: "", - InwardDate: "", - SuppId: suppId || "", - Reference: "", + QtyBasedPrice: '', + InwardDate: '', + SuppId: suppId || '', + Reference: '', ReceivedQty: 0, AcceptedQty: 0, RejectedQty: 0, - RejectionReason: "", + RejectionReason: '', IssuedQty: 0, BalanceQty: 0, InwardPrice: 0, @@ -811,23 +702,32 @@ const StockForm = ({ formType }) => { Cess: 0, })); - const bulkResponse = await dispatch(bulkpostdata({ ProdDetails: newProductsData })).unwrap(); + const bulkResponse = await dispatch( + bulkpostdata({ ProdDetails: newProductsData }) + ).unwrap(); if (bulkResponse?.data?.statusCode === 1) { // After successful bulk upload, check the condition again const updatedResponse = await dispatch( - getSupplaierIdBasedProducts({ CompId, AppId, BranchId, SuppId: suppId }) + getSupplaierIdBasedProducts({ + CompId, + AppId, + BranchId, + SuppId: suppId, + }) ).unwrap(); if (updatedResponse?.data?.statusCode === 1) { - const updatedAllSupplierProducts = updatedResponse?.data?.data || []; + const updatedAllSupplierProducts = + updatedResponse?.data?.data || []; const updatedMatchingProdIds = []; unmatchedProducts.forEach((item) => { - const match = updatedAllSupplierProducts?.[0]?.ProductDetails.find( - (supp) => - supp?.ProdName?.toLowerCase() === - item?.parsedData?.description?.toLowerCase() - ); + const match = + updatedAllSupplierProducts?.[0]?.ProductDetails.find( + (supp) => + supp?.ProdName?.toLowerCase() === + item?.parsedData?.description?.toLowerCase() + ); if (match) { updatedMatchingProdIds.push(match.ProdId); } @@ -921,7 +821,7 @@ const StockForm = ({ formType }) => { setPurchaseData(purchasedData); if (purchasedData.length > 0) { for (const item of purchasedData) { - const index = purchasedData.indexOf(item); + // const index = purchasedData.indexOf(item); const localId = item?.localId; form.setFieldsValue({ ...form.getFieldsValue(), @@ -970,7 +870,6 @@ const StockForm = ({ formType }) => { for (const item of matchedProducts) { if (item.matchFound) { const newProduct = await ProductDropDownChange( - item?.selectedProduct?.ProdVariantName, item.selectedProdId, { label: item.selectedProduct.ProdName }, @@ -1005,7 +904,7 @@ const StockForm = ({ formType }) => { setPurchaseData(purchasedData); if (purchasedData.length > 0) { for (const item of purchasedData) { - const index = purchasedData.indexOf(item); + // const index = purchasedData.indexOf(item); const localId = item?.localId; form.setFieldsValue({ ...form.getFieldsValue(), @@ -1099,15 +998,16 @@ const StockForm = ({ formType }) => { const getPurchaseTaxType = async () => { let res = await dispatch(getPurchaseTaxTypeData()).unwrap(); if (res?.data?.statusCode === 1) { - setPurcTaxTypeData(res?.data?.data); + // setPurcTaxTypeData(res?.data?.data); let tempniltax = res?.data?.data?.find( (item) => item?.ConfigName?.toLowerCase() === 'inclusive' ); setSelectedPurcTaxType(tempniltax?.ConfigId); formRef.current?.setFieldsValue({ TaxType: tempniltax?.ConfigId }); - } else { - setPurcTaxTypeData(null); } + // else { + // setPurcTaxTypeData(null); + // } }; const pinCodeChange = async (e) => { if (e.target.value?.length < 6) { @@ -1147,52 +1047,17 @@ const StockForm = ({ formType }) => { const handleSuppInvoiceNoChange = (e) => { const value = e.target.value; formRef.current?.setFieldsValue({ SuppInvoiceNo: value }); - setExtractorData(prev => prev ? { ...prev, invoiceNo: value } : null); + setExtractorData((prev) => (prev ? { ...prev, invoiceNo: value } : null)); }; const handleInvoiceTypeChange = (value) => { setInvoiceType(value); }; - const handleSellPrice = (rule, value, callback) => { - if ( - parseInt(formProductRef?.current?.getFieldsValue()?.MRP) >= - parseInt(value) - ) { - callback(); - } else { - callback('Please enter retail less than MRP'); - } - }; - const handleInwardDateChange = (date) => { - console.log(date, 'date'); setInwardDate(date); }; - useEffect(() => { - if (extractorData && selectedSupplierData) { - console.log( - formRef?.current?.getFieldsValue(), - 'formRefformRefformRefformRef' - ); - if (extractorData?.invoiceNo !== null && extractorData?.invoiceNo !== "") { - formRef?.current?.setFieldsValue({ - SuppInvoiceNo: extractorData?.invoiceNo, - }); - } - - formRef?.current?.setFieldsValue({ - PaymentAmount: extractorData?.TotalAmtData, - }); - setPaymentAmount((extractorData?.TotalAmtData)); - onSuppInvoiceDateChange( - extractorData?.date, - extractorData?.date?.format('DD-MM-YYYY') || '' - ); - } - }, [selectedSupplierData]); - // formRef?.current?.setFieldsValue({ SuppInvoiceNo: extractorData?.invoiceNo }); const handleSupplierDropDownChange = async ( @@ -1200,12 +1065,6 @@ const StockForm = ({ formType }) => { option, suppliers = null ) => { - let SuppDtl = (suppliers || SupplierData).filter( - (item) => item.SuppId == SuppId - )?.[0]; - setSupplierAppId(SuppDtl?.SuppAppId); - setSupplierCompId(SuppDtl?.SuppCompId); - setSupplierBranchId(SuppDtl?.SuppBranchId); let suppName = (suppliers || SupplierData)?.filter( (item) => item.SuppId == SuppId )?.[0]?.SuppName; @@ -1216,8 +1075,8 @@ const StockForm = ({ formType }) => { suppName === 'Self' ? setSelectedSupplierName(false) : setSelectedSupplierName(true); - setselectedProductVariantData(null); - setSelectedProductData(null); + // setselectedProductVariantData(null); + // setSelectedProductData(null); setSelectedProductName(null); formRef?.current?.setFieldsValue({ ProdId: null }); setSearchText(null); @@ -1240,17 +1099,7 @@ const StockForm = ({ formType }) => { setSuppInvoiceDate(); } }; - const onInvoiceDateChange = async (date, dateString) => { - if (dateString) { - const Date3 = moment(dateString, ['DD-MM-YYYY']).format( - 'YYYY-MM-DDTHH:mm:ss' - ); - formRef.current?.setFieldsValue({ InvoiceDate: Date3 }); - setInvoiceDate(Date3); - } else if (dateString === '') { - setInvoiceDate(); - } - }; + const onPurchaseDateChange = async (date, dateString) => { if (dateString) { const Date3 = moment(dateString, ['DD-MM-YYYY']).format( @@ -1272,56 +1121,29 @@ const StockForm = ({ formType }) => { extractedItem, existingProducts ) => { - setProductSearchText(''); setSelectedProductName(option?.label ? option?.label : ''); formRef?.current?.resetFields(['VarProdId']); - setselectedProductVariantData(null); - setSelectedProductData(ProdId); - - // let x = (productsList || productData)?.find( - // (e) => e.ProdId == ProdId - // )?.ProdName; - let OnePcsAvailable = (productsList || productData)?.find((e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName)?.OnePcsAvailable == 'Y'; - // let variantValues1 = await dispatch( - // getProdvaraiantdata({ - // CompId: SupplierCompId, - // AppId: SupplierAppId, - // BranchId: SupplierBranchId, - // prodName: x, - // }) - // ).unwrap(); - // let variants = variantValues1?.data?.data; - - // let cc = variants?.filter((variant) => - // variant?.ProductDetail?.some((e) => e.ProdId == ProdId) - // )?.[0]?.ProductDetail; - - // setVariants( - // cc?.[0]?.ProdVariantDetails?.map((detail) => ({ - // ...detail, - // ProdIdProdName: `${detail.ProdVariantName} ${detail.ProdId}`, - // OnePcsAvailable, - // })) - // ); - - if (true - // cc?.[0]?.ProdVariantDetails?.length < 2 || - // (extractedProduct ? cc?.[0]?.ProdVariantDetails?.length > 0 : false) - ) { - // let getSuppId = (productsList || productData)?.filter((item) => item.ProdId == ProdId); + // setselectedProductVariantData(null); + if (true) { formRef.current?.setFieldsValue({ ProdId: ProdId }); - await setSelectedProductData(ProdId); - // await setSelectedSupplierData(getSuppId?.[0]?.["SuppId"]) ,CustSuppId:getSuppId?.[0]?.["SuppId"] - if ((existingProducts || PurchaseData)?.some((e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName)) { - const existingProduct = (existingProducts || PurchaseData)?.find((e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName); - setMessageType('error'); - setMessageData(`Product "${existingProduct?.ProdName} - ${existingProduct?.ProdVariantName}" already exists`); - return null; - } - else { + // await setSelectedProductData(ProdId); + if ( + (existingProducts || PurchaseData)?.some( + (e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName + ) + ) { + const existingProduct = (existingProducts || PurchaseData)?.find( + (e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName + ); + setMessageType('error'); + setMessageData( + `Product "${existingProduct?.ProdName} - ${existingProduct?.ProdVariantName}" already exists` + ); + return null; + } else { let ProductData1 = (productsList || productData)?.find( (e) => e.ProdId == ProdId && e?.ProdVariantName == VariantName ); @@ -1337,8 +1159,6 @@ const StockForm = ({ formType }) => { SellPrice: ProductData1?.SellPrice, StockAvailable: ProductData1?.StockAvailable, OnePcsAvailable: ProductData1?.OnePcsAvailable, - // NumberofPieceinside: ProductData1?.NoOfPcs, - // AmountPerPiece: ProductData1?.OnePcsPrice, OnePcsPrice: ProductData1?.OnePcsPrice, NoOfPcs: ProductData1?.NoOfPcs, TaxId: ProductData1?.TaxId, @@ -1369,7 +1189,6 @@ const StockForm = ({ formType }) => { RejectedQty: qty - acceptedQty, OfferPrice: 0, SpecialPrice: 0, - // ProdVariantName: 'Variant 1', FreeItem: 0, TaxAmt: 0, TaxType: SelectedPurcTaxType ? SelectedPurcTaxType : 0, @@ -1384,6 +1203,81 @@ const StockForm = ({ formType }) => { } }; + const handleProductSelect = async (value, option) => { + const [prodId, variantName] = value?.split('_'); + + const product = productData.find( + (p) => p.ProdId === prodId && p.ProdVariantName === variantName + ); + + if (!product) return; + + // Check for duplicates + const exists = PurchaseData.some( + (p) => p.ProdId === prodId && p.ProdVariantName === variantName + ); + if (exists) { + const existingProduct = PurchaseData.find( + (p) => p.ProdId === prodId && p.ProdVariantName === variantName + ); + setMessageType('error'); + setMessageData( + `Product "${existingProduct?.ProdName} - ${existingProduct?.ProdVariantName}" already exists` + ); + return; + } + + // Build product row + const defaultVariant = product.ProdVariantPriceDetails?.find( + (item) => item?.DefaultVariant === 'Y' && item?.ReceivedQty === 0 + )?.DefaultVariant; + + const newRow = { + ProdId: product.ProdId, + ProdName: product.ProdName, + ProdVariantName: product.ProdVariantName, + UomName: product.UomName, + MRP: product.MRP, + SellPrice: product.SellPrice, + OnePcsPrice: product.OnePcsPrice, + NoOfPcs: product.NoOfPcs, + StockAvailable: product.StockAvailable, + OnePcsAvailable: product.OnePcsAvailable, + TaxId: product.TaxId, + TaxPercentage: product.TaxPercentage, + DefaultVariant: defaultVariant, + PurchaseTax: 0, + BalanceQty: 0, + InwardPrice: 0, + ReceivedQty: 0, + AcceptedQty: 0, + RejectedQty: 0, + Amount: 0, + WhSalePrice: 0, + OfferPrice: 0, + SpecialPrice: 0, + FreeItem: 0, + TaxAmt: 0, + PurcDisc: 0, + PurcDiscType: 'P', + PurchaseHSNCode: product.PurchaseHSNCode || '', + refImage: product?.image || '', + localId: uuidv4(), + }; + + // ✅ Single state update: update PurchaseData + form fields together + setPurchaseData((prev) => [newRow, ...prev]); + form?.setFieldsValue({ + [`SellPrice${newRow.localId}`]: newRow.SellPrice, + [`PurchaseTax${newRow.localId}`]: newRow.PurchaseTax, + ProdId: prodId, + }); + + // Reset search text + setProductSearchText(''); + setSelectedProductName(option?.label || ''); + }; + const debouncedScannerSearch = useCallback( debounce(async (value) => { const qr = value?.trim(); @@ -1404,7 +1298,7 @@ const StockForm = ({ formType }) => { } if (matchedProduct?.ProdVariantPriceDetails?.length < 2) { setSelectedProductName(''); - setSelectedProductData(null); + // setSelectedProductData(null); } } else { setMessageType('error'); @@ -1415,19 +1309,13 @@ const StockForm = ({ formType }) => { ); // Clean up debounce on unmount - useEffect(() => { - return () => { - debouncedScannerSearch.cancel(); - }; - }, []); + const handleProductSearch = (value) => { if (scanner) { debouncedScannerSearch(value); } setProductSearchText(value); setSelectedProductName(value); - setselectedProductVariantData([]); - setVariants([]); }; const handleScanSearch = () => { if (scanner === false) { @@ -1439,252 +1327,27 @@ const StockForm = ({ formType }) => { } setScanner((prev) => !prev); setSelectedProductName(null); - setselectedProductVariantData(null); - setVariants(null); + // setselectedProductVariantData(null); + // setVariants(null); formRef?.current?.setFieldsValue({ ProdId: null, VarProdId: null, }); }; - const handleTaxDropDownChange = async (TaxId) => { - formProductRef.current?.setFieldsValue({ TaxId: TaxId }); - await setSelectedTaxId(TaxId); - }; - - const handleKeyPressSingle = (e) => { - // Prevent form submission on Enter key press - if (e.key === 'Enter') { - e.preventDefault(); - } - }; - - const handleInput = async (val) => { - if (val?.target?.value?.length >= 5) { - let QRCodeData = await dispatch( - getQrcodeData({ QRCode: val?.target?.value }) - ).unwrap(); - if (QRCodeData?.data?.statusCode == 0) { - setQrcodeFinalVal(val?.target?.value); - // setMessageType("success"); - // setMessageData("Qrcode Added :" + `${val?.target?.value}`); - } else { - let existsQrcodeData = QRCodeData?.data?.data?.filter( - (item) => - item?.AppId === AppId && - item?.CompId === CompId && - item?.BranchId === BranchId - ); - if (existsQrcodeData?.length > 0) { - setQrcodeFinalVal(null); - formRef.current?.setFieldsValue({ QRCode: null }); - setQrcodeExistsVal(existsQrcodeData?.[0]?.QRCode); - - setMessageType('error'); - setMessageData('Qrcode Already Exists'); - } else { - // setQrcodeExistsData(QRCodeData.data?.data) - // setQrcodeExistsDataOpen(true) - setQrcodeFinalVal(val?.target?.value); - // setMessageType("success"); - // setMessageData("Qrcode Added :" + `${val?.target?.value}`); - setQrcodeAuto('N'); - } - } - } - }; - const handleInputSingle = async (val) => { - setQrcodeSingleFinalVal(val?.target?.value); - if (val?.target?.value?.length >= 5) { - let QRCodeData = await dispatch( - getsingleQrcodeData({ QRCode: val?.target?.value }) - ).unwrap(); - if (QRCodeData.data?.statusCode == 0) { - setQrcodeSingleFinalVal(val?.target?.value); - // setMessageType("success"); - // setMessageData("Qrcode Added :" + `${val?.target?.value}`); - } else { - let existsQrcodeData = QRCodeData?.data?.data?.filter( - (item) => - item?.AppId === AppId && - item?.CompId === CompId && - item?.BranchId === BranchId - ); - if (existsQrcodeData?.length > 0) { - setQrcodeSingleFinalVal(null); - formRef.current?.setFieldsValue({ QRCodeSingle: null }); - setQrcodeSingleExistsVal(val?.target?.value); - - setMessageType('error'); - setMessageData('Qrcode Already Exists'); - } else { - // setQrcodeExistsData(QRCodeData.data?.data) - // setQrcodeExistsDataOpen(true) - setQrcodeSingleFinalVal(val?.target?.value); - // setMessageType("success"); - // setMessageData("Qrcode Added :" + `${val?.target?.value}`); - setQrcodeAutoSingle('N'); - } - } - } - }; - const addSupplier = () => { setOpenSupplierModel(true); }; const handleSupplier = () => { setOpenSupplierModel(false); }; - const handleCategory = () => { - setOpenCategoryModel(false); - setCategoryImageUrl(''); - formCategoryRef?.current?.resetFields(); - }; - const handleSubCategory = () => { - setOpenSubCategoryModel(false); - setSubCategoryImageUrl(''); - setSelectedCategory(null); - formSubCategoryRef?.current?.resetFields(); - }; - - const handleBrand = () => { - setOpenBrandModel(false); - setBrandImageUrl(''); - setSelectedSubCategory(null); - formBrandRef?.current?.resetFields(); - }; - - const handleTax = () => { - setOpenTaxModel(false); - }; - const submitCategory = async () => { - const categoryData = await formCategoryRef?.current?.validateFields(); - const categoryTypeId = await dispatch( - getConfigTypeData({ TypeName: 'Product Category' }) - ).unwrap(); - const addCategoryData = { - TypeId: categoryTypeId?.data?.data?.[0]?.TypeId, - ConfigName: categoryData?.ConfigName, - AlphaNumFId: AppId, - SmallIcon: imageCategoryUrl, - CreatedBy: UserId, - }; - - let response = {}; - response = await dispatch(postConfiguration(addCategoryData)).unwrap(); - if (response?.data?.statusCode == 1) { - setCategoryImageUrl(''); - setMessageType('success'); - setMessageData(response?.data?.response); - setOpenCategoryModel(false); - dispatch(getProdCatData({ AppId: AppId })); - formCategoryRef?.current?.resetFields(); - } else { - setCategoryImageUrl(''); - setMessageType('error'); - setMessageData(response?.data?.response); - formCategoryRef?.current?.resetFields(); - } - }; - - const submitSubCategory = async () => { - const subCategoryData = await formSubCategoryRef?.current?.validateFields(); - const subCategoryTypeId = await dispatch( - getConfigTypeData({ TypeName: 'Product Sub-Category' }) - ).unwrap(); - const addSubCategoryData = { - TypeId: subCategoryTypeId?.data?.data?.[0]?.TypeId, - ConfigName: subCategoryData?.SubConfigName, - AlphaNumFId: AppId, - NumFId: SelectedCategory, - SmallIcon: imageSubCategoryUrl, - CreatedBy: UserId, - }; - let response = {}; - response = await dispatch(postConfiguration(addSubCategoryData)).unwrap(); - if (response?.data?.statusCode == 1) { - setSubCategoryImageUrl(''); - setMessageType('success'); - setMessageData(response?.data?.response); - setOpenSubCategoryModel(false); - setSelectedCategory(null); - dispatch(getProdSubCatData({ ConfigId: SelectedCategory })); - formSubCategoryRef?.current?.resetFields(); - } else { - setSubCategoryImageUrl(''); - setSelectedCategory(null); - setMessageType('error'); - setMessageData(response?.data?.response); - formSubCategoryRef?.current?.resetFields(); - } - }; - - const submitBrand = async () => { - const subBrandData = await formBrandRef?.current?.validateFields(); - const subBrandTypeId = await dispatch( - getConfigTypeData({ TypeName: 'Product Brand' }) - ).unwrap(); - const addBrandData = { - TypeId: subBrandTypeId?.data?.data?.[0]?.TypeId, - ConfigName: subBrandData?.SubConfigName, - AlphaNumFId: AppId, - NumFId: SelectedSubCategory, - SmallIcon: imageBrandUrl, - CreatedBy: UserId, - }; - let response = {}; - response = await dispatch(postConfiguration(addBrandData)).unwrap(); - if (response?.data?.statusCode == 1) { - setBrandImageUrl(''); - setMessageType('success'); - setMessageData(response?.data?.response); - setOpenBrandModel(false); - setSelectedSubCategory(null); - dispatch(getBrandData({ ConfigId: SelectedSubCategory })); - formBrandRef?.current?.resetFields(); - } else { - setBrandImageUrl(''); - setSelectedSubCategory(null); - setMessageType('error'); - setMessageData(response?.data?.response); - formBrandRef?.current?.resetFields(); - } - }; - - const submitTax = async () => { - const subTaxData = await formTaxRef?.current?.validateFields(); - const effectiveDate = new Date(subTaxData.EffectiveFrom); - const formattedDate = effectiveDate.toLocaleDateString('en-CA'); - const addTaxData = { - CompId: getSession('CompId'), - AppId: getSession('AppId'), - TaxName: subTaxData?.TaxName, - TaxPercentage: subTaxData?.TaxPercentage, - EffectiveFrom: formattedDate, - Reference: subTaxData?.Reference, - CreatedBy: UserId, - }; - let response = {}; - response = await dispatch(postTax(addTaxData)).unwrap(); - if (response?.data?.statusCode == 1) { - setMessageType('success'); - setMessageData(response?.data?.response); - setOpenTaxModel(false); - dispatch(getAdmin({ CompId: CompId, AppId: AppId })); - formTaxRef?.current?.resetFields(); - } else { - setMessageType('error'); - setMessageData(response?.data?.response); - formTaxRef?.current?.resetFields(); - } - }; const submitSupplier = async () => { const subSupplierData = await formSupplierRef?.current?.validateFields(); const addSupplierData = { - CompId: getSession('CompId'), - AppId: getSession('AppId'), - BranchId: getSession('BranchId'), + CompId: CompId, + AppId: AppId, + BranchId: BranchId, SuppName: subSupplierData?.SuppName, SuppGSTIN: subSupplierData?.SuppGSTIN, SuppPOC: subSupplierData?.SuppPOC, @@ -1728,78 +1391,64 @@ const StockForm = ({ formType }) => { formSupplierRef?.current?.resetFields(); } }; + useEffect(() => { + if (!editingKey) return; - const getOptionLabel = (option, selected) => { - return selected - ? option.TaxPercentage + ' %' - : option.TaxIdName + ' - ' + option.TaxPercentage + ' % '; - }; + const record = PurchaseData.find((item) => item.localId === editingKey); + if (!record) return; - const isEditing = (record, index) => record?.localId === editingKey; + const localId = record.localId; + const values = Delete + ? { + [`BalanceQty${localId}`]: undefined, + [`ReceivedQty${localId}`]: undefined, + [`AcceptedQty${localId}`]: undefined, + [`RejectedQty${localId}`]: undefined, + [`Amount${localId}`]: undefined, + [`Freeqty${localId}`]: undefined, + [`InwardPrice${localId}`]: undefined, + [`MRP${localId}`]: undefined, + [`PurcDisc${localId}`]: undefined, + [`SellPrice${localId}`]: undefined, + [`WhSalePrice${localId}`]: undefined, + [`offerSalePrice${localId}`]: undefined, + [`splSalePrice${localId}`]: undefined, + [`NumberofPieceinside${localId}`]: undefined, + [`AmountPerPiece${localId}`]: undefined, + [`PurcDiscType${localId}`]: undefined, + [`ManufDate${localId}`]: undefined, + [`ExpDate${localId}`]: undefined, + [`OnePcsPrice${localId}`]: undefined, + [`NoOfPcs${localId}`]: undefined, + } + : { + [`BalanceQty${localId}`]: record.BalanceQty, + [`ReceivedQty${localId}`]: record.ReceivedQty, + [`AcceptedQty${localId}`]: record.AcceptedQty, + [`RejectedQty${localId}`]: record.RejectedQty, + [`Freeqty${localId}`]: record.FreeItem, + [`MRP${localId}`]: record.MRP, + [`ManufDate${localId}`]: record.ManufDate, + [`ExpDate${localId}`]: record.ExpDate, + [`SellPrice${localId}`]: record.SellPrice, + [`WhSalePrice${localId}`]: record.WhSalePrice, + [`PurcDiscType${localId}`]: record.PurcDiscType, + [`Amount${localId}`]: record.Amount, + [`InwardPrice${localId}`]: record.InwardPrice, + [`PurcDisc${localId}`]: record.PurcDisc, + [`offerSalePrice${localId}`]: record.OfferPrice, + [`splSalePrice${localId}`]: record.SpecialPrice, + [`OnePcsPrice${localId}`]: record.OnePcsPrice, + [`NoOfPcs${localId}`]: record.NoOfPcs, + }; - const edit = (record, index) => { - const localId = record?.localId; - form.setFieldsValue({ ...record }); - - setEditingKey(localId); - setindex(localId); - - if (Delete) { - form.setFieldsValue({ - [`BalanceQty${localId}`]: undefined, - [`ReceivedQty${localId}`]: undefined, - [`AcceptedQty${localId}`]: undefined, - [`RejectedQty${localId}`]: undefined, - [`Amount${localId}`]: undefined, - [`Freeqty${localId}`]: undefined, - [`InwardPrice${localId}`]: undefined, - [`MRP${localId}`]: undefined, - [`PurcDisc${localId}`]: undefined, - [`SellPrice${localId}`]: undefined, - [`WhSalePrice${localId}`]: undefined, - [`offerSalePrice${localId}`]: undefined, - [`splSalePrice${localId}`]: undefined, - [`NumberofPieceinside${localId}`]: undefined, - [`AmountPerPiece${localId}`]: undefined, - [`PurcDiscType${localId}`]: undefined, - [`ManufDate${localId}`]: undefined, - [`ExpDate${localId}`]: undefined, - [`OnePcsPrice${localId}`]: undefined, - [`NoOfPcs${localId}`]: undefined, - }); - setDelete(false); - } else { - form.setFieldsValue({ - [`BalanceQty${localId}`]: record?.BalanceQty, - [`ReceivedQty${localId}`]: record?.ReceivedQty, - [`AcceptedQty${localId}`]: record?.AcceptedQty, - [`RejectedQty${localId}`]: record?.RejectedQty, - [`Freeqty${localId}`]: record?.FreeItem, - [`MRP${localId}`]: record?.MRP, - [`ManufDate${localId}`]: record?.ManufDate, - [`ExpDate${localId}`]: record?.ExpDate, - [`SellPrice${localId}`]: record?.SellPrice, - [`WhSalePrice${localId}`]: record?.WhSalePrice, - [`PurcDiscType${localId}`]: record?.PurcDiscType, - [`Amount${localId}`]: record?.Amount, - [`InwardPrice${localId}`]: record?.InwardPrice, - [`PurcDisc${localId}`]: record?.PurcDisc, - [`offerSalePrice${localId}`]: record?.OfferPrice, - [`splSalePrice${localId}`]: record?.SpecialPrice, - [`OnePcsPrice${localId}`]: record?.OnePcsPrice, - [`NoOfPcs${localId}`]: record?.NoOfPcs, - - - }); - - - if (applicationRestrictedFields.BatchAndModelDetails) { - form.setFieldsValue({ - [`BatchRef${localId}`]: record?.BatchRef, - }); - } + if (!Delete && applicationRestrictedFields.BatchAndModelDetails) { + values[`BatchRef${localId}`] = record.BatchRef; } - }; + + form.setFieldsValue(values); + setDelete(false); + }, [editingKey]); const save = async (localId) => { try { @@ -1810,16 +1459,14 @@ const StockForm = ({ formType }) => { for (const key in row) { // remove localId suffix from field names if (key.endsWith(localId)) { - const newKey = key.replace(localId, ''); + const newKey = key?.replace(localId, ''); modifiedObject[newKey] = row[key]; } } setPurchaseData((prev) => prev.map((item) => - item.localId === localId - ? { ...item, ...modifiedObject } - : item + item.localId === localId ? { ...item, ...modifiedObject } : item ) ); @@ -1829,7 +1476,6 @@ const StockForm = ({ formType }) => { } }; - const handleKeyPress = async (e, record) => { if (e.key === 'Enter') { try { @@ -1841,12 +1487,24 @@ const StockForm = ({ formType }) => { } }; - const formatDateForDisplay = (dateString) => { if (!dateString) return ''; return moment(dateString).format('DD-MMM-YY'); }; + const sellPriceValidator = useCallback((_, value) => { + if (value <= 0) return Promise.reject('Invalid price'); + return Promise.resolve(); + }, []); + + const handleDecimalInput = (e) => { + let value = e.target.value?.replace(/[^0-9.]/g, ''); + if (value.startsWith('.')) value = '0' + value; + + const parts = value.split('.'); + e.target.value = + parts?.length > 2 ? `${parts[0]}.${parts.slice(1).join('')}` : value; + }; const updateRowValues = (localId, updates) => { setPurchaseData((prev) => @@ -1872,1117 +1530,1042 @@ const StockForm = ({ formType }) => { form.setFieldsValue({ [`${key}${localId}`]: value, }); - } - - const columns = [ - { - title: 'SL.NO', - align: 'center', - key: 'sno', - render: (text, object, index) => ( - {index + 1} - ), - }, - { - title: 'Name', - dataIndex: 'ProdName', - key: 'ProdName', - align: 'left', - render: (text, record, index) => ( - - {record?.ProdName} - - ), - }, - { - title: 'Variant', - dataIndex: 'ProdVariantName', - key: 'ProdVariantName', - align: 'left', - render: (text, record, index) => ( - - {record?.ProdVariantName} - - ), - }, - { - title: 'Uom', - dataIndex: 'UomName', - key: 'UOMName', - }, - { - title: 'Qty', - dataIndex: 'BalanceQty', - key: 'BalanceQty', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - { - if (value?.length > 10) { - return Promise.reject( - 'Quantity cannot exceeds more than 10 chars' - ); - } - return Promise.resolve(); - }, - }, - ]} - > - handleKeyPress(e, record)} - onBlur={(e) => handleQtyChange(e, record)} - onChange={(e) => handleQtyChange(e, record)} - inputMode="decimal" - onInput={(e) => { - 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; - }} - /> - - ) : ( - text - ); - }, - }, - { - title: ( - - Purchase Rate/unit - - ), - dataIndex: 'InwardPrice', - key: 'InwardPrice', - width: 120, - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - { - if (value?.length > 10) { - return Promise.reject( - 'Purchase Rate cannot exceeds more than 10 chars' - ); - } - return Promise.resolve(); - }, - }, - ]} - > - handleKeyPress(e, record)} - onChange={(e) => handlePurrateChange(e, record)} - onBlur={(e) => handlePurrateChange(e, record)} - inputMode="decimal" - onInput={(e) => { - 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; - }} - /> - - ) : ( - text || 0 - ); - }, - }, - { - title: ( - - {' '} - Tax (%){' '} - - ), - dataIndex: 'PurchaseTax', - key: 'PurchaseTax', - // width: 120, - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - { - if (value === undefined || value === '' || value === null) { - return Promise.resolve(); - } - - const stringValue = String(value).trim(); - - if (stringValue === '') { - return Promise.resolve(); - } - - const num = parseFloat(stringValue); - - if (isNaN(num)) { - return Promise.reject('Invalid tax value'); - } - - if (num < 0) { - return Promise.reject('Tax cannot be negative'); - } - - if (num > 99) { - return Promise.reject('Tax cannot exceed 99%'); - } - - if (stringValue.length > 10) { - return Promise.reject('Tax cannot exceed 10 characters'); - } - - // Check for valid decimal format - if (!/^\d+(\.\d{1,2})?$/.test(stringValue)) { - return Promise.reject( - 'Enter valid tax format (max 2 decimal places)' - ); - } - - return Promise.resolve(); - }, - }, - ]} - > - handleKeyPress(e, record)} - onChange={(e) => handleTaxChange(e, record)} - onBlur={(e) => handleTaxChange(e, record)} - inputMode="decimal" - onInput={(e) => { - let value = e.target.value.replace(/[^0-9.]/g, ''); - - if (value.startsWith('.')) value = '0' + value; - - const parts = value.split('.'); - if (parts.length > 2) { - value = `${parts[0]}.${parts.slice(1).join('')}`; - } - - e.target.value = value; - }} - /> - - ) : ( - text || 0 - ); - }, - }, - { - title: 'Amount', - dataIndex: 'Amount', - key: 'Amount', - editable: true, - }, - ...(selectedAdditionalColumn.includes("Mrp") ? [ + }; + const columns = useMemo(() => { + const baseColumns = [ { - title: 'MRP', - dataIndex: 'MRP', - key: 'MRP', - editable: true, - // width: 150, - render: (text, record) => { - const localId = record.localId; - - return isEditing(record) ? ( - - { - const value = e.target.value; - - if (!/^\d*\.?\d*$/.test(value)) { - setMessageType('error'); - setMessageData('Only numeric values are allowed'); - return; - } - - updateRowValues(record.localId, { - MRP: value, - SellPrice: value, - }); - }} - onPressEnter={(e) => handleKeyPress(e, record)} - /> - - - ) : ( - text - ) - } - }] : []), - { - title: ( - - Selling Price - - ), - dataIndex: 'SellPrice', - key: 'SellPrice', - width: 70, - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record)} - onChange={(e) => handleSellPriceChange(e, record)} - onBlur={(e) => handleSellPriceChange(e, record)} - inputMode="decimal" - onInput={(e) => { - 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; - }} - /> - - ) : ( - text || 0 - ); - }, - }, - - ...(selectedAdditionalColumn.includes("Amount Per Piece") ? [ - { - title: "Amount per piece", - dataIndex: 'OnePcsPrice', - key: 'OnePcsPrice', - width: 70, - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record)} - onChange={(e) => { - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, OnePcsPrice: e.target.value } : item - ); - setPurchaseData(newData); - }} - placeholder="OnePcsPrice" - /> - - ) : ( - text - ); - }, - }] : []), - ...(selectedAdditionalColumn.includes("Amount Per Piece") ? [ - { - title: "Number of piece", - dataIndex: 'NoOfPcs', - key: 'NoOfPcs', - width: 70, - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record)} - onChange={(e) => { - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, NoOfPcs: e.target.value } : item - ); - setPurchaseData(newData); - }} - placeholder="NoOfPcs" - /> - - ) : ( - text - ); - }, - }] : []), - ...(selectedAdditionalColumn.includes("Wholesale Price") ? [ - { - title: "Wholesale price", - dataIndex: 'WhSalePrice', - key: 'WhSalePrice', - width: 70, - editable: true, - render: (text, record) => { - return isEditing(record) ? ( - - handleKeyPress(e, record)} - onChange={(e) => { - const value = e.target.value; - - // 🚫 block non-numeric - if (!/^\d*\.?\d*$/.test(value)) return; - - updateRowValue(record.localId, 'WhSalePrice', value); - }} - /> - - ) : ( - text - ); - }, - } - ] : []), - - ...(selectedAdditionalColumn.includes("Manufacture Date") ? [ - { - title: 'Manuf.Date', - dataIndex: 'ManufDate', - key: 'ManufDate', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - { - const formattedDate = dateString === '' ? undefined : moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss'); - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, ManufDate: formattedDate } : item - ); - setPurchaseData(newData); - form.setFieldsValue({ - [`ManufDate${record?.localId}`]: formattedDate - }); - }} - valueData={record?.ManufDate} - cancelFuture={true} - /> - - ) : ( - formatDateForDisplay(text) - ); - }, - }] : []), - ...(selectedAdditionalColumn.includes("Expiry Date") ? [ - { - title: 'Exp.Date', - dataIndex: 'ExpDate', - key: 'ExpDate', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - { - const formattedDate = dateString === '' ? undefined : moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss'); - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, ExpDate: formattedDate } : item - ); - setPurchaseData(newData); - form.setFieldsValue({ - [`ExpDate${record?.localId}`]: formattedDate - }); - }} - valueData={record?.ExpDate} - cancelFuture={false} - /> - - ) : ( - formatDateForDisplay(text) - ); - }, - }] : []), - - ...(selectedAdditionalColumn.includes("Hsn") ? [ - { - title: 'Hsn', - dataIndex: 'Hsn', - key: 'Hsn', - editable: true, - // width: 130, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record)} - onChange={(e) => { - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, PurchaseHSNCode: e.target.value } : item - ); - setPurchaseData(newData); - }} - placeholder="HSN code" - /> - - ) : ( - text - ); - }, - }] : []), - ...(selectedAdditionalColumn.includes("Model No") ? [ - { - title: 'Model', - dataIndex: 'Model', - key: 'Model', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record, index)} - onChange={(e) => { - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, ModelNumber: e.target.value } : item - ); - setPurchaseData(newData); - }} - placeholder="Model No" - /> - - ) : ( - text - ); - }, - }] : []), - ...(selectedAdditionalColumn.includes("Batch No") ? [ - { - title: 'Batch', - dataIndex: 'Batch', - key: 'Batch', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record, index)} - onChange={(e) => { - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { ...item, BatchRef: e.target.value } : item - ); - setPurchaseData(newData); - }} - placeholder="Batch No" - /> - - ) : ( - text - ); - }, - }] : []), - - ...(selectedAdditionalColumn.includes("Rejected Qty") ? - [ - { - title: 'Rejected Qty', - dataIndex: 'RejectedQty', - key: 'RejectedQty', - editable: true, - render: (text, record, index) => { - return isEditing(record, index) ? ( - - handleKeyPress(e, record, index)} - onChange={(e) => { - const inputValue = e.target.value; - const rejectedQty = parseFloat(inputValue) || 0; - const receivedQty = parseFloat(record.ReceivedQty) || 0; - - if (inputValue !== '' && rejectedQty >= receivedQty) { - setMessageType('error'); - setMessageData('Rejected Qty cannot be greater than or Equal to Received Qty'); - form.setFieldsValue({ - [`RejectedQty${record?.localId}`]: record.RejectedQty || 0 - }); - return; - } - - const acceptedQty = receivedQty - rejectedQty; - const totalAmount = acceptedQty * (parseFloat(record.InwardPrice) || 0); - - const newData = PurchaseData.map((item) => - item.localId === record?.localId ? { - ...item, - RejectedQty: parseFloat(inputValue) || 0, - AcceptedQty: acceptedQty, - Amount: totalAmount - } : item - ); - setPurchaseData(newData); - }} - placeholder="Rejected Qty" - /> - - ) : ( - text - ); - }, - }] : []), - - - - - ...(selectedAdditionalColumn.includes("Free Qty") ? [ - { - title: 'Free Qty', - dataIndex: 'Freeqty', - key: 'Freeqty', - editable: true, - render: (text, record) => { - return isEditing(record) ? ( - - handleKeyPress(e, record)} - onChange={(e) => { - const value = e.target.value; - - // 🚫 block non-numeric - if (!/^\d*$/.test(value)) return; - - updateRowValue(record.localId, 'Freeqty', value); - }} - /> - - ) : ( - text - ); - }, - }, - ] : []), - - ...(selectedAdditionalColumn.includes("IMEI") ? [ - { - title: 'IMEI', - dataIndex: 'AdditionalInfo', - key: 'AdditionalInfo', - width: 120, + title: 'SL.NO', align: 'center', + key: 'sno', + width: 50, + render: (text, object, index) => ( + {index + 1} + ), + }, + { + title: 'Name', + dataIndex: 'ProdName', + key: 'ProdName', + align: 'left', + width: 150, + render: (text, record, index) => ( + {record?.ProdName} + ), + }, + { + title: 'Variant', + dataIndex: 'ProdVariantName', + key: 'ProdVariantName', + align: 'center', + width: 100, + render: (text, record, index) => ( + {record?.ProdVariantName} + ), + }, + { + title: 'Uom', + dataIndex: 'UomName', + key: 'UOMName', + align: 'center', + width: 100, + }, + { + title: 'Qty', + dataIndex: 'BalanceQty', + key: 'BalanceQty', + align: 'center', + editable: true, + width: 100, render: (text, record, index) => { - const hasQty = record?.ReceivedQty && parseFloat(record.ReceivedQty) > 0; return ( - <> - {' '} - { - if (hasQty) { - - setSelectedRowIndex(index); - handleModelDataOpen(record); - - } else { - setMessageType('error'); - setMessageData('Please Enter Qty'); - } - }} - className="shape-preview" - /> - + handleQtyTyping(e, record)} + onBlur={() => commitQtyChange(record)} + onPressEnter={() => commitQtyChange(record)} + inputMode="decimal" + onInput={(e) => { + let v = e.target.value.replace(/[^0-9.]/g, ''); + if (v.startsWith('.')) v = '0' + v; + const parts = v.split('.'); + e.target.value = + parts.length > 2 + ? `${parts[0]}.${parts.slice(1).join('')}` + : v; + }} + /> ); }, - }] : []), - { - title: 'Action', - dataIndex: 'Action', - key: 'Action', - align: 'center', - render: (_, record, index) => ( - { - e.stopPropagation(); - }} - > - statusFormatters(record)} - /> - - ), - }, - ]; + }, + { + title: 'Pur Rate / unit', + dataIndex: 'InwardPrice', + key: 'InwardPrice', + width: 120, + editable: true, + align: 'center', + render: (_, record) => { + const editable = true; + + return editable ? ( + handlePurrateTyping(e, record)} + /> + ) : ( +
edit(record)} // ✅ THIS is required + style={{ cursor: 'pointer' }} + > + {record.InwardPrice || 0} +
+ ); + }, + }, + + { + title: ( + + Tax (%) + + ), + dataIndex: 'PurchaseTax', + key: 'PurchaseTax', + editable: true, + align: 'center', + width: 100, + render: (_, record) => ( + handleTaxTyping(e, record)} + onBlur={() => debouncedTaxCalc(record.PurchaseTax, record)} + /> + ), + }, + { + title: 'Amount', + dataIndex: 'Amount', + key: 'Amount', + editable: true, + align: 'right', + width: 100, + }, + ...(selectedAdditionalColumn.includes('Mrp') + ? [ + { + title: 'MRP', + dataIndex: 'MRP', + key: 'MRP', + editable: true, + width: 100, + align: 'center', + render: (_, record) => { + return ( + edit(record)} + placeholder="MRP" + value={record?.MRP ?? ''} + maxLength={10} + inputMode="decimal" + onChange={(e) => handleMRPChange(e, record)} + onBlur={(e) => handleMRPBlur(e, record)} + onPressEnter={(e) => handleKeyPress(e, record)} + /> + ); + }, + }, + ] + : []), + { + title: ( + + Selling Price + + ), + dataIndex: 'SellPrice', + key: 'SellPrice', + width: 100, + editable: true, + align: 'center', + render: (_, record) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + value={record?.SellPrice ?? ''} + maxLength={10} + inputMode="decimal" + onChange={(e) => handleSellPriceChange(e, record)} + onBlur={(e) => handleSellPriceBlur(e, record)} + onPressEnter={(e) => handleKeyPress(e, record)} + onInput={handleDecimalInput} + /> + ); + }, + }, + + ...(selectedAdditionalColumn.includes('Amount Per Piece') + ? [ + { + title: 'Amount per piece', + dataIndex: 'OnePcsPrice', + key: 'OnePcsPrice', + width: 70, + editable: true, + render: (_, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + disabled={record?.OnePcsAvailable === 'N'} + placeholder="OnePcsPrice" + value={record?.OnePcsPrice ?? ''} + maxLength={10} + inputMode="decimal" + onChange={(e) => handleOnePcsChange(e, record)} + onBlur={(e) => handleOnePcsBlur(e, record)} + onPressEnter={() => handleKeyPress(e, record)} + onInput={(e) => { + let v = e.target.value.replace(/[^0-9.]/g, ''); + if (v.startsWith('.')) v = '0' + v; + const parts = v.split('.'); + e.target.value = + parts.length > 2 + ? `${parts[0]}.${parts.slice(1).join('')}` + : v; + }} + /> + ); + }, + }, + ] + : []), + ...(selectedAdditionalColumn.includes('Amount Per Piece') + ? [ + { + title: 'Number of piece', + dataIndex: 'NoOfPcs', + key: 'NoOfPcs', + width: 70, + editable: true, + render: (_, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + disabled={record?.OnePcsAvailable === 'N'} + placeholder="NoOfPcs" + value={record.NoOfPcs ?? ''} + maxLength={5} + inputMode="numeric" + onChange={(e) => handleNoOfPcsChange(e, record)} + onBlur={(e) => handleNoOfPcsBlur(e, record)} + onPressEnter={() => handleKeyPress(e, record)} + onInput={(e) => { + // remove invalid characters & leading zeros + let val = e.target.value.replace(/[^0-9]/g, ''); + val = val.replace(/^0+(?=\d)/, ''); // removes leading zeros but keeps single 0 + e.target.value = val; + }} + /> + ); + }, + }, + ] + : []), + ...(selectedAdditionalColumn.includes('Wholesale Price') + ? [ + { + title: 'Wholesale price', + dataIndex: 'WhSalePrice', + key: 'WhSalePrice', + width: 70, + editable: true, + render: (_, record) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + placeholder="WhSalePrice" + value={record.WhSalePrice ?? ''} + inputMode="decimal" + maxLength={10} + onChange={(e) => handleWhSalePriceChange(e, record)} + onBlur={(e) => handleWhSalePriceBlur(e, record)} + onPressEnter={() => handleKeyPress(record)} + onInput={(e) => { + let val = e.target.value.replace(/[^0-9.]/g, ''); // remove invalid chars + if (val.startsWith('.')) val = '0' + val; // leading dot fix + const parts = val.split('.'); + if (parts.length > 2) + val = `${parts[0]}.${parts.slice(1).join('')}`; // max one dot + val = val.replace(/^0+(?=\d)/, ''); // remove leading zeros + e.target.value = val; + }} + /> + ); + }, + }, + ] + : []), + + ...(selectedAdditionalColumn.includes('Manufacture Date') + ? [ + { + title: 'Manuf.Date', + dataIndex: 'ManufDate', + key: 'ManufDate', + editable: true, + render: (text, record, index) => { + return ( + { + // Format date to your preferred format + const formattedDate = dateString + ? moment(dateString, ['DD-MM-YYYY']).format( + 'YYYY-MM-DDTHH:mm:ss' + ) + : undefined; + + // Update the row data immutably + const newData = PurchaseData.map((item) => + item.localId === record.localId + ? { ...item, ManufDate: formattedDate } + : item + ); + setPurchaseData(newData); + }} + /> + ); + }, + }, + ] + : []), + ...(selectedAdditionalColumn.includes('Expiry Date') + ? [ + { + title: 'Exp.Date', + dataIndex: 'ExpDate', + key: 'ExpDate', + editable: true, + render: (text, record, index) => { + return ( + + handleExpDateChange(dateString, record) + } + /> + ); + }, + }, + ] + : []), + + ...(selectedAdditionalColumn.includes('Hsn') + ? [ + { + title: 'Hsn', + dataIndex: 'Hsn', + key: 'Hsn', + editable: true, + // width: 130, + render: (text, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + onPressEnter={() => handleKeyPress(record)} + onChange={(e) => { + const value = e.target.value; + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, PurchaseHSNCode: value } + : item + ) + ); + }} + /> + ); + }, + }, + ] + : []), + ...(selectedAdditionalColumn.includes('Model No') + ? [ + { + title: 'Model', + dataIndex: 'Model', + key: 'Model', + editable: true, + render: (text, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + onPressEnter={() => handleKeyPress(record)} + onChange={(e) => { + const value = e.target.value; + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, ModelNumber: value } + : item + ) + ); + }} + /> + ); + }, + }, + ] + : []), + ...(selectedAdditionalColumn.includes('Batch No') + ? [ + { + title: 'Batch', + dataIndex: 'Batch', + key: 'Batch', + editable: true, + render: (text, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + onPressEnter={() => handleKeyPress(record, index)} + onChange={(e) => { + const value = e.target.value; + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, BatchRef: value } + : item + ) + ); + }} + /> + ); + }, + }, + ] + : []), + + ...(selectedAdditionalColumn.includes('Rejected Qty') + ? [ + { + title: 'Rejected Qty', + dataIndex: 'RejectedQty', + key: 'RejectedQty', + editable: true, + render: (text, record, index) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + onPressEnter={() => handleKeyPress(record, index)} + onChange={(e) => { + let inputValue = e.target.value.replace(/[^0-9.]/g, ''); // allow only numbers + if (inputValue.startsWith('0') && inputValue.length > 1) { + inputValue = inputValue.replace(/^0+/, ''); // remove leading zeros + } + + const rejectedQty = parseFloat(inputValue) || 0; + const receivedQty = parseFloat(record.ReceivedQty) || 0; + + // validation + if (rejectedQty >= receivedQty) { + setMessageType('error'); + setMessageData( + 'Rejected Qty cannot be greater than or equal to Received Qty' + ); + return; + } + + const acceptedQty = receivedQty - rejectedQty; + const price = parseFloat(record.InwardPrice) || 0; + const amount = acceptedQty * price; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { + ...item, + RejectedQty: rejectedQty, + AcceptedQty: acceptedQty, + Amount: amount, + } + : item + ) + ); + }} + /> + ); + }, + }, + ] + : []), + + ...(selectedAdditionalColumn.includes('Free Qty') + ? [ + { + title: 'Free Qty', + dataIndex: 'Freeqty', + key: 'Freeqty', + editable: true, + render: (text, record) => { + return ( + edit(record)} + onFocus={(e) => e.stopPropagation()} + onPressEnter={() => handleKeyPress(record)} + onChange={(e) => { + let value = e.target.value.replace(/[^0-9]/g, ''); // only digits + if (value.startsWith('0') && value.length > 1) { + value = value.replace(/^0+/, ''); // remove leading zeros + } + + updateRowValue(record.localId, 'Freeqty', value); + }} + /> + ); + }, + }, + ] + : []), + + ...(selectedAdditionalColumn.includes('IMEI') + ? [ + { + title: 'IMEI', + dataIndex: 'AdditionalInfo', + key: 'AdditionalInfo', + width: 120, + align: 'center', + render: (text, record, index) => { + const receivedQty = parseFloat(record?.ReceivedQty) || 0; + const isClickable = receivedQty > 0; + + return ( + { + if (!isClickable) { + setMessageType('error'); + setMessageData('Please Enter Qty'); + return; + } + setSelectedRowIndex(index); + handleModelDataOpen(record); + }} + className="shape-preview" + /> + ); + }, + }, + ] + : []), + { + title: 'Action', + dataIndex: 'Action', + key: 'Action', + align: 'center', + width: 80, + render: (_, record, index) => ( + { + e.stopPropagation(); + }} + > + statusFormatters(record)} + /> + + ), + }, + ]; + return baseColumns; + }, [editingKey, editingQty, selectedAdditionalColumn]); const statusFormatters = (record) => { const localId = record?.localId; - // Remove row using localId (not index) - const data = PurchaseData.filter( - (item) => item?.localId !== localId + setPurchaseData((prev) => prev.filter((item) => item.localId !== localId)); + + const formValues = form.getFieldsValue(); + const keysToRemove = Object.keys(formValues).filter((key) => + key.endsWith(localId) ); + if (keysToRemove.length) { + const newValues = { ...formValues }; + keysToRemove.forEach((key) => { + newValues[key] = undefined; + }); + form.setFieldsValue(newValues); + } - setDelete(true); - - // Clear form fields for this row - - form.setFieldsValue({ - [`BalanceQty${localId}`]: undefined, - [`ReceivedQty${localId}`]: undefined, - [`AcceptedQty${localId}`]: undefined, - [`RejectedQty${localId}`]: undefined, - [`Freeqty${localId}`]: undefined, - [`MRP${localId}`]: undefined, - [`ManufDate${localId}`]: undefined, - [`ExpDate${localId}`]: undefined, - [`SellPrice${localId}`]: undefined, - [`WhSalePrice${localId}`]: undefined, - [`PurcDiscType${localId}`]: undefined, - [`Amount${localId}`]: undefined, - [`InwardPrice${localId}`]: undefined, - [`PurcDisc${localId}`]: undefined, - [`offerSalePrice${localId}`]: undefined, - [`splSalePrice${localId}`]: undefined, - [`OnePcsPrice${localId}`]: undefined, - [`NoOfPcs${localId}`]: undefined, - }); - setVariants(undefined); - setPurchaseData(data); - setSelectedProductData(null); - + // 3️⃣ Clear other single fields formRef?.current?.setFieldsValue({ ProdId: null, }); + + setDelete(true); // only if absolutely necessary }; + const handleQtyTyping = (e, record) => { + let value = e.target.value; + // allow only numbers + decimal + if (!/^\d*\.?\d*$/.test(value)) return; - - const handleQtyChange = (e, record) => { - const { localId } = record; - - const sourceData = PurchaseData; - - const findIndex = sourceData.findIndex( - (item) => item?.localId === localId - ); - - if (findIndex === -1) return; - - const inputValue = e.target.value; - - // ✅ Numeric validation - if (!/^\d*\.?\d*$/.test(inputValue)) { - setMessageType('error'); - setMessageData('Only numeric values are allowed'); - return; + // 🔥 remove leading zero (but keep "0." valid) + if (value.length > 1 && value.startsWith('0') && !value.startsWith('0.')) { + value = value.replace(/^0+/, ''); } - const qty = Number(inputValue) || 0; - const acceptedQty = qty; + setEditingQty((prev) => ({ + ...prev, + [record.localId]: value, + })); + }; - const newData = [...PurchaseData]; + const commitQtyChange = (record) => { + const { localId } = record; + const qty = Number(editingQty[localId]) || 0; - const item = newData[findIndex]; + setPurchaseData((prev) => + prev.map((item) => + item.localId === localId + ? { + ...item, + BalanceQty: qty, + ReceivedQty: qty, + AcceptedQty: qty, + RejectedQty: 0, + PurcDisc: 0, + Amount: + isNaN(item.InwardPrice) || isNaN(qty) + ? 0 + : item.InwardPrice * qty, + ProductIdentifierDtls: [], + } + : item + ) + ); - newData[findIndex] = { - ...item, - Amount: - isNaN(Number(item?.InwardPrice)) || isNaN(acceptedQty) - ? 0 - : Number(item?.InwardPrice) * acceptedQty, - PurcDisc: 0, - BalanceQty: qty, - ReceivedQty: qty, - AcceptedQty: acceptedQty, - RejectedQty: 0, - ProductIdentifierDtls: [], - }; - - setPurchaseData(newData); - - // ✅ Sync form values form.setFieldsValue({ - [`PurcDisc${localId}`]: 0, [`BalanceQty${localId}`]: qty, [`ReceivedQty${localId}`]: qty, - [`AcceptedQty${localId}`]: acceptedQty, + [`AcceptedQty${localId}`]: qty, [`RejectedQty${localId}`]: 0, - }); - }; - - - - const handlePurrateChange = (e, record) => { - const { localId, PurcDisc, PurcDiscType } = record; - const PurcRate = e.target.value; - - // ✅ Numeric validation - if (!/^\d*\.?\d*$/.test(PurcRate)) { - setMessageType('error'); - setMessageData('Only numeric values are allowed'); - return; - } - - const acceptedQty = Number(record?.AcceptedQty) || 0; - const rate = Number(PurcRate) || 0; - const amount = rate * acceptedQty; - - // 🔍 Find correct index using localId - const findIndex = PurchaseData.findIndex( - (item) => item?.localId === localId - ); - - if (findIndex === -1) return; - - const item = PurchaseData[findIndex]; - - // 🧮 Discount calculation - let discountAmt = 0; - if (PurcDiscType === 'P') { - discountAmt = (amount * Number(PurcDisc || 0)) / 100; - } else { - discountAmt = Number(PurcDisc || 0); - } - - // 🧮 Tax calculation - const taxPercent = Number(item?.TaxPercentage || 0); - const taxAmt = - taxPercent > 0 - ? ((amount - discountAmt) * taxPercent) / (100 + taxPercent) - : 0; - - // ✅ Update data immutably - const newData = [...PurchaseData]; - - newData[findIndex] = { - ...item, - PurcDisc: 0, - InwardPrice: Delete ? 0 : rate, - Amount: !isNaN(amount) ? amount : 0, - TaxAmt: taxAmt.toFixed(2), - }; - - setPurchaseData(newData); - - // 🔄 Update payment amount - const totalAmount = newData.reduce( - (acc, data) => acc + Number(data?.Amount || 0), - 0 - ); - - setPaymentAmount(totalAmount); - - formRef?.current?.setFieldsValue({ - PaymentAmount: totalAmount, - }); - - // 🔄 Sync row form fields - form.setFieldsValue({ [`PurcDisc${localId}`]: 0, - [`InwardPrice${localId}`]: Delete ? 0 : rate, - [`Amount${localId}`]: !isNaN(amount) ? amount : 0, }); }; + useEffect(() => { + const id = setTimeout(() => { + const total = PurchaseData.reduce( + (acc, d) => acc + Number(d.Amount || 0), + 0 + ); + + setPaymentAmount(total); + formRef?.current?.setFieldsValue({ PaymentAmount: total }); + }, 150); + + return () => clearTimeout(id); + }, [PurchaseData]); + + const handleMRPChange = (e, record) => { + const value = e.target.value ?? ''; + + if (!/^\d*\.?\d*$/.test(value)) return; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { + ...item, + MRP: value, + SellPrice: value, + } + : item + ) + ); + }; + + const handleMRPBlur = (e, record) => { + const value = e.target.value ?? ''; + const normalized = value === '' ? '' : String(Number(value)); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { + ...item, + MRP: normalized, + SellPrice: normalized, + } + : item + ) + ); + }; + + const handlePurrateChange = useCallback((e, record) => { + let value = e?.target?.value ?? ''; + + // allow decimals only + if (!/^\d*\.?\d*$/.test(value)) return; + + // 🔥 remove leading zero when user starts typing + if (value.length > 1 && value.startsWith('0') && !value.startsWith('0.')) { + value = value.replace(/^0+/, ''); + } + + setPurchaseData((prev) => + prev.map((item) => { + if (item.localId !== record.localId) return item; + + const qty = Number(item.AcceptedQty) || 0; + const rateNum = Number(value || 0); + const amount = rateNum * qty; + + let discountAmt = 0; + if (item.PurcDiscType === 'P') { + discountAmt = (amount * Number(item.PurcDisc || 0)) / 100; + } else { + discountAmt = Number(item.PurcDisc || 0); + } + + const taxPercent = Number(item.TaxPercentage || 0); + const taxAmt = + taxPercent > 0 + ? ((amount - discountAmt) * taxPercent) / (100 + taxPercent) + : 0; + + return { + ...item, + InwardPrice: value, // 👈 clean value + Amount: amount, + TaxAmt: +taxAmt.toFixed(2), + }; + }) + ); + }, []); + const handlePurrateTyping = (e, record) => { + let value = e?.target?.value ?? ''; + + if (!/^\d*\.?\d*$/.test(value)) return; + + if (value.length > 1 && value.startsWith('0') && !value.startsWith('0.')) { + value = value.replace(/^0+/, ''); + } + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId ? { ...item, InwardPrice: value } : item + ) + ); + + debouncedCalc(value, record); + }; + + const calculateRate = useCallback((value, record) => { + setPurchaseData((prev) => + prev.map((item) => { + if (item.localId !== record.localId) return item; + + const qty = Number(item.AcceptedQty) || 0; + const rateNum = Number(value || 0); + const amount = rateNum * qty; + + let discountAmt = 0; + if (item.PurcDiscType === 'P') { + discountAmt = (amount * Number(item.PurcDisc || 0)) / 100; + } else { + discountAmt = Number(item.PurcDisc || 0); + } + + const taxPercent = Number(item.TaxPercentage || 0); + const taxAmt = + taxPercent > 0 + ? ((amount - discountAmt) * taxPercent) / (100 + taxPercent) + : 0; + + return { + ...item, + Amount: amount, + TaxAmt: +taxAmt.toFixed(2), + }; + }) + ); + }, []); + + const debouncedCalc = useDebounce(calculateRate, 300); const handleSellPriceChange = (e, record) => { - const { localId } = record; - const value = e?.target?.value; + const value = e?.target?.value ?? ''; - // ✅ Numeric validation - if (!/^\d*\.?\d*$/.test(value)) { - setMessageType('error'); - setMessageData('Only numeric values are allowed'); - return; - } + // allow smooth typing + if (!/^\d*\.?\d*$/.test(value)) return; - // 🔍 Find correct row using localId - const findIndex = PurchaseData.findIndex( - (item) => item?.localId === localId + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId ? { ...item, SellPrice: value } : item + ) ); - - if (findIndex === -1) return; - - // ✅ Immutable update - const newData = [...PurchaseData]; - - newData[findIndex] = { - ...newData[findIndex], - SellPrice: value, - }; - - setPurchaseData(newData); - - // 🔄 Sync form field - form.setFieldsValue({ - [`SellPrice${localId}`]: value, - }); }; - const handleTaxChange = (e, record) => { - const { localId } = record; - const value = e?.target?.value; + const handleSellPriceBlur = (e, record) => { + const value = e?.target?.value ?? ''; + const normalized = value === '' ? '' : String(Number(value)); - // ✅ Numeric validation - if (!/^\d*\.?\d*$/.test(value)) { - setMessageType('error'); - setMessageData('Only numeric values are allowed'); - return; - } - - const taxValue = Number(value) || 0; - - // 🔍 Find correct row - const findIndex = PurchaseData.findIndex( - (item) => item?.localId === localId + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, SellPrice: normalized } + : item + ) ); - - if (findIndex === -1) return; - - // ✅ Immutable update - const newData = [...PurchaseData]; - - newData[findIndex] = { - ...newData[findIndex], - PurchaseTax: taxValue, - }; - - setPurchaseData(newData); - - // 🔄 Sync form value - form.setFieldsValue({ - [`PurchaseTax${localId}`]: taxValue, - }); }; + const handleOnePcsChange = (e, record) => { + const value = e?.target?.value ?? ''; + if (!/^\d*\.?\d*$/.test(value)) return; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId ? { ...item, OnePcsPrice: value } : item + ) + ); + }; + + const handleOnePcsBlur = (e, record) => { + const value = e?.target?.value ?? ''; + const normalized = value === '' ? '' : String(Number(value)); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, OnePcsPrice: normalized } + : item + ) + ); + }; + + const handleNoOfPcsChange = (e, record) => { + const value = e?.target?.value ?? ''; + + // only whole numbers + if (!/^\d*$/.test(value)) return; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId ? { ...item, NoOfPcs: value } : item + ) + ); + }; + + const handleNoOfPcsBlur = (e, record) => { + const value = e?.target?.value ?? ''; + const normalized = value === '' ? '' : String(parseInt(value, 10)); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, NoOfPcs: normalized } + : item + ) + ); + }; + + const handleWhSalePriceChange = (e, record) => { + const value = e?.target?.value ?? ''; + + if (!/^\d*\.?\d*$/.test(value)) return; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId ? { ...item, WhSalePrice: value } : item + ) + ); + }; + + const handleWhSalePriceBlur = (e, record) => { + const value = e?.target?.value ?? ''; + const normalized = value === '' ? '' : String(Number(value)); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, WhSalePrice: normalized } + : item + ) + ); + }; + + const handleManufDateChange = (dateString, record) => { + const formattedDate = + !dateString || dateString === '' + ? undefined + : moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss'); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, ManufDate: formattedDate } + : item + ) + ); + }; + + const handleExpDateChange = (dateString, record) => { + const formattedDate = + !dateString || dateString === '' + ? undefined + : moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss'); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, ExpDate: formattedDate } + : item + ) + ); + }; + + const handleHSNChange = (value, record) => { + // optional: digits only (HSN is numeric) + const cleanValue = value.replace(/\D/g, ''); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, PurchaseHSNCode: cleanValue } + : item + ) + ); + }; + + const handleTaxTyping = (e, record) => { + let value = e?.target?.value ?? ''; + + // allow decimal typing only + if (!/^\d*\.?\d*$/.test(value)) return; + + // fix ".5" → "0.5" + if (value.startsWith('.')) value = '0' + value; + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, PurchaseTax: value } // keep STRING + : item + ) + ); + + debouncedTaxCalc(value, record); + }; + + const calculateTax = useCallback((value, record) => { + setPurchaseData((prev) => + prev.map((item) => { + if (item.localId !== record.localId) return item; + + const amount = Number(item.Amount) || 0; + const taxPercent = Number(value || 0); + + const taxAmt = + taxPercent > 0 ? (amount * taxPercent) / (100 + taxPercent) : 0; + + return { + ...item, + TaxPercentage: taxPercent, + TaxAmt: +taxAmt.toFixed(2), + }; + }) + ); + }, []); + const debouncedTaxCalc = useDebounce(calculateTax, 300); + + // const handleTaxChange = (e, record) => { + // const { localId } = record; + // const value = e?.target?.value ?? ''; + + // // ✅ allow natural typing + // if (!/^\d*\.?\d*$/.test(value)) return; + + // setPurchaseData((prev) => + // prev.map((item) => + // item.localId === localId + // ? { + // ...item, + // PurchaseTax: value, // 👈 KEEP STRING + // } + // : item + // ) + // ); + + // // 👇 keep form in sync (string only) + // form.setFieldsValue({ + // [`PurchaseTax${localId}`]: value, + // }); + // }; + + const handleTaxBlur = (e, record) => { + const value = e?.target?.value ?? ''; + const normalized = value === '' ? '' : String(Number(value)); + + setPurchaseData((prev) => + prev.map((item) => + item.localId === record.localId + ? { ...item, PurchaseTax: normalized } + : item + ) + ); + + form.setFieldsValue({ + [`PurchaseTax${record.localId}`]: normalized, + }); + }; const purchaseStatusChange = (value) => { setPurchaseStatus(value); }; - const handleQuickAddCancel = () => { - setAddProductDetail(false); - formProductRef.current?.resetFields(); - setOpenAdd(false); - setSelectedProdCat(null); - setSelectedProdSubCat(null); - setSelectedBrand(null); - }; - - const handleUomDropDownChange = async (ConfigId) => { - formProductRef.current?.setFieldsValue({ UOM: ConfigId }); - setSelectedUom(ConfigId); - }; - - const handleBrandDropDownChange = async (ConfigId) => { - formProductRef.current?.setFieldsValue({ Brand: ConfigId }); - setSelectedBrand(ConfigId); - }; - - const handleProdCatDropDownChange = async (ConfigId) => { - dispatch(getProdSubCatData({ ConfigId: ConfigId })); - formProductRef.current?.setFieldsValue({ - ProdCat: ConfigId, - ProdSubCat: null, - }); - setSelectedProdCat(ConfigId); - setSelectedProdSubCat(null); - }; - - const handleProdSubCatDropDownChange = async (ConfigId) => { - dispatch(getBrandData({ ConfigId: ConfigId })); - formProductRef.current?.setFieldsValue({ - ProdSubCat: ConfigId, - Brand: null, - }); - setSelectedProdSubCat(ConfigId); - setSelectedBrand(null); - }; - const openToken = (value) => { - setTokenOpen(value); - }; - - const openQrcodeAuto = (value) => { - setQrcodeAuto(value); - }; - - const openQrcodeAutoSingle = (value) => { - setQrcodeAutoSingle(value); - }; - - const openAmountPerPieceAvailable = (value) => { - setAmountPerPieceAvailable(value); - }; - - const addCategory = () => { - setOpenCategoryModel(true); - }; - - const addSubCategory = () => { - setOpenSubCategoryModel(true); - }; - - const addBrand = () => { - setOpenBrandModel(true); - }; - - const addTax = () => { - setOpenTaxModel(true); - }; - - const handleCatDropDownChange = (value) => { - setSelectedCategory(value); - formSubCategoryRef?.current?.setFieldsValue({ CategoryId: value }); - }; - - const handleSubCatDropDownChange = (value) => { - setSelectedSubCategory(value); - formBrandRef?.current?.setFieldsValue({ SubCategoryId: value }); - }; - - const handleTaxNameDropDownChange = async (ConfigId) => { - formTaxRef.current?.setFieldsValue({ TaxName: ConfigId }); - setSelectedTaxNameId(ConfigId); - }; - - const updateCategoryImageUrl = (url) => { - setCategoryImageUrl(url); - }; - - const updateSubCategoryImageUrl = (url) => { - setSubCategoryImageUrl(url); - }; - - const updateBrandImageUrl = (url) => { - setBrandImageUrl(url); - }; - - const openAdditionalDetails = () => { - setOpenAdd(OpenAdd ? false : true); - }; - - const openStock = (value) => { - setStockOpen(value); - }; - const SupplierOpenfun = (value) => { setSupplierOpen(value); }; @@ -3000,29 +2583,26 @@ const StockForm = ({ formType }) => { }, []); }; - - const onFinish = async ({ PaymentType, PaymentAmount = 0, ...values }) => { try { // =============================== // 1️⃣ TAX VALIDATION // =============================== const invalidTaxItems = PurchaseData?.filter((item) => { - const tax = item.PurchaseTax; + const tax = item?.PurchaseTax; if (tax === undefined || tax === '' || tax === null) return false; const num = Number(tax); return isNaN(num) || num < 0 || num > 99; }); - if (invalidTaxItems.length > 0) { + if (invalidTaxItems?.length > 0) { setMessageType('error'); - setMessageData('Please enter valid tax percentage (0–99%) for all items'); + setMessageData( + 'Please enter valid tax percentage (0–99%) for all items' + ); return; } - // =============================== - // 2️⃣ SELL PRICE > MRP CHECK - // =============================== if ( PurchaseData?.some( (item) => @@ -3036,18 +2616,12 @@ const StockForm = ({ formType }) => { return; } - // =============================== - // 3️⃣ NO PRODUCT CHECK - // =============================== - if (!PurchaseData || PurchaseData.length === 0) { + if (!PurchaseData || PurchaseData?.length === 0) { setMessageType('error'); setMessageData('No Product Selected'); return; } - // =============================== - // 4️⃣ FILTER VALID / INVALID ROWS - // =============================== const validRows = []; const invalidRowNumbers = []; @@ -3062,7 +2636,7 @@ const StockForm = ({ formType }) => { } }); - if (validRows.length === 0) { + if (validRows?.length === 0) { setMessageType('error'); setMessageData('Please enter Qty and Amount for at least one product'); return; @@ -3214,81 +2788,11 @@ const StockForm = ({ formType }) => { } }; - - const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); - const onProductFinish = async (values) => { - setExpandCollapseActive('1'); - let postData = values; - postData['CompId'] = CompId; - postData['BranchId'] = BranchId; - postData['AppId'] = AppId; - postData['SuppId'] = SupplierData?.filter( - (item) => item.SuppName?.toLowerCase() === 'Self'?.toLowerCase() - )?.[0]?.['SuppId']; - postData['ProdType'] = ProductTypeData?.filter( - (item) => item.ConfigName === 'Product' - )?.[0]?.['ConfigId']; - postData['InvoiceDate'] = new Date().toJSON(); - postData['StockAvailable'] = StockOpen; - postData['TokenAvailable'] = TokenOpen; - postData['OnePcsAvailable'] = AmountPerPieceAvailable; - postData['AutoGenerateQr'] = - values?.QRCode == undefined || values?.QRCode == null ? QrcodeAuto : 'N'; - postData['AutoGenerateSingleQr'] = - values?.OnePcQR == undefined || values?.OnePcQR == null - ? QrcodeAutoSingle - : 'N'; - postData['CreatedBy'] = UserId; - - if (SelectedTaxId) { - postData['Cess'] = - values?.Cess == undefined || values?.Cess == null || values?.Cess == '' - ? 0 - : values?.Cess; - } - - let response = {}; - - if (formType === 'add') { - try { - response = await dispatch(postProductData(postData)).unwrap(); - } catch (err) { - if (err['message'] == 'Request failed with status code 422') { - response = { - data: { - statusCode: 0, - response: 'Please Give Required Fields', - data: [], - }, - }; - } - } - } - if (response?.data?.statusCode == 1) { - setOpenAdd(false); - setExpandCollapseActive('1'); - setMessageType('success'); - setMessageData(response?.data?.response); - let postData1 = {}; - postData1['CompId'] = CompId; - postData1['BranchId'] = BranchId; - postData1['AppId'] = AppId; - - let product = await dispatch(getProductData(postData1))?.unwrap(); - if (product.data?.statusCode == 1) { - handleQuickAddCancel(); - } - } else { - setMessageType('error'); - setMessageData(response?.data?.response); - } - }; - const defaultColumns = [ { title: 'IMEI 1', @@ -3362,7 +2866,7 @@ const StockForm = ({ formType }) => { const handleInvoiceSelect = async (value) => { if (value === selectedInvoice) return; - const invoiceParts = value.split('-'); + const invoiceParts = value?.split('-'); const shortInvoice = invoiceParts[invoiceParts.length - 1]; formRef?.current?.setFieldsValue({ SuppInvoiceNo: value }); @@ -3488,15 +2992,14 @@ const StockForm = ({ formType }) => { : null; setOrderType(isNewOrder); setSelectedInvoice(null); - setInvoiceNo(null); setSearchText(null); setSelectedSupplierName(!isNewOrder); setSupplierOpen(isNewOrder ? 'own' : null); setSelectedSupplierData(supplierData); setPurchaseData([]); - setSelectedProductData(null); + // setSelectedProductData(null); setSelectedProductName(null); - setselectedProductVariantData(null); + // setselectedProductVariantData(null); setInvoiceType('I'); setPurchaseStatus('P'); setProductData([]); @@ -3545,13 +3048,6 @@ const StockForm = ({ formType }) => { // command - - - ; - - - - const validateSellPrice = (record) => (_, value) => { if (!value) { return Promise.reject('Selling Price is required'); @@ -3623,7 +3119,6 @@ const StockForm = ({ formType }) => { }; const handleModelDataSumbitOrClose = () => { - setimeiSerialOpen(false); const productIdentifierDtls = dataSource ?.filter( @@ -3637,40 +3132,46 @@ const StockForm = ({ formType }) => { })); const newData = PurchaseData.map((item, index) => - index === selectedRowIndex ? { ...item, ProductIdentifierDtls: productIdentifierDtls } : item + index === selectedRowIndex + ? { ...item, ProductIdentifierDtls: productIdentifierDtls } + : item ); setPurchaseData(newData); }; - const handleFieldSetupSubmit = async () => { - + const handleFieldSetupSubmit = async ({ + selectedFields, + tempSelectedColumns, + closeModal, + resetTemp, + }) => { const postData = { - "AppId": AppId, - "CompId": CompId, - "BranchId": BranchId, - "Type": "PE", - "FormType": "Purchase Entry", - "TypeId": categoryId, - "ConfigDtl": selectedFields?.map((field) => ({ - "ConfigId": field, - "Access": 'Y', + AppId, + CompId, + BranchId, + Type: 'PE', + FormType: 'Purchase Entry', + TypeId: categoryId, + ConfigDtl: selectedFields.map((field) => ({ + ConfigId: field, + Access: 'Y', })), - "CreatedBy": UserId - } + CreatedBy: UserId, + }; const response = await dispatch(postFieldSetup(postData))?.unwrap(); if (response?.data?.statusCode === 1) { setSelectedAdditionalColumn([...tempSelectedColumns]); - setShowColumnModal(false); - setTempSelectedColumns([]) - setMessageType("success"); + closeModal(); + resetTemp(); + setMessageType('success'); setMessageData(response?.data?.response); await getFieldSetup(); } else { - setMessageType("error"); - setMessageData("Failed to set up fields"); + setMessageType('error'); + setMessageData('Failed to set up fields'); } - } + }; const handleModalSubmited = () => { setIsModalOpen(false); }; @@ -3778,7 +3279,7 @@ const StockForm = ({ formType }) => {
)}
-
+
{ }} > - {/*
- -
*/}
{ className="pruchaseCatBTN scan-receipt-btn" onClick={() => setExtractorModalVisible(true)} > -

Scan Receipt (Auto-Fill)

+ {' '} +

Scan Receipt (Auto-Fill)

{ initialValues={editstate} className="formDivAnt" onFinish={onFinish} + style={{ width: '100%' }} >
-
-
- -
- - - -
- -
-
Order Type
- -
-
-
-
-

Supplier Details

+ {/*

Supplier Details

*/}
{!orderType && ( { > + } @@ -3927,22 +3383,24 @@ const StockForm = ({ formType }) => { options={ SupplierData ? SupplierData.filter( - (obj, index, self) => - index === - self.findIndex( - (t) => t.SuppId === obj.SuppId - ) // remove dup SuppId - ).map((option) => ({ - key: `${option.SuppId}-${option.Type}`, // 👈 unique key - value: option.SuppId, - label: - option.Type === 'Branch' - ? `${option.SuppName} (${option.Type}) [${option.SuppId}]` - : `${option.SuppName} (${option.Type})`, - })) + (obj, index, self) => + index === + self.findIndex( + (t) => t.SuppId === obj.SuppId + ) // remove dup SuppId + ).map((option) => ({ + key: `${option.SuppId}-${option.Type}`, // 👈 unique key + value: option.SuppId, + label: + option.Type === 'Branch' + ? `${option.SuppName} (${option.Type}) [${option.SuppId}]` + : `${option.SuppName} (${option.Type})`, + })) : [] } - label={} + label={ + + } className="field-DropDown" onChangeFunction={handleSupplierDropDownChange} valueData={selectedSupplierData} @@ -3973,6 +3431,49 @@ const StockForm = ({ formType }) => { onSelectFuntion={(e) => SupplierOpenfun(e)} /> )} + +
+ + + + + +
+ +
+
+ Order Type +
+ +
+
{(SupplierOpen !== 'own' || selectedSupplierName) && @@ -4024,7 +3525,7 @@ const StockForm = ({ formType }) => { + - } - inputMode="decimal" - disable={!payAmountDisable} - isOnChange={paymentAmount ? true : false} - min={0} - type="number" - value={paymentAmount} - onChange={(e) => { - formRef?.current?.setFieldsValue({ - PaymentAmount: e?.target?.value, - }); - setPaymentAmount(e?.target?.value); - }} - /> - - - )} + }, + ]} + > + + Payment Amount + + } + inputMode="decimal" + disable={!payAmountDisable} + isOnChange={paymentAmount ? true : false} + min={0} + type="number" + value={paymentAmount} + onChange={(e) => { + formRef?.current?.setFieldsValue({ + PaymentAmount: e?.target?.value, + }); + setPaymentAmount(e?.target?.value); + }} + /> + + + )}
@@ -4207,9 +3710,13 @@ const StockForm = ({ formType }) => { className="field-DropDown" value={selectedProductName} filterOption={(input, option) => { - const [prodId, variantName] = option.value.split('_'); + const [prodId, variantName] = + option?.value?.split('_'); const product = productData.find( - (p) => p.ProdId === prodId && (p.ProdVariantName || 'Variant1') === variantName + (p) => + p.ProdId === prodId && + (p.ProdVariantName || 'Variant1') === + variantName ); const nameMatch = option.label ?.toLowerCase() @@ -4222,35 +3729,41 @@ const StockForm = ({ formType }) => { options={ !scanner ? productData?.map((option) => ({ - - value: `${option.ProdId}_${option.ProdVariantName}`, - label: `${option.ProdName} (${option.Size} ${option.UomName})${option?.BrandName ? ` - ${option?.BrandName}` : ''} - ${option.ProdVariantName}`, - - })) + value: `${option.ProdId}_${option.ProdVariantName}`, + label: `${option.ProdName} (${option.Size} ${option.UomName})${option?.BrandName ? ` - ${option?.BrandName}` : ''} - ${option.ProdVariantName}`, + })) : [] } - onSelect={async (value, option) => { - const [prodId, variantName] = value.split('_'); - const product = productData.find(p => p.ProdId === prodId && (p.ProdVariantName) === variantName); - const newProduct = await ProductDropDownChange( - product?.ProdVariantName, - prodId, - option - ); - if (newProduct) { - form?.setFieldsValue({ - [`SellPrice${newProduct?.localId}`]: - newProduct?.SellPrice, - [`PurchaseTax${newProduct?.localId}`]: - newProduct?.PurchaseTax, - }); - setPurchaseData([ - newProduct, - ...PurchaseData, - ]); - } + // onSelect={async (value, option) => { + // const [prodId, variantName] = value?.split('_'); + // const product = productData.find( + // (p) => + // p.ProdId === prodId && + // p.ProdVariantName === variantName + // ); + // const newProduct = await ProductDropDownChange( + // product?.ProdVariantName, + // prodId, + // option + // ); + // if (newProduct) { + // form?.setFieldsValue({ + // [`SellPrice${newProduct?.localId}`]: + // newProduct?.SellPrice, + // [`PurchaseTax${newProduct?.localId}`]: + // newProduct?.PurchaseTax, + // }); + // setPurchaseData([ + // newProduct, + // ...PurchaseData, + // ]); + // } + // }} + + onSelect={(value, option) => { + handleProductSelect(value, option); }} - onChange={handleProductSearch} + onSearch={handleProductSearch} onKeyDown={(e) => { if (scanner && e.key === 'Enter') { e.preventDefault(); @@ -4274,56 +3787,24 @@ const StockForm = ({ formType }) => {
- - setIsModalOpen(true)} size={18} /> + setIsModalOpen(true)} + size={18} + /> - - - - + {isModalOpen && ( @@ -4343,23 +3824,12 @@ const StockForm = ({ formType }) => { /> )} -
- -
{ - setTempSelectedColumns([...selectedAdditionalColumn]); - setShowColumnModal(true); - }}> - - - -
+
+
{ />
- -
-
- {/*
- 0 ? filteredPurchaseData : PurchaseData} - columns={columns} - rowClassName="editable-row" - onRow={(record, index) => ({ - onClick: () => { - edit(record, index); - }, - })} - pagination={false} - /> */} - -
({ - onClick: () => { - edit(record); - }, - })} - pagination={false} - locale={{ - emptyText: isSearching ? 'No matching products found' : 'No data', - }} - /> - +
+ */} +
+
- - - { color="901D77" icon={} /> - -
{ ]} > Supplier Name} + label={} autocomplete="off" /> @@ -4520,7 +3983,7 @@ const StockForm = ({ formType }) => { > Address} + label={} /> { > Zipcode} + label={} maxLength="6" onChange={pinCodeChange} /> @@ -4572,7 +4035,7 @@ const StockForm = ({ formType }) => { autoComplete="off" label="GST No" autocapitalize="on" - // isOnChange={formType == 'edit' ? true : false} + // isOnChange={formType == 'edit' ? true : false} /> @@ -4594,10 +4057,10 @@ const StockForm = ({ formType }) => { // isOnChange={formType == 'edit' ? true : false} inputMode="numeric" onInput={(e) => - (e.target.value = e.target.value.replace( - /[^0-9]/g, - '' - )) + (e.target.value = e.target.value?.replace( + /[^0-9]/g, + '' + )) } /> @@ -4609,7 +4072,7 @@ const StockForm = ({ formType }) => { MailId} autocomplete="off" - // isOnChange={formType == 'edit' ? true : false} + // isOnChange={formType == 'edit' ? true : false} /> @@ -4634,9 +4097,9 @@ const StockForm = ({ formType }) => { ]} > Point of Contact} + label={} autocomplete="off" - // isOnChange={formType == 'edit' ? true : false} + // isOnChange={formType == 'edit' ? true : false} /> @@ -4655,10 +4118,10 @@ const StockForm = ({ formType }) => { ]} > POC Mobile Number} + label={} autocomplete="off" maxLength="10" - // isOnChange={formType == 'edit' ? true : false} + // isOnChange={formType == 'edit' ? true : false} /> @@ -4667,9 +4130,9 @@ const StockForm = ({ formType }) => { rules={[{ validator: validateEmail }]} > POC MailId} + label={} autocomplete="off" - // isOnChange={formType == 'edit' ? true : false} + // isOnChange={formType == 'edit' ? true : false} /> @@ -4814,874 +4277,20 @@ const StockForm = ({ formType }) => { )}
- } - handleSubmit={submitSupplier} - handleCancel={handleSupplier} - >
+ + )}
- -
- { - await validateSafeInput(value); - - if (value && value.length > 50) { - return Promise.reject( - 'Product Name should not exceed 50 characters' - ); - } - - return Promise.resolve(); - }, - }, - ]} - > - Product Name} - // isOnChange={(editstate?.ProdName || QrcodeExistsData?.[0]?.ProdName) ? true : false} - onChange={(e) => setProductName(e?.target?.value)} - /> - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - Quantity} - // isOnChange={(editstate?.Size || QrcodeExistsData?.[0]?.Size) ? true : false} - suffix={ - - - - } - /> - - - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label={} - className="field-DropDown" - // isOnchanges={(editstate?.UOM || SelectedUom)?true:false} - onChangeFunction={handleUomDropDownChange} - valueData={SelectedUom} - disabled={formType == 'edit' ? true : false} - /> - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - MRP} - // isOnChange={(editstate?.MRP || QrcodeExistsData?.[0]?.MRP) ? true : false} - onChange={handleMRP} - /> - - - Sales Price} - // isOnChange={(editstate?.SellPrice || QrcodeExistsData?.[0]?.SellPrice)? true : false} - /> - - - - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label={} - className="field-DropDown" - // isOnchanges={(editstate?.ProdCat || SelectedProdCat)?true:false} - onChangeFunction={handleProdCatDropDownChange} - valueData={SelectedProdCat} - disabled={ - editstate?.ProdTypeName == 'Others' || formType == 'add' - ? false - : true - } - /> - - - - - - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label={} - className="field-DropDown" - // isOnchanges={(editstate?.ProdSubCat || SelectedProdSubCat)?true:false} - onChangeFunction={handleProdSubCatDropDownChange} - valueData={SelectedProdSubCat} - disabled={ - editstate?.ProdTypeName == 'Others' || formType == 'add' - ? false - : true - } - /> - - - - - - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label="Brand" - className="field-DropDown" - // isOnchanges={(editstate?.Brand || SelectedBrand)?true:false} - onChangeFunction={handleBrandDropDownChange} - valueData={SelectedBrand} - // disabled={editstate?.Brand ? true : false} - /> - - - - -
- - -
-
- openStock(e)} - /> -
-
- openToken(e)} - /> -
-
- openQrcodeAuto(e)} - disabled={editstate?.QRCode ? true : false} - /> -
-
- - openAmountPerPieceAvailable(e) - } - // disabled={editstate?.QRCode ? true : false} - /> -
- {(QrcodeAuto == 'N' || editstate?.QRCode) && ( -
- - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - {QrcodeExistsVal && QrcodeExistsVal} - -
- )} - {AmountPerPieceAvailable == 'Y' && ( - <> - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - - -
- - openQrcodeAutoSingle(e) - } - disabled={editstate?.OnePcQR ? true : false} - /> -
- {(QrcodeAutoSingle == 'N' || - editstate?.OnePcQR) && ( -
- - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - {QrcodeSingleExistsVal && - QrcodeSingleExistsVal} - -
- )} - - )} - - {StockOpen == 'Y' && - AmountPerPieceAvailable == 'Y' && ( - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - - )} -
-
-
-
- - {OpenAdd && ( - <> - - ({ - value: option.TaxId, - label: getOptionLabel( - option, - SelectedTaxId === option.TaxId - ), - // label: option.TaxIdName + ' - ' + option.TaxPercentage + ' % ', - }))} - label="Tax" - className="field-DropDown" - isOnchanges={SelectedTaxId ? true : false} - onChangeFunction={handleTaxDropDownChange} - valueData={SelectedTaxId} - /> - - - - - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - WholeSale} - /> - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - splSale} - /> - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - offerSale} - /> - - - )} -
-
- Additional Details -
-
- } - htmlType={true} - /> -
- - } - handleCancel={handleQuickAddCancel} - /> - -
-
-
- { - await validateSafeInput(value); - - if (value && value.length > 50) { - return Promise.reject( - 'Config Name should not exceed 50 characters' - ); - } - - return Promise.resolve(); - }, - }, - ]} - > - Config Name} - autocomplete="off" - /> - -
-
- -
-
-

Upload Icon

-

- -
-
-
- - } - handleSubmit={submitCategory} - handleCancel={handleCategory} - >
- -
-
-
- - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label={} - className="field-DropDown" - onChangeFunction={handleCatDropDownChange} - valueData={SelectedCategory} - /> - - -
-

Upload Icon

-

- -
-
-
- -
-
- { - await validateSafeInput(value); - - if (value && value.length > 50) { - return Promise.reject( - 'Config Name should not exceed 50 characters' - ); - } - - return Promise.resolve(); - }, - }, - ]} - > - Config Name} - autocomplete="off" - /> - -
-
-
- - } - >
- -
-
-
- - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label={} - className="field-DropDown" - onChangeFunction={handleSubCatDropDownChange} - valueData={SelectedSubCategory} - /> - - -
-

Upload Icon

-

- -
-
-
- -
-
- { - await validateSafeInput(value); - - if (value && value.length > 50) { - return Promise.reject( - 'Config Name should not exceed 50 characters' - ); - } - - return Promise.resolve(); - }, - }, - ]} - > - Config Name} - autocomplete="off" - /> - -
-
-
- - } - >
- -
- - ({ - value: option.ConfigId, - label: option.ConfigName, - }))} - label="Tax Name" - className="field-DropDown" - onChangeFunction={handleTaxNameDropDownChange} - valueData={SelectedTaxNameId} - /> - - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - - - { - await validateSafeInput(value); // To block HTML tags & SQL keywords - return Promise.resolve(); - }, - }, - ]} - > - - -
- -
- - - -
- - } - handleSubmit={submitTax} - handleCancel={handleTax} - >
- + {imeiSerialOpen && ( + +
'editable-row'} @@ -5691,54 +4300,8 @@ const StockForm = ({ formType }) => { pagination={{ showSizeChanger: false }} /> - } - handleSubmit={handleModelDataSumbitOrClose} - handleCancel={handleModelDataSumbitOrClose} - > - - { - setShowColumnModal(false); - setSelectedFields([...selectedAdditionalColumn.map(col => - tableFieldPreferences?.find(pref => pref.label === col)?.value - ).filter(Boolean)]); - setTempSelectedColumns([...selectedAdditionalColumn]); - }} - > -
- {tableFieldPreferences?.map((option) => ( -
- -
- ))} -
-
+ + )} { /> -