import { useState, useEffect, useRef, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Form, Tooltip } from 'antd'; import { ArrowRightOutlined, PlusCircleOutlined, InfoCircleOutlined, } from '@ant-design/icons'; import Buttons from '../../../../Components/Forms/Buttons.jsx'; import { InputField } from '../../../../Components/Forms/InputField.jsx'; import { Messages } from '../../../../Components/Notifications/Messages'; import { DropDowns } from '../../../../Components/Forms/DropDown.jsx'; import { DatePic } from '../../../../Components/Forms/DatePicker.jsx'; import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx'; import FormHeader from '../../../PageComponents/FormHeader.jsx'; import { getSession, validateSafeInput } from '../../../../Services/Others'; import { getAdmin, getProductTypeData, getUomData, getProdCatData, getProdSubCatData, getProdTaxData, getSupplierData, productTypeDataSelector, uomDataSelector, prodCatDataSelector, prodSubCatDataSelector, prodTaxDataSelector, taxSelector, supplierSelector, postProductData, postTax, getHsnData } from '../../../../Features/ProductPage/ProductPage.js'; import { ChangeNewQrProduct, GlobalSearchData, changeSearchedData, getSelectedFavItems, GlobalProductCategorie, GlobalProductSubCategorie, getLayoutproductCard, getCardDataWithoutSub, getCardDataWithoutSubmodule, getLayoutCategories, } from '../../../../Features/BookingScreen/BookingData/BookingData'; import { IoCloseSharp, } from 'react-icons/io5'; import '../../../../Styles/Product/Product.scss'; import { getTemplateData } from '../../../../Features/ThemeChange/ThemeChange'; import Imageupload from '../../../../Components/Forms/Upload.jsx'; import { ApplicationPreferences, getCommonAppPreference } from '../../../../Features/BrachLogin/BranchLogin.js'; const ProductForm = ({ formType, handleCancelData, ProductSearch, ProductSearchType, cardData, }) => { const dispatch = useDispatch(); const formRef = useRef(null); const formTaxRef = useRef(null); const ProductTypeData = useSelector(productTypeDataSelector); const UomData = useSelector(uomDataSelector); const ProdCatData = useSelector(prodCatDataSelector); const ProdSubCatData = useSelector(prodSubCatDataSelector); const ProdTaxData = useSelector(prodTaxDataSelector); const TaxData = useSelector(taxSelector); const SupplierData = useSelector(supplierSelector); const ProductSearchValue = useSelector(GlobalSearchData); const templateData = useSelector(getTemplateData); const prodCat = useSelector(GlobalProductCategorie); const ProdSubCat = useSelector(GlobalProductSubCategorie); const appPreferences = useSelector(ApplicationPreferences) const productFieldPreferences = appPreferences?.find( (preference) => preference?.PreferredCatName?.toLowerCase() === "product form fields" )?.PreferenceCatDetails; const UomTypePreference = appPreferences?.find((preference) => preference?.PreferredCatName === 'Product Uom')?.PreferenceCatDetails const UomPreference = UomData?.filter((item) => UomTypePreference?.some?.((e) => e?.PreferredSubCatName?.toLowerCase() == item?.ConfigName?.toLowerCase() && e?.PreferredStatus == "Y")) const filteredFields = productFieldPreferences?.filter( (field) => field?.PreferredStatus === 'Y' ); const cessField = filteredFields?.find((field) => field?.PreferredSubCatName === 'Cess'); const hsnField = filteredFields?.find((field) => field?.PreferredSubCatName === 'HSN'); const taxField = filteredFields?.find((field) => field?.PreferredSubCatName === 'Tax'); //local states const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [SelectedUom, setSelectedUom] = useState(null); const [SelectedTaxId, setSelectedTaxId] = useState(null); const [SelectedTaxNameId, setSelectedTaxNameId] = useState(null); const [OpenTaxModel, setOpenTaxModel] = useState(false); const [OpenAdd, setOpenAdd] = useState(false); const [imageBrandUrl, setBrandImageUrl] = useState(''); const [selectedHsn, setSelectedHsn] = useState(""); const [HsnDetails, setHsnDetails] = useState([]); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserId = getSession('UserId'); useEffect(() => { getApplicationPreference() dispatch(getProductTypeData()); dispatch(getUomData()); dispatch(getProdCatData({ AppId: AppId })); dispatch( getSupplierData({ CompId: CompId, AppId: AppId, BranchId: BranchId }) ); dispatch(getProdTaxData({ AppId: AppId })); dispatch(getAdmin({ CompId: CompId, AppId: AppId })); }, []); useEffect(() => { if (formType == 'add') { let ProductCatId = ProdCatData?.filter( (item) => item.ConfigName?.toLowerCase() === 'General'?.toLowerCase() )?.[0]?.['ConfigId']; dispatch(getProdSubCatData({ ConfigId: ProductCatId })); } }, [ProdCatData]); useEffect(() => { if (formType == 'add' && cardData?.length !== 1) { let UomId = UomPreference?.filter( (item) => item.ConfigName?.toLowerCase() === 'PCS'?.toLowerCase() )?.[0]?.['ConfigId']; formRef.current?.setFieldsValue({ UOM: UomId }); setSelectedUom(UomId); } }, []); useEffect(() => { if (formType == 'add') { let TaxId = TaxData?.filter( (item) => item.TaxIdName?.toLowerCase() === 'NIL'?.toLowerCase() )?.[0]?.['TaxId']; formRef.current?.setFieldsValue({ TaxId: TaxId }); setSelectedTaxId(TaxId); } }, [TaxData]); const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); const openAdditionalDetails = () => { if (OpenAdd) { setOpenAdd(false); } else { setOpenAdd(true); } }; const getApplicationPreference = async () => { const response = await dispatch(getCommonAppPreference(AppId)).unwrap(); } const handleSellPrice = (_, value) => { return new Promise((resolve, reject) => { if (!value) { return reject('Selling Price is required'); } if (!/^\d+(\.\d{1,2})?$/.test(value)) { return reject('Invalid format (Max 2 decimal places allowed)'); } if (parseFloat(value) === 0) { return reject('Selling Price cannot be 0'); } if (value.length > 10) { return reject('MRP cannot exceed 10 digits'); } const MRP = formRef?.current?.getFieldsValue()?.MRP || 0; if (MRP !== undefined && parseFloat(MRP) < parseFloat(value)) { return reject('Please enter Selling Price less than MRP'); } return resolve(); }); }; useEffect(() => { if (cardData?.length === 1) { AutoProdFun(); } }, [cardData]); const getUOMConfigId = async (uomName) => { if (!uomName) return getUOMConfigId('PCS'); const normalize = (str) => str?.toLowerCase().replace(/s$/, ''); // remove trailing 's' const normalizedInput = normalize(uomName); // Try exact match let match = UomPreference.find( (item) => normalize(item.ConfigName || '') === normalizedInput ); // If no exact match, try partial match (like "kg" in "KGS") if (!match) { match = UomPreference.find((item) => normalize(item.ConfigName || '').includes(normalizedInput) ); } return match ? match.ConfigId : getUOMConfigId('PCS'); // fallback to PCS }; const AutoProdFun = async () => { const regex = /([\d.]+)\s*([a-zA-Z]+)\)?$/; const match = cardData?.[0]?.ProdName.match(regex); if (match) { const quantity = parseFloat(match[1]); const uom = match[2]; const name = cardData?.[0]?.ProdName.slice(0, match.index) ?.replace(/[\(\),]+$/, '') ?.trim(); // return { name, quantity, uom }; const configId = await getUOMConfigId(uom); console.log(configId, 'configIdconfigIdconfigIdconfigId'); // setSelectedUom(configId) handleUomDropDownChange(configId); console.log(`ConfigId for ${uom}:`, configId); formRef.current?.setFieldsValue({ ProdName: name }); formRef.current?.setFieldsValue({ Size: quantity }); formRef.current?.setFieldsValue({ BrandName: cardData?.[0]?.Brand }); setBrandImageUrl(cardData?.[0]?.ImageUrl); } else { const configId = await getUOMConfigId('PCS'); formRef.current?.setFieldsValue({ ProdName: cardData?.[0]?.ProdName.trim(), }); formRef.current?.setFieldsValue({ Size: 1 }); handleUomDropDownChange(configId); formRef.current?.setFieldsValue({ BrandName: cardData?.[0]?.Brand }); setBrandImageUrl(cardData?.[0]?.ImageUrl); } }; const handleUomDropDownChange = async (ConfigId) => { formRef.current?.setFieldsValue({ UOM: ConfigId }); await setSelectedUom(ConfigId); }; 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 handleTax = () => { setOpenTaxModel(false); }; const handleTaxDropDownChange = async (TaxId) => { formRef.current?.setFieldsValue({ TaxId: TaxId }); await setSelectedTaxId(TaxId); }; const handleTaxNameDropDownChange = async (ConfigId) => { formTaxRef.current?.setFieldsValue({ TaxName: ConfigId }); await setSelectedTaxNameId(ConfigId); }; const getOptionLabel = (option, selected) => { return selected ? option.TaxPercentage + ' %' : option.TaxIdName + ' - ' + option.TaxPercentage + ' % '; }; const onFinish = async (values) => { let postData = values; postData['CompId'] = CompId; postData['BranchId'] = BranchId; postData['AppId'] = AppId; postData['ProdType'] = ProductTypeData?.filter( (item) => item.ConfigName === 'Product' )?.[0]?.['ConfigId']; postData['ProdCat'] = ProdCatData?.filter( (item) => item.ConfigName === 'General' )?.[0]?.['ConfigId']; postData['ProdSubCat'] = ProdSubCatData?.filter( (item) => item.ConfigName === 'General' )?.[0]?.['ConfigId']; postData['QtyBasedPrice'] = 'N'; postData['ProdQtywisePriceDetails'] = []; postData['StockAvailable'] = 'N'; postData['TokenAvailable'] = 'N'; postData['TaxId'] = SelectedTaxId; postData['InwardDate'] = new Date().toJSON(); postData['SuppId'] = SupplierData?.filter( (item) => item.SuppName?.toLowerCase() === 'Self'?.toLowerCase() )?.[0]?.['SuppId']; postData['AutoGenerateQr'] = 'N'; postData['QRCode'] = ProductSearchValue?.length > 0 ? ProductSearchValue : null; postData['CreatedBy'] = UserId; postData['ProdLogo'] = imageBrandUrl; 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) { setMessageType('success'); setMessageData(response?.data?.response); formRef.current?.resetFields(); setSelectedUom(null); setSelectedTaxId(null); handleCancelData(); setOpenAdd(false); if (ProductSearchType != 'C') { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, }; await dispatch(getSelectedFavItems(data)).unwrap(); await dispatch(getLayoutCategories(data)).unwrap(); let data1 = { CompId: CompId, BranchId: BranchId, AppId: AppId, ProdSubCat: ProdSubCat, }; let data2 = { compId: CompId, branchId: BranchId, appId: AppId, prodCat: prodCat, }; if ( templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) && ProdSubCat ) { await dispatch(getLayoutproductCard(data1)).unwrap(); } else if ( !templateData?.BookingLayout?.[1]?.some( (item) => item?.OptionName === 'SubCategory' ) ) { await dispatch(getCardDataWithoutSubmodule(data2)).unwrap(); } else { await dispatch(getCardDataWithoutSub(data2)).unwrap(); } } let productData = response?.data?.ProductDetails?.[0]; dispatch(ChangeNewQrProduct({ ...productData, Quantity: parseInt(1) })); if ( ProductSearchValue && (ProductSearchType == 'I' || ProductSearchType == 'C') ) { dispatch(changeSearchedData([])); } } else { setMessageType('error'); setMessageData(response?.data?.response); } }; const addTax = () => { setOpenTaxModel(true); }; const updateBrandImageUrl = (url) => { setBrandImageUrl(url); }; const handleHsnData = async (value) => { const response = await dispatch(getHsnData(value)).unwrap(); if (response?.data?.statusCode === 1) { const data = response?.data?.data; setTimeout(() => { setHsnDetails(data); }, 1000); } else { setMessageData(response?.data?.response); setMessageType('error'); } } return (