Android_Retail/src/Pages/StockMaster/StockForm.jsx

5500 lines
197 KiB
React
Raw Normal View History

2026-01-27 18:27:29 +05:30
import React, {
useState,
useEffect,
useRef,
useContext,
useCallback,
useMemo,
} from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import {
ArrowRightOutlined,
PlusCircleOutlined,
InfoCircleOutlined,
} from '@ant-design/icons';
import {
Form,
Tooltip,
Table,
Input,
Collapse,
AutoComplete,
Switch,
} from 'antd';
import { IoAddCircleSharp } from 'react-icons/io5';
import { ScannerInputField } from '../../Components/Forms/ScannerInputField.jsx';
import { InputField } from '../../Components/Forms/InputField.jsx';
import Buttons from '../../Components/Forms/Buttons.jsx';
import { Messages } from '../../Components/Notifications/Messages.jsx';
import { DeleteFilled } from '@ant-design/icons';
import { changeBreadCrumb } from '../../Features/AppPage/CenterPage.js';
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,
} 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,
} 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 {
getSupplaierIdBasedProducts,
getSupplaierIdwithTypeBasedProducts,
postSupplaierProducts,
} from '../../Features/SupplierProductMapping/SupplierProductMapping.js';
import { 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';
const subDirectory = import.meta.env.BASE_URL;
const EditableContext = React.createContext(null);
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef?.current?.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({
...record,
...values,
});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
// rules={[
// (dataIndex == "imei1" || dataIndex == "imei2") && {
// pattern: /^[0-9]{15}$/,
// message: 'IMEI must be a 15-digit number'
// }
// ]}
>
<Input
ref={inputRef}
onPressEnter={save}
onBlur={save}
onMouseLeave={save}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
/>
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{
paddingRight: 24,
}}
onClick={toggleEdit}
>
{/* {dataIndex === "CurrentAmt" && Array.isArray(record[dataIndex])
? record[dataIndex]?.map((item, index) => (
<span key={index}>
{item.CurrentAmt + "-" + item.CurrentAmt}
</span>
))
: children} */}
<Input
ref={inputRef}
onPressEnter={save}
onBlur={save}
value={
Array.isArray(record[dataIndex]) ? undefined : record[dataIndex]
}
/>
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
const StockForm = ({ formType }) => {
const { Panel } = Collapse;
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();
const location = useLocation();
const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState('');
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 [applicationRestrictedFields, setApplicationRestrictedFields] =
useState({
DatesAndExpiry: false,
BatchAndModelDetails: false,
AmountPerPieceDetail: false,
});
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([]);
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);
const [deliveryPerformanceData, SetDeleveryPerformanceData] = useState([]);
const [DiscountData, setDiscountData] = useState([]);
const [QualityData, setQualityData] = useState([]);
const [Delivery, setDeliveryValue] = useState();
const [DicountValue, setDicountValue] = useState();
const [QualityValue, setQualityValue] = useState();
const [ViewDtl, setViewDtl] = useState(false);
const [paymentOptions, setPaymentOptions] = useState([]);
const [selectedPaymentMode, setSelectedPaymentMode] = useState(null);
const [payAmountDisable, setPayAmountDisable] = useState(
paymentOptions
?.find((option) => option?.ModeId === selectedPaymentMode)
?.ModeName?.toLowerCase() === 'credit'
);
const [extractorModalVisible, setExtractorModalVisible] = useState(false);
const [extractorData, setExtractorData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [loadingText, setLoadingText] = useState('');
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
{
name: 'Product Receipt',
link: `${subDirectory}setting/purchase-entry`,
},
{
name: editstate ? 'Edit' : 'New',
link: null,
},
];
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
dispatch(
getProductData({ CompId: CompId, AppId: AppId, BranchId: BranchId })
).unwrap();
dispatch(getProductTypeData());
dispatch(getAdmin({ AppId: AppId, CompId: CompId }));
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());
formRef.current?.setFieldsValue({ DueDate: new Date().toJSON() });
setPurchaseDate(new Date().toJSON());
formRef.current?.setFieldsValue({ InvoiceDate: new Date().toJSON() });
formRef.current?.setFieldsValue({ OrderType: 'N' });
}
if (formType == 'edit') {
formRef.current?.setFieldsValue({
ProdId: editstate?.ProdId,
ProdVariantName: editstate?.ProdVariantName,
SuppId: editstate?.SuppId,
InwardDate: editstate?.InwardDate + 'T00:00:00',
});
if (applicationRestrictedFields.DatesAndExpiry) {
formRef.current?.setFieldsValue({
ManufDate: editstate?.ManufDate,
ExpDate: editstate?.ExpDate,
});
}
handleSupplierBasedProduct(editstate?.SuppId);
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]);
useEffect(() => {
let x = productData?.filter((e) => e.ProdId == selectedProductData);
setVariantData1(x?.[0]?.ProdVariantPriceDetails);
}, [selectedProductData]);
const getSuplaierApi = async ({ dataReturn = false }) => {
const response = await dispatch(
getPurchaseSupplierAndWareHouseData({ CompId, AppId, BranchId })
).unwrap();
if (response?.statusCode === 1) {
setSupplierData(response?.data);
if (dataReturn) {
return response?.data;
}
} else {
setSupplierData([]);
if (dataReturn) {
return [];
}
}
};
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(() => {
let total = PurchaseData?.reduce((accumulator, currentValue) => {
return accumulator + currentValue.Amount;
}, 0);
setSelInvoiceAmount(!isNaN(total) && total !== 0 ? total : null);
formRef.current?.setFieldsValue({
InvoiceAmount: !isNaN(total) && total !== 0 ? total : null,
});
let totaltax = PurchaseData?.reduce((accumulator, currentValue) => {
return accumulator + currentValue.TaxAmt;
}, 0);
setTotalTaxAmount(totaltax);
}, [PurchaseData]);
const getPurchaseOrders = async () => {
const { data: res } = await dispatch(
PendingOrdersPE({ CompId, AppId, BranchId })
).unwrap();
if (res?.statusCode === 1) {
setPurchaseOrderList(
res?.data?.PurchaseOrder?.map((item) => ({
...item,
localId: uuidv4(),
}))
);
} else {
setPurchaseOrderList([]);
setMessageType('error');
setMessageData('No pending purchase orders found.');
}
};
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) =>
(x.SuppMobile || '').toString().includes(m)
);
}
// 2⃣ If no mobile match or mobile empty → fallback to name
if (name) {
const n = name?.trim().toLowerCase(); // 🔥 trimmed + lowercase
list = supplierData.filter(
(x) => (x.SuppName || '').trim().toLowerCase() === n // 🔥 safe compare
);
}
let finalList = list?.length > 0 ? [list[0]] : [];
const mappedSupplierProducts = await handleSupplierDropDownChange(
finalList?.[0]?.SuppId,
null,
supplierData
);
return { mappedSupplierProducts, SuppId: finalList?.[0]?.SuppId };
};
const AddSupplierimg = async (subSupplierData) => {
const addSupplierData = {
CompId: getSession('CompId'),
AppId: getSession('AppId'),
BranchId: getSession('BranchId'),
SuppName: subSupplierData?.SuppName,
SuppGSTIN: subSupplierData?.SuppGSTIN,
SuppPOC: subSupplierData?.SuppPOC,
SuppMobile: subSupplierData?.SuppMobile,
SuppEmail: subSupplierData?.SuppEmail,
Address1: subSupplierData?.Address1,
Address2: subSupplierData?.Address1,
Zip: subSupplierData?.Zip,
City: subSupplierData?.City,
State: subSupplierData?.State,
Dist: subSupplierData?.Dist,
CreatedBy: UserId,
};
let response = {};
response = await dispatch(postSupplier(addSupplierData)).unwrap();
if (response?.data?.statusCode == 1) {
setMessageType('success');
setMessageData(response?.data?.response);
let response1 = await dispatch(
getSupplierData({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
ActiveStatus: 'A',
})
).unwrap();
const suppliers = await getSuplaierApi({ dataReturn: true });
if (response1?.data?.statusCode == 1) {
setZipCodeData(null);
const mappedSupplierProducts = await findMatchingSuppliers(
subSupplierData?.SuppName,
subSupplierData?.SuppMobile,
suppliers
);
return mappedSupplierProducts;
}
} else {
setMessageType('error');
setMessageData(response?.data?.response);
return { mappedSupplierProducts: null, SuppId: null };
}
};
const handleExtractorApply = async (data) => {
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) {
setLoadingText('Loading supplier products...');
supplierProducts = await handleSupplierDropDownChange(
data?.supplierSuggestions?.[0]?.SuppId
);
suppId = data?.supplierSuggestions?.[0]?.SuppId;
}
if (data?.supplierSuggestions?.length === 0) {
setLoadingText('Creating new supplier...');
const Address = await getPincodeValues(data?.pincode);
let suppdata = {
SuppName: data?.name,
SuppMobile: data?.mobile,
SuppGSTIN: data?.gst,
Zip: data?.pincode,
City: Address?.City || '.',
State: Address?.State || '.',
Dist: Address?.Dist || '.',
Address1: data?.address || '.',
};
const { mappedSupplierProducts, SuppId } = await AddSupplierimg(suppdata);
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...');
let matchedProducts = data?.products?.map((imgItem) => {
const match = supplierProducts?.find(
(supp) =>
supp?.ProdName?.toLowerCase() === imgItem?.description?.toLowerCase()
);
return {
selectedProduct: match || null,
parsedData: imgItem,
matchFound: !!match,
selectedProdId: match?.ProdId || null,
};
});
const unmatchedProducts = matchedProducts.filter(
(item) => !item.matchFound
);
if (unmatchedProducts?.length > 0) {
setLoadingText('Mapping unmatched products...');
const response = await dispatch(
getSupplaierIdBasedProducts({ CompId, AppId, BranchId, SuppId: suppId })
).unwrap();
if (response?.data?.statusCode === 1) {
const allSupplierProducts = response?.data?.data || [];
const matchingProdIds = [];
2026-01-27 18:27:29 +05:30
// check if the unmatched products exists in our products list
unmatchedProducts.forEach((item) => {
const match = allSupplierProducts?.[0]?.ProductDetails.find(
(supp) =>
supp?.ProdName?.toLowerCase() ===
item?.parsedData?.description?.toLowerCase()
);
if (match) {
matchingProdIds.push(match.ProdId);
}
});
2026-01-27 18:27:29 +05:30
// if there is matching products, map them to the supplier
if (matchingProdIds.length > 0) {
setLoadingText('Mapping products to supplier...');
const payload = {
CompId,
BranchId,
AppId,
SuppId: suppId,
ProductDetails: matchingProdIds.map((item) => ({ ProdId: item })),
};
const response = await dispatch(
postSupplaierProducts(payload)
)?.unwrap();
if (response?.data?.statusCode === 1) {
const suppliers = await getSuplaierApi({ dataReturn: true });
const mappedSupplierProducts = await handleSupplierDropDownChange(
suppId,
null,
suppliers
);
// update matchedProducts with newly mapped products
matchedProducts = data?.products?.map((imgItem) => {
const match = mappedSupplierProducts?.find(
(supp) =>
supp?.ProdName?.toLowerCase() ===
imgItem?.description?.toLowerCase()
);
return {
selectedProduct: match || null,
parsedData: imgItem,
matchFound: !!match,
selectedProdId: match?.ProdId || null,
};
});
console.log(matchedProducts, 'matchedProductsmatchedProducts');
if (matchedProducts?.length > 0) {
setLoadingText('Adding products to purchase list...');
const newProducts = [];
for (const item of matchedProducts) {
if (item.matchFound) {
const newProduct = await ProductDropDownChange(
item.selectedProdId,
{ label: item.selectedProduct.ProdName },
mappedSupplierProducts,
true,
item,
newProducts
);
if (newProduct) {
if (
!PurchaseData.some((p) => p.ProdId === newProduct.ProdId)
) {
newProducts.push(newProduct);
} else {
if (suppId !== selectedSupplierData) {
newProducts.push(newProduct);
} else {
setMessageType('error');
setMessageData(
`Product ${newProduct.ProdName} already added in the list.`
);
}
}
}
}
}
// if (newProducts.length > 0) {
const updatedPurchaseData = [...PurchaseData, ...newProducts];
const purchasedData =
selectedSupplierData === suppId
? updatedPurchaseData
: newProducts;
setPurchaseData(purchasedData);
if (purchasedData.length > 0) {
for (const item of purchasedData) {
const index = purchasedData.indexOf(item);
const localId = item?.localId;
form.setFieldsValue({
...form.getFieldsValue(),
[`BalanceQty${localId}`]: item.BalanceQty,
[`ReceivedQty${localId}`]: item.ReceivedQty,
[`AcceptedQty${localId}`]: item.AcceptedQty,
[`RejectedQty${localId}`]: item?.RejectedQty,
[`InwardPrice${localId}`]: item?.InwardPrice,
[`Amount${localId}`]: item?.Amount,
});
}
}
// }
setMessageType('success');
setMessageData('Extracted data applied successfully!');
} else {
setMessageType('error');
setMessageData(
'No matching products found in your product list.'
);
console.log('Matching 1');
}
} else {
setMessageType('error');
setMessageData(
'Error Occurred while mapping products with supplier.'
);
}
} else {
setMessageType('error');
setMessageData('No matching products found in your product list.');
console.log('Matching 2');
}
} else {
setIsLoading(false);
setLoadingText('');
setMessageType('error');
setMessageData('Error Occurred while mapping products with supplier.');
return;
}
} else {
if (matchedProducts?.length > 0) {
setLoadingText('Adding products to purchase list...');
const newProducts = [];
for (const item of matchedProducts) {
if (item.matchFound) {
const newProduct = await ProductDropDownChange(
item.selectedProdId,
{ label: item.selectedProduct.ProdName },
supplierProducts,
true,
item,
newProducts
);
if (newProduct) {
if (!PurchaseData.some((p) => p.ProdId === newProduct.ProdId)) {
newProducts.push(newProduct);
} else {
if (suppId !== selectedSupplierData) {
newProducts.push(newProduct);
} else {
setMessageType('error');
setMessageData(
`Product ${newProduct.ProdName} already added in the list.`
);
}
}
}
}
}
// if (newProducts.length > 0) {
const updatedPurchaseData = [...PurchaseData, ...newProducts];
const purchasedData =
selectedSupplierData === suppId ? updatedPurchaseData : newProducts;
setPurchaseData(purchasedData);
if (purchasedData.length > 0) {
for (const item of purchasedData) {
const index = purchasedData.indexOf(item);
const localId = item?.localId;
form.setFieldsValue({
...form.getFieldsValue(),
[`BalanceQty${localId}`]: item.BalanceQty,
[`ReceivedQty${localId}`]: item.ReceivedQty,
[`AcceptedQty${localId}`]: item.AcceptedQty,
[`RejectedQty${localId}`]: item?.RejectedQty,
[`InwardPrice${localId}`]: item?.InwardPrice,
[`Amount${localId}`]: item?.Amount,
});
}
}
// }
setMessageType('success');
setMessageData('Extracted data applied successfully!');
} else {
setMessageType('error');
setMessageData('No matching products found in your product list.');
console.log('Matching 3');
}
}
setExtractorModalVisible(false);
setIsLoading(false);
setLoadingText('');
};
const applicationApplicableFields = async () => {
const response = await dispatch(getCommonAppPreference(AppId)).unwrap();
if (response?.data?.statusCode === 1) {
const details = response?.data?.data?.[0]?.PreferenceDetails?.find(
(find) => find.PreferredCatName === 'Purchase Entry'
);
if (Object.keys(details || {})?.length > 0) {
if (details?.PreferenceCatDetails?.length > 0) {
setApplicationRestrictedFields({
DatesAndExpiry: details?.PreferenceCatDetails?.some(
(some) =>
some.PreferredSubCatName === 'Dates & Expiry' &&
some.PreferredStatus === 'Y'
),
BatchAndModelDetails: details?.PreferenceCatDetails?.some(
(some) =>
some.PreferredSubCatName === 'Batch & Model Details' &&
some.PreferredStatus === 'Y'
),
AmountPerPieceDetail: details?.PreferenceCatDetails?.some(
(some) =>
some.PreferredSubCatName === 'Amount Per Piece' &&
some.PreferredStatus === 'Y'
),
});
return;
}
}
setApplicationRestrictedFields({
DatesAndExpiry: null,
BatchAndModelDetails: null,
AmountPerPieceDetail: null,
});
}
};
const filteredOptions = useMemo(() => {
return (
purchaseOrderList?.map((data) => {
const purchaseInvoiceParts = data?.PurOrderId?.split('-');
return {
value: data?.PurOrderId,
label: purchaseInvoiceParts[purchaseInvoiceParts?.length - 1],
};
}) || []
);
}, [purchaseOrderList, selectedSupplierData]);
const getPurchaseType = async () => {
let res = await dispatch(getPurchaseTypeData()).unwrap();
if (res?.data?.statusCode === 1) {
setPurchaseTypeData(res?.data?.data);
let tempcash = res?.data?.data?.find(
(item) => item?.ConfigName?.toLowerCase() === 'cash'
);
setSelectedPurchaseType(tempcash?.ConfigId);
formRef.current?.setFieldsValue({ PaymentType: tempcash?.ConfigId });
} else {
setPurchaseTypeData(null);
}
};
const getPurchaseTaxType = async () => {
let res = await dispatch(getPurchaseTaxTypeData()).unwrap();
if (res?.data?.statusCode === 1) {
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);
}
};
const pinCodeChange = async (e) => {
if (e.target.value?.length < 6) {
setZipCodeData(false);
return false;
}
await getPincodeValues(e?.target?.value);
};
const getPincodeValues = async (pinCode) => {
let response = '';
await fetch(`https://api.postalpincode.in/pincode/${pinCode}`)
.then((res) => res.text())
.then((text) => (response = JSON.parse(text)));
if (response[0]['Status'] === 'Success') {
setZipCodeData(true);
formSupplierRef.current?.setFieldsValue({
City: response[0]['PostOffice'][0]['Block'],
Dist: response[0]['PostOffice'][0]['District'],
State: response[0]['PostOffice'][0]['State'],
});
return {
City: response[0]['PostOffice'][0]['Block'],
Dist: response[0]['PostOffice'][0]['District'],
State: response[0]['PostOffice'][0]['State'],
};
} else {
setZipCodeData(false);
}
};
const handleMRP = () => {
formProductRef.current?.setFieldsValue({ SellPrice: null });
};
const handleSuppInvoiceNoChange = (e) => {
formProductRef.current?.setFieldsValue({ SuppInvoiceNo: e.target.value });
2026-01-27 18:27:29 +05:30
};
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'
);
formRef?.current?.setFieldsValue({
SuppInvoiceNo: extractorData?.invoiceNo,
});
2026-01-27 18:27:29 +05:30
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 (
SuppId,
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;
formRef?.current?.setFieldsValue({ CustSuppId: SuppId });
setSelectedSupplierData(SuppId);
const mappedSupplierProducts = await handleSupplierBasedProduct(SuppId);
formRef?.current?.resetFields(['VarProdId', 'ProdId']);
suppName === 'Self'
? setSelectedSupplierName(false)
: setSelectedSupplierName(true);
setselectedProductVariantData(null);
setSelectedProductData(null);
setSelectedProductName(null);
formRef?.current?.setFieldsValue({ ProdId: null });
setSearchText(null);
return mappedSupplierProducts;
};
const handlePurchaseTypeChange = (PurId) => {
formRef.current?.setFieldsValue({ PaymentType: PurId });
setSelectedPurchaseType(PurId);
};
const onSuppInvoiceDateChange = async (date, dateString) => {
if (dateString) {
const Date3 = moment(dateString, ['DD-MM-YYYY']).format(
'YYYY-MM-DDTHH:mm:ss'
);
formRef.current?.setFieldsValue({ SuppInvoiceDate: Date3 });
setSuppInvoiceDate(Date3);
} else if (dateString === '') {
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(
'YYYY-MM-DDTHH:mm:ss'
);
formRef.current?.setFieldsValue({ DueDate: Date3 });
setPurchaseDate(Date3);
} else if (dateString === '') {
setPurchaseDate();
}
};
const ProductDropDownChange = async (
ProdId,
option,
productsList,
extractedProduct = false,
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)
?.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 (
cc?.[0]?.ProdVariantDetails?.length < 2 ||
(extractedProduct ? cc?.[0]?.ProdVariantDetails?.length > 0 : false)
) {
// let getSuppId = (productsList || productData)?.filter((item) => item.ProdId == ProdId);
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)) {
setMessageType('error');
setMessageData('Already Product Exists');
return null;
} else {
let ProductData1 = (productsList || productData)?.find(
(e) => e.ProdId == ProdId
);
let DefaultVariant = ProductData1?.ProdVariantPriceDetails?.find(
(item) => item?.DefaultVariant === 'Y' && item?.ReceivedQty === 0
)?.DefaultVariant;
let ProduData2 = {
DefaultVariant: DefaultVariant,
ProdId: ProductData1?.ProdId,
MRP: ProductData1?.MRP,
ProdName: ProductData1?.ProdName,
UomName: ProductData1?.UomName,
SellPrice: ProductData1?.SellPrice,
StockAvailable: ProductData1?.StockAvailable,
OnePcsAvailable: ProductData1?.OnePcsAvailable,
NumberofPieceinside: ProductData1?.NoOfPcs,
AmountPerPiece: ProductData1?.OnePcsPrice,
TaxId: ProductData1?.TaxId,
TaxPercentage: ProductData1?.TaxPercentage,
};
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;
let tempPurData = {
...ProduData2,
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,
ProdVariantName: 'Variant 1',
FreeItem: 0,
TaxAmt: 0,
TaxType: SelectedPurcTaxType ? SelectedPurcTaxType : 0,
PurcDiscType: 'P',
refImage: extractedItem?.parsedData?.image,
PurchaseHSNCode: extractedItem?.parsedData?.hsn || '',
localId: uuidv4(),
};
return tempPurData;
}
}
};
const debouncedScannerSearch = useCallback(
debounce(async (value) => {
const qr = value?.trim();
const matchedProduct = productData.find(
(p) => p.QRCode?.toLowerCase() === qr?.toLowerCase()
);
if (matchedProduct) {
let productName = {};
productName.label = `${matchedProduct?.ProdName} (${matchedProduct.Size} ${matchedProduct.UomName})${matchedProduct?.BrandName ? ` - ${matchedProduct?.BrandName}` : ''}`;
const newProduct = await ProductDropDownChange(
matchedProduct.ProdId,
productName
);
if (newProduct) {
setPurchaseData([newProduct, ...PurchaseData]);
}
if (matchedProduct?.ProdVariantPriceDetails?.length < 2) {
setSelectedProductName('');
setSelectedProductData(null);
}
} else {
setMessageType('error');
setMessageData('The Scanned Product not Available in Product List');
}
}, 300),
[productData]
);
// 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) {
setMessageType('success');
setMessageData('Search by QrCode/BarCode Enabled');
} else {
setMessageType('success');
setMessageData('Search by QrCode/BarCode Disabled');
}
setScanner((prev) => !prev);
setSelectedProductName(null);
setselectedProductVariantData(null);
setVariants(null);
formRef?.current?.setFieldsValue({
ProdId: null,
VarProdId: null,
});
};
const ProductVariantDropDownChange = (value) => {
const ProdName2 = Variants?.filter(
(item) => item.ProdIdProdName === value
)?.[0]?.ProdVariantName;
const ProdName1 = PurchaseData?.some(
(item) =>
item.ProdId === selectedProductData &&
item.ProdVariantName === ProdName2
);
if (ProdName1) {
setMessageType('error');
setMessageData('Already variant Exists');
} else {
const ProdName = Variants?.filter(
(item) => item.ProdIdProdName === value
)?.[0]?.ProdVariantName;
const OnePcsAvailable = Variants?.filter(
(item) => item.ProdIdProdName === value
)?.[0]?.OnePcsAvailable;
formRef?.current?.setFieldsValue({ VarProdId: value });
setselectedProductVariantData(ProdName);
let ProductData1 = productData?.find(
(e) => e.ProdId == selectedProductData
);
let mrp;
let sellprice;
if (ProdName == 'Variant 1') {
mrp = ProductData1?.MRP;
sellprice = ProductData1?.SellPrice;
} else {
mrp = ProductData1?.ProdVariantPriceDetails?.find(
(item) => item.ProdVariantName == ProdName
)?.MRP;
sellprice = ProductData1?.ProdVariantPriceDetails?.find(
(item) => item.ProdVariantName == ProdName
)?.SellPrice;
}
let DefaultVariant = ProductData1?.ProdVariantPriceDetails?.find(
(item) => item?.ProdVariantName === ProdName && item?.ReceivedQty === 0
)?.DefaultVariant;
let ProduData2 = {
DefaultVariant: DefaultVariant,
ProdId: ProductData1?.ProdId,
MRP: mrp,
ProdName: ProductData1?.ProdName,
UomName: ProductData1?.UomName,
SellPrice: sellprice,
StockAvailable: ProductData1?.StockAvailable,
OnePcsAvailable: ProductData1?.OnePcsAvailable,
NumberofPieceinside: ProductData1?.NoOfPcs,
AmountPerPiece: ProductData1?.OnePcsPrice,
TaxId: ProductData1?.TaxId,
TaxPercentage: ProductData1?.TaxPercentage,
};
// ProduData2["StockAvailable"]="Y"
const localId = uuidv4();
let tempPurData = {
...ProduData2,
BalanceQty: 0,
InwardPrice: 0,
PurcDisc: 0,
Amount: 0,
WhSalePrice: 0,
ReceivedQty: 0,
AcceptedQty: 0,
FreeItem: 0,
RejectedQty: 0,
OfferPrice: 0,
SpecialPrice: 0,
ProdVariantName: ProdName,
// 'TaxId': PurcselectedTax ? PurcselectedTax : 0,
TaxAmt: 0,
TaxType: SelectedPurcTaxType ? SelectedPurcTaxType : 0,
PurcDiscType: 'P',
localId: localId,
PurchaseTax: 0,
};
form?.setFieldsValue({
[`SellPrice${localId}`]: tempPurData?.SellPrice,
[`PurchaseTax${localId}`]: tempPurData?.PurchaseTax,
});
setPurchaseData([tempPurData, ...PurchaseData]);
Delete
? (form.setFieldsValue({
[`BalanceQty${index}`]: undefined,
[`ReceivedQty${index}`]: undefined,
[`AcceptedQty${index}`]: undefined,
[`RejectedQty${index}`]: undefined,
[`Amount${index}`]: undefined,
[`FreeQty${index}`]: undefined,
[`InwardPrice${index}`]: undefined,
[`MRP${index}`]: undefined,
[`PurcDisc${index}`]: undefined,
[`SellPrice${index}`]: undefined,
[`WhSalePrice${index}`]: undefined,
[`offerSalePrice${index}`]: undefined,
[`splSalePrice${index}`]: undefined,
[`NumberofPieceinside${index}`]: undefined,
[`AmountPerPiece${index}`]: undefined,
}),
setDelete(false))
: ' ';
}
};
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'),
SuppName: subSupplierData?.SuppName,
SuppGSTIN: subSupplierData?.SuppGSTIN,
SuppPOC: subSupplierData?.SuppPOC,
SuppMobile: subSupplierData?.SuppMobile,
SuppEmail: subSupplierData?.SuppEmail,
Address1: subSupplierData?.Address1,
Address2: subSupplierData?.Address1,
Zip: subSupplierData?.Zip,
City: subSupplierData?.City,
State: subSupplierData?.State,
Dist: subSupplierData?.Dist,
SuppPOCMobile: subSupplierData?.SuppPOCMobile,
SuppPOCEmail: subSupplierData?.SuppPOCEmail,
DeliveryPerformance: subSupplierData?.DeliveryPerformance,
DiscountLevel: subSupplierData?.DiscountLevel,
QualityofSupp: subSupplierData?.QualityofSupp,
CreatedBy: UserId,
};
let response = {};
response = await dispatch(postSupplier(addSupplierData)).unwrap();
if (response?.data?.statusCode == 1) {
setMessageType('success');
setMessageData(response?.data?.response);
let response1 = await dispatch(
getSupplierData({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
ActiveStatus: 'A',
})
).unwrap();
if (response1?.data?.statusCode == 1) {
setOpenSupplierModel(false);
}
formSupplierRef?.current?.resetFields();
setZipCodeData(null);
} else {
setMessageType('error');
setMessageData(response?.data?.response);
formSupplierRef?.current?.resetFields();
}
};
const getOptionLabel = (option, selected) => {
return selected
? option.TaxPercentage + ' %'
: option.TaxIdName + ' - ' + option.TaxPercentage + ' % ';
};
const isEditing = (record, index) => record?.localId === editingKey;
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 },
});
setDelete(false);
} else {
form.setFieldsValue({
BalanceQty: { [localId]: record?.BalanceQty },
ReceivedQty: { [localId]: record?.ReceivedQty },
AcceptedQty: { [localId]: record?.AcceptedQty },
RejectedQty: { [localId]: record?.RejectedQty },
PurcDiscType: { [localId]: record?.PurcDiscType },
Amount: { [localId]: record?.Amount },
FreeQty: { [localId]: record?.FreeItem },
InwardPrice: { [localId]: record?.InwardPrice },
MRP: { [localId]: record?.MRP },
PurcDisc: { [localId]: record?.PurcDisc },
SellPrice: { [localId]: record?.SellPrice },
WhSalePrice: { [localId]: record?.WhSalePrice },
offerSalePrice: { [localId]: record?.OfferPrice },
splSalePrice: { [localId]: record?.SpecialPrice },
NumberofPieceinside: { [localId]: record?.NumberofPieceinside },
AmountPerPiece: { [localId]: record?.AmountPerPiece },
});
if (applicationRestrictedFields.BatchAndModelDetails) {
form.setFieldsValue({
BatchRef: { [localId]: record?.BatchRef },
});
}
}
};
const save = async (index) => {
try {
const row = await form?.validateFields();
const modifiedObject = {};
for (const key in row) {
const newKey = key.slice(0, -1); // Remove the last character ("0") from the key
modifiedObject[newKey] = row[key];
}
const newData = [...PurchaseData];
// const index = newData.findIndex((item) => recordKey === item.InwardDtlId);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...modifiedObject });
setPurchaseData(newData);
setEditingKey('');
}
} catch (err) {
console.error('Save failed:', err);
}
};
const handleKeyPress = async (e, record, index) => {
if (e.key === 'Enter') {
try {
await form.validateFields();
save(index);
} catch (error) {
console.error('Save failed:', error);
}
}
};
const openAdditionalInfoModal = (record, index) => {
console.log(record, 'recordrecord');
if (record?.ReceivedQty === 0 || record?.ReceivedQty === '') {
setMessageType('error');
setMessageData('Please Enter Qty');
return;
}
setSelectedRowIndex(index);
setSelectedRowRecord(record);
setAdditionalInfoModal(true);
};
const columns = [
{
title: 'SL.NO',
align: 'center',
key: 'sno',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{index + 1}</a>
),
},
{
title: 'Product Name',
dataIndex: 'ProdName',
key: 'ProdName',
align: 'left',
render: (text, record, index) => (
<a style={{ color: 'black' }}>
{record?.ProdName + '(' + record?.ProdVariantName + ')'}
</a>
),
},
{
title: 'Uom',
dataIndex: 'UomName',
key: 'UOMName',
},
{
title: 'Qty',
dataIndex: 'BalanceQty',
key: 'BalanceQty',
editable: true,
render: (text, record, index) => {
return isEditing(record, index) ? (
<Form.Item
name={'BalanceQty' + record?.localId}
rules={[
{
required: true,
pattern: /^(0+\d*[1-9]\d*|[1-9]\d*|0\.\d+)(\.\d+)?$/,
message: 'Please enter quantity',
},
{
validator: (_, value) => {
if (value?.length > 10) {
return Promise.reject(
'Quantity cannot exceeds more than 10 chars'
);
}
return Promise.resolve();
},
},
]}
>
<Input
onPressEnter={(e) => handleKeyPress(e, record, index)}
onBlur={(e) => handleQtyChange(e, record)}
onChange={(e) => handleQtyChange(e, record, index)}
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;
}}
/>
</Form.Item>
) : (
text
);
},
},
{
title: (
<Tooltip title="Purchase rate per unit" placement="top">
Purchase Rate / Unit
</Tooltip>
),
dataIndex: 'InwardPrice',
key: 'InwardPrice',
width: 120,
editable: true,
render: (text, record, index) => {
return isEditing(record, index) ? (
<Form.Item
name={'InwardPrice' + record?.localId}
rules={[
{
required: true,
pattern: /^(0+\d*[1-9]\d*|[1-9]\d*|0\.\d+)(\.\d+)?$/,
message: 'Please enter Purchase Rate',
},
{
validator: (_, value) => {
if (value?.length > 10) {
return Promise.reject(
'Purchase Rate cannot exceeds more than 10 chars'
);
}
return Promise.resolve();
},
},
]}
>
<Input
onPressEnter={(e) => handleKeyPress(e, record, index)}
onChange={(e) => handlePurrateChange(e, record, index)}
onBlur={(e) => handlePurrateChange(e, record, index)}
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;
}}
/>
</Form.Item>
) : (
text || 0
);
},
},
{
title: (
<Tooltip title="GST (CGST + SGST or IGST)" placement="top">
{' '}
Tax (%){' '}
</Tooltip>
),
dataIndex: 'PurchaseTax',
key: 'PurchaseTax',
width: 120,
editable: true,
render: (text, record, index) => {
return isEditing(record, index) ? (
<Form.Item
name={`PurchaseTax${record?.localId}`}
validateTrigger={['onChange', 'onBlur']}
rules={[
{
validator: (_, value) => {
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();
},
},
]}
>
<Input
onPressEnter={(e) => handleKeyPress(e, record, index)}
onChange={(e) => handleTaxChange(e, record, index)}
onBlur={(e) => handleTaxChange(e, record, index)}
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;
}}
/>
</Form.Item>
) : (
text || 0
);
},
},
{
title: 'Amount',
dataIndex: 'Amount',
key: 'Amount',
editable: true,
},
{
title: (
<Tooltip title="Selling price per unit" placement="top">
Selling Price / Unit
</Tooltip>
),
dataIndex: 'SellPrice',
key: 'SellPrice',
width: 120,
editable: true,
render: (text, record, index) => {
return isEditing(record, index) ? (
<Form.Item
name={`SellPrice${record?.localId}`}
rules={[
{
validator: validateSellPrice(record),
},
]}
>
<Input
onPressEnter={(e) => handleKeyPress(e, record, index)}
onChange={(e) => handleSellPriceChange(e, record, index)}
onBlur={(e) => handleSellPriceChange(e, record, index)}
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;
}}
/>
</Form.Item>
) : (
text || 0
);
},
},
{
title: 'Additional Info',
dataIndex: 'AdditionalInfo',
key: 'AdditionalInfo',
width: 120,
align: 'center',
render: (text, record, index) => {
return (
<>
{' '}
<IoAddCircleSharp
style={{ cursor: 'pointer' }}
onClick={() => openAdditionalInfoModal(record, index)}
className="shape-preview"
/>
</>
);
},
},
{
title: 'Action',
dataIndex: 'Action',
key: 'Action',
align: 'center',
render: (_, record, index) => (
<a
onClick={(e) => {
e.stopPropagation();
}}
>
<DeleteFilled
style={{
color: '#FF4D4F',
}}
onClick={() => statusFormatters(record, index)}
/>
</a>
),
},
];
const statusFormatters = (record, index) => {
const localId = record?.localId;
const Data = PurchaseData.filter((_, i) => i !== index);
setDelete(true);
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,
});
setVariants();
setPurchaseData(Data);
setSelectedProductData(null);
formRef?.current?.setFieldsValue({ ProdId: null });
};
const handleQtyChange = (e, record, index) => {
const { localId } = record;
const inputValue = e.target.value;
setDataSource([]);
setDataSourceBackup([]);
// Validate if inputValue is numeric
if (!/^\d*\.?\d*$/.test(inputValue)) {
setMessageType('error');
setMessageData('Only numeric values are allowed');
return;
}
const qty = inputValue;
const acceptedQty = parseFloat(qty);
const newData = PurchaseData.map((item, index1) => {
if (index1 === index) {
return {
...item,
Amount:
isNaN(parseFloat(item?.InwardPrice)) || isNaN(acceptedQty)
? 0
: parseFloat(item?.InwardPrice) * acceptedQty,
PurcDisc: 0,
BalanceQty: qty,
ReceivedQty: qty,
AcceptedQty: !isNaN(acceptedQty) ? acceptedQty : 0,
RejectedQty: !isNaN(qty - acceptedQty) ? qty - acceptedQty : 0,
ProductIdentifierDtls: [],
};
}
return item;
});
setPurchaseData(newData);
form.setFieldsValue({
...form.getFieldsValue(),
[`PurcDisc${localId}`]: 0,
[`BalanceQty${localId}`]: qty,
[`ReceivedQty${localId}`]: qty,
[`AcceptedQty${localId}`]: !isNaN(acceptedQty) ? acceptedQty : 0,
[`RejectedQty${localId}`]: !isNaN(qty - acceptedQty)
? qty - acceptedQty
: 0,
// ReceivedQty: qty,
// AcceptedQty: acceptedQty,
// RejectedQty: qty - acceptedQty,
});
};
const handlePurrateChange = (e, record, index) => {
const { localId, PurcDisc, PurcDiscType, PurchaseTax } = record;
const PurcRate = e.target.value;
if (!/^\d*\.?\d*$/.test(PurcRate)) {
setMessageType('error');
setMessageData('Only numeric values are allowed');
return;
}
const Amount = parseFloat(PurcRate) * record?.AcceptedQty;
let discountAmt = 0;
if (PurcDiscType === 'P') {
discountAmt = (Amount * Number(PurcDisc)) / 100;
} else {
discountAmt = Number(PurcDisc);
}
// You can calculate acceptedQty based on your requirement
const newData = PurchaseData.map((item, index1) => {
if (index1 === index) {
return {
...item,
PurcDisc: 0,
InwardPrice: Delete ? 0 : PurcRate,
Amount: !isNaN(Amount) ? Amount : 0,
TaxAmt:
(parseInt(Amount) * parseInt(item?.TaxPercentage)) /
(100 + parseInt(item?.TaxPercentage))?.toFixed(2),
};
}
return item;
});
formRef?.current?.setFieldsValue({
PaymentAmount: newData?.reduce((acc, data) => acc + data?.Amount, 0),
});
setPaymentAmount(newData?.reduce((acc, data) => acc + data?.Amount, 0));
setPurchaseData(newData);
form.setFieldsValue({
[`PurcDisc${localId}`]: 0,
InwardPrice: { [localId]: Delete ? 0 : PurcRate },
Amount: { [localId]: !isNaN(Amount) ? Amount : 0 },
});
};
const handleSellPriceChange = (e, record, index) => {
const { localId } = record;
const value = e?.target?.value;
if (!/^\d*\.?\d*$/.test(value)) {
setMessageType('error');
setMessageData('Only numeric values are allowed');
return;
}
const newData = PurchaseData?.map((item, index1) => {
if (index1 === index) {
return {
...item,
SellPrice: value,
};
}
return item;
});
form.setFieldsValue({
[`SellPrice${localId}`]: value,
});
setPurchaseData(newData);
};
const handleTaxChange = (e, record, index) => {
const { localId } = record;
const value = e?.target?.value;
if (!/^\d*\.?\d*$/.test(value)) {
setMessageType('error');
setMessageData('Only numeric values are allowed');
return;
}
const newData = PurchaseData?.map((item, index1) => {
if (index1 === index) {
return {
...item,
PurchaseTax: parseFloat(value) || 0,
};
}
return item;
});
form.setFieldsValue({
[`PurchaseTax${localId}`]: parseFloat(value) || 0,
});
setPurchaseData(newData);
};
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);
};
const getUniqueImageArray = (data = []) => {
const seen = new Set();
return data.reduce((acc, item) => {
const url = item?.refImage;
if (url && !seen.has(url)) {
seen.add(url);
acc.push({ ImageUrl: url });
}
return acc;
}, []);
};
const onFinish = async ({ PaymentType, PaymentAmount = 0, ...values }) => {
try {
const invalidTaxItems = PurchaseData?.filter((item) => {
const tax = item.PurchaseTax;
if (tax === undefined || tax === '' || tax === null) {
return false;
}
const num = Number(tax);
if (isNaN(num)) {
return true;
}
if (num < 0 || num > 99) {
return true;
}
return false;
});
if (invalidTaxItems && invalidTaxItems.length > 0) {
setMessageType('error');
setMessageData(
'Please enter valid tax percentage (0-99%) for all items'
);
return;
}
if (
PurchaseData?.some(
(item) =>
item.SellPrice &&
item.MRP &&
parseFloat(item.SellPrice) > parseFloat(item.MRP)
)
) {
setMessageType('error');
setMessageData('Selling Price cannot be greater than MRP');
return;
}
if (PurchaseData.length === 0) {
setMessageType('error');
setMessageData('No Product Selected');
return;
}
if (
!PurchaseData?.every(
(item) =>
(parseFloat(item.BalanceQty) ? parseFloat(item.BalanceQty) : 0) !==
0 && item.Amount !== 0
)
) {
setMessageType('error');
setMessageData('Please Enter Qty And Amount');
return;
}
if (!PurchaseData?.every((item) => item.AcceptedQty !== 0)) {
setMessageType('error');
setMessageData('Qty & Rejected Qty Should not be same');
return;
}
if (SupplierOpen === 'paid') {
const { SuppInvoiceNo, SuppInvoiceDate } =
(await formRef?.current?.getFieldsValue()) || {};
if (!SuppInvoiceNo && !SuppInvoiceDate) {
setMessageType('error');
setMessageData(
`Enter The ${invoiceType === 'I' ? 'Invoice ' : 'Delivery Challan'} No and Date`
);
return;
} else if (!SuppInvoiceNo) {
setMessageType('error');
setMessageData(
`Enter The ${invoiceType === 'I' ? 'Invoice ' : 'Delivery Challan'} No`
);
return;
} else if (!SuppInvoiceDate) {
setMessageType('error');
setMessageData(
`Enter The ${invoiceType === 'I' ? 'Invoice ' : 'Delivery Challan'} Date`
);
return;
}
}
const images = getUniqueImageArray(PurchaseData);
const postData = {
...values,
InvoiceAmount: PurchaseData?.reduce(
(acc, data) => acc + data?.Amount,
0
),
CompId,
BranchId,
AppId,
CreatedBy: UserId,
PurOrderStatus: purchaseStatus,
TaxAmount: TotalTaxAmount?.toFixed(2),
BillAmount: (SelInvoiceAmount - TotalTaxAmount)?.toFixed(2),
TotalAmount: SelInvoiceAmount,
PurOrderInvoiceNo: purchaseOrderId,
PaymentStatus: 'S',
LocationType: SupplierData?.find(
(item) => item?.SuppId === selectedSupplierData
)?.Type,
ImageDetails: images || [],
};
const fieldsToRemove = [
'InwardDtlId',
'InwardId',
'UomName',
'ProdName',
'UOMName',
];
const processedData = PurchaseData?.map((item) => {
const cleanItem = { ...item };
fieldsToRemove.forEach((field) => delete cleanItem[field]);
return {
...cleanItem,
TaxType: SelectedPurcTaxType || 0,
BalanceQty: cleanItem.AcceptedQty,
OnePcsPrice: cleanItem.AmountPerPiece,
NoOfPcs: cleanItem.NumberofPieceinside,
};
});
const isPaidSelected = PurchaseTypeData?.some(
(item) =>
item.ConfigId === SelectedPurchaseType && item.ConfigName === 'Cash'
);
if (
(SupplierOpen !== 'own' || selectedSupplierName) &&
selectedSupplierData &&
isPaidSelected
) {
postData.PaymentAmount = PaymentAmount;
postData.PaymentType = selectedPaymentMode;
} else {
postData.PaymentType = PaymentType;
}
postData['ProdDetails'] = processedData;
if (formType === 'edit') {
postData['ProdId'] = editstate?.ProdId;
postData['InwardId'] = editstate?.InwardId;
postData['InwardDtlId'] = editstate?.InwardDtlId;
postData['UpdatedBy'] = UserId;
}
let response;
try {
if (formType === 'add') {
response = await dispatch(postPurchaseData(postData)).unwrap();
} else {
response = await dispatch(putStockData(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) {
navigate(`${subDirectory}setting/purchase-entry/`, {
state: {
Notiffy: {
messageType: 'success',
messageData: response?.data?.response,
},
},
});
} else {
setMessageType('error');
setMessageData(response?.data?.response);
}
} catch (errorInfo) {
console.log('Validation Failed:', errorInfo);
setMessageType('error');
setMessageData('Please correct the highlighted fields');
return;
}
};
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',
dataIndex: 'imei1',
width: '30%',
editable: true,
},
{
title: 'IMEI 2',
dataIndex: 'imei2',
editable: true,
},
{
title: 'Serial No',
dataIndex: 'serialno',
editable: true,
},
{
title: 'Mac Id',
dataIndex: 'Macid',
editable: true,
},
];
const handleSave = (row) => {
const newData = [...dataSource];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setDataSource(newData);
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const IMEIcolumns = defaultColumns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
const handleInvoiceSearch = (value) => {
setSelectedSupplierData(null);
formRef?.current?.setFieldsValue({ CustSuppId: null });
setSelectedSupplierName(true);
setSearchText(value);
setPurchaseOrderId(null);
setSelectedInvoice(null);
setPurchaseData([]);
setProductData([]);
form?.resetFields();
};
const handleInvoiceSelect = async (value) => {
if (value === selectedInvoice) return;
const invoiceParts = value.split('-');
const shortInvoice = invoiceParts[invoiceParts.length - 1];
formRef?.current?.setFieldsValue({ SuppInvoiceNo: value });
formRef?.current?.setFieldsValue({ PurchaseOrderNo: value });
const purchaseOrders = purchaseOrderList?.filter(
(order) => order?.PurOrderId === value
);
const supplierExists = SupplierData?.filter(
(item) => item?.SuppId === purchaseOrders?.[0]?.SuppId
);
console.log(supplierExists, 'supplierExists');
let supplierMappedProducts = [];
if (supplierExists?.length > 0) {
setSelectedSupplierData(purchaseOrders?.[0]?.SuppId);
supplierMappedProducts =
(await handleSupplierBasedProduct(purchaseOrders?.[0]?.SuppId)) || [];
formRef?.current?.setFieldsValue({
CustSuppId: purchaseOrders?.[0]?.SuppId,
});
} else {
setMessageType('error');
setMessageData("Supplier for this Order isn't Active");
return;
}
if (supplierExists?.[0]?.SuppName === 'Self') {
setSelectedSupplierName(false);
setSupplierOpen('own');
} else {
setSelectedSupplierName(true);
}
setSelectedInvoice(value);
setSearchText(shortInvoice);
if (!purchaseOrders?.[0]?.OrderDetails?.length) {
setPurchaseData([]);
return;
}
let unMappedProducts = [];
const orderedData = purchaseOrders[0].OrderDetails.map((order, index) => {
const orderedProduct = supplierMappedProducts?.find(
(prod) => prod?.ProdId === order?.ProdId
);
if (orderedProduct === undefined) {
unMappedProducts.push(`${order?.ProdName}`);
}
const DefaultVariant = orderedProduct?.ProdVariantPriceDetails?.find(
(item) =>
item?.ReceivedQty === 0 &&
item?.ProdVariantName === order?.ProdVariantName &&
item?.ProdId === order?.ProdId
)?.DefaultVariant;
const ProduData2 = {
DefaultVariant,
ProdId: orderedProduct?.ProdId,
MRP: orderedProduct?.MRP,
ProdName: orderedProduct?.ProdName,
UomName: orderedProduct?.UomName,
SellPrice: orderedProduct?.SellPrice,
StockAvailable: orderedProduct?.StockAvailable,
OnePcsAvailable: orderedProduct?.OnePcsAvailable,
NumberofPieceinside: orderedProduct?.NoOfPcs,
AmountPerPiece: orderedProduct?.OnePcsPrice,
TaxId: orderedProduct?.TaxId,
TaxPercentage: orderedProduct?.TaxPercentage,
PurOrderInvoiceNo: order?.PurOrderId,
};
const uniqueId = uuidv4();
const tempPurData = {
...ProduData2,
BalanceQty: JSON.stringify(order?.OrderQty),
InwardPrice: 0,
PurcDisc: 0,
Amount: 0,
WhSalePrice: 0,
ReceivedQty: order?.OrderQty,
AcceptedQty: JSON.stringify(order?.OrderQty),
RejectedQty: 0,
OfferPrice: 0,
SpecialPrice: 0,
ProdVariantName: order?.ProdVariantName,
FreeItem: 0,
TaxAmt: 0,
TaxType: SelectedPurcTaxType || 0,
PurcDiscType: 'P',
localId: uniqueId,
};
form.setFieldsValue({
[`BalanceQty${uniqueId}`]: JSON.stringify(order?.OrderQty),
[`ReceivedQty${uniqueId}`]: order?.OrderQty,
[`AcceptedQty${uniqueId}`]: JSON.stringify(order?.OrderQty),
});
return tempPurData;
});
const filterOrders = orderedData?.filter(
(order) => order?.ProdId !== null && order?.ProdId !== undefined
);
if (filterOrders?.length > 0) {
setPurchaseOrderId(filterOrders[0]?.PurOrderInvoiceNo);
}
setPurchaseData(filterOrders);
if (unMappedProducts?.length > 0) {
setMessageType('error');
setMessageData(
`Please map the products that are not mapped with the selected supplier.`
);
}
};
const handleOrderTypeChange = (checked) => {
const isNewOrder = checked;
const supplierData = isNewOrder
? SupplierData?.find((supplier) => supplier?.SuppName === 'Self')?.SuppId
: null;
setOrderType(isNewOrder);
setSelectedInvoice(null);
setInvoiceNo(null);
setSearchText(null);
setSelectedSupplierName(!isNewOrder);
setSupplierOpen(isNewOrder ? 'own' : null);
setSelectedSupplierData(supplierData);
setPurchaseData([]);
setSelectedProductData(null);
setSelectedProductName(null);
setselectedProductVariantData(null);
setInvoiceType('I');
setPurchaseStatus('P');
setProductData([]);
handleSupplierBasedProduct(supplierData);
formRef?.current?.setFieldsValue({
InvoiceType: 'I',
PurchaseOrderNo: null,
SuppInvoiceNo: null,
CustSuppId: supplierData,
ProdId: null,
OrderType: isNewOrder ? 'N' : 'O',
VarProdId: null,
});
form?.resetFields();
};
useEffect(() => {
if (additionalInfoModal) {
productAddInfoRef?.current?.setFieldsValue({
ReceivedQty: selectedRowRecord?.ReceivedQty,
RejectedQty: selectedRowRecord?.RejectedQty,
AcceptedQty: selectedRowRecord?.AcceptedQty,
FreeItem: selectedRowRecord?.FreeItem,
OfferPrice: selectedRowRecord?.OfferPrice,
WhSalePrice: selectedRowRecord?.WhSalePrice,
SpecialPrice: selectedRowRecord?.SpecialPrice,
MRP: selectedRowRecord?.MRP,
SellPrice: selectedRowRecord?.SellPrice,
AmountPerPiece: selectedRowRecord?.AmountPerPiece,
NumberofPieceinside: selectedRowRecord?.NumberofPieceinside,
});
if (applicationRestrictedFields.BatchAndModelDetails) {
productAddInfoRef?.current?.setFieldsValue({
BatchRef: selectedRowRecord?.BatchRef,
ModelNumber: selectedRowRecord?.ModelNumber,
});
}
if (applicationRestrictedFields.DatesAndExpiry) {
productAddInfoRef?.current?.setFieldsValue({
ManufDate: selectedRowRecord?.ManufDate,
ExpDate: selectedRowRecord?.ExpDate,
});
}
}
}, [additionalInfoModal]);
// command
const handleRejectedQty = () => {
const formData = productAddInfoRef?.current?.getFieldsValue();
const rejectedQty =
formData?.RejectedQty === '' ? 0 : parseFloat(formData?.RejectedQty);
const receivedQty = parseFloat(formData.ReceivedQty)
? parseFloat(formData.ReceivedQty)
: 0;
let acceptedQty = receivedQty;
let newRejectedQty = 0;
if (isNaN(rejectedQty)) {
newRejectedQty = '';
} else if (rejectedQty >= receivedQty) {
setMessageType('error');
setMessageData(
'Rejected Qty cannot be greater than or Equal to Received Qty'
);
} else {
newRejectedQty = rejectedQty;
acceptedQty = receivedQty - rejectedQty;
}
let totalAmount =
acceptedQty * (parseFloat(selectedRowRecord?.InwardPrice) || 0);
setSelectedRowRecord((prev) => ({
...prev,
AcceptedQty: acceptedQty,
RejectedQty: newRejectedQty === '' ? 0 : newRejectedQty,
ProductIdentifierDtls: [],
Amount: totalAmount,
}));
productAddInfoRef?.current?.setFieldsValue({
RejectedQty: newRejectedQty === '' ? 0 : newRejectedQty,
AcceptedQty: acceptedQty,
});
};
const handleFreeQtyChange = (e) => {
const inputValue = e?.target?.value;
if (!/^\d*\.?\d*$/.test(inputValue)) {
setMessageType('error');
setMessageData('Only numeric values are allowed');
return;
}
const freeQty = inputValue === '' ? '' : parseFloat(inputValue);
setSelectedRowRecord((prev) => ({
...prev,
FreeItem: freeQty,
}));
};
const handleMRPChange = (e) => {
let value = e?.target?.value === '' ? 0 : parseFloat(e?.target?.value);
productAddInfoRef?.current?.setFieldsValue({ SellPrice: null, MRP: value });
setSelectedRowRecord((prev) => ({ ...prev, SellPrice: null, MRP: value }));
productAddInfoRef?.current?.validateFields();
};
const handleHSNChange = (e) => {
const value = e?.target?.value;
productAddInfoRef?.current?.setFieldsValue({ PurchaseHSNCode: value });
setSelectedRowRecord((prev) => ({ ...prev, PurchaseHSNCode: value }));
};
const validateSellPrice = (record) => (_, value) => {
if (!value) {
return Promise.reject('Selling Price is required');
}
if (!/^[1-9]\d*(\.\d+)?$/.test(value)) {
return Promise.reject('Please enter a valid selling price');
}
const mrp = record?.MRP;
// const mrp = productAddInfoRef?.current?.getFieldValue('MRP');
if (parseFloat(value) > parseFloat(mrp)) {
return Promise.reject(
'Please enter selling price less than or equal to MRP'
);
}
return Promise.resolve();
};
const handleAmountPerPiecechange = (e) => {
const inputValue = e?.target?.value;
const amountPerPiece = inputValue === '' ? '' : parseFloat(inputValue);
if (selectedRowRecord?.OnePcsAvailable === 'Y') {
setSelectedRowRecord((prev) => ({
...prev,
AmountPerPiece: amountPerPiece,
}));
}
};
const handleNumberofPieceinsidechange = (e) => {
const inputValue = e?.target?.value;
const numberOfPieceInside = inputValue === '' ? '' : parseFloat(inputValue);
if (selectedRowRecord?.OnePcsAvailable === 'Y') {
setSelectedRowRecord((prev) => ({
...prev,
NumberofPieceinside: numberOfPieceInside,
}));
}
};
const handleManufactureDate = (date, dateString) => {
const formattedDate =
dateString === ''
? undefined
: moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss');
productAddInfoRef?.current?.setFieldsValue({
ManufDate: date,
});
setSelectedRowRecord((prev) => ({ ...prev, ManufDate: formattedDate }));
};
const handleExpireDate = (date, dateString) => {
const formattedDate =
dateString === ''
? undefined
: moment(dateString, ['DD-MM-YYYY']).format('YYYY-MM-DDTHH:mm:ss');
productAddInfoRef?.current?.setFieldsValue({
ExpDate: date,
});
setSelectedRowRecord((prev) => ({ ...prev, ExpDate: formattedDate }));
};
const handleBatchRefChange = (e) => {
const value = parseInt(e?.target?.value);
if (!/^\d*\.?\d*$/.test(value)) {
return;
}
productAddInfoRef?.current?.setFieldsValue({
BatchRef: value,
});
setSelectedRowRecord((prev) => ({ ...prev, BatchRef: value }));
};
const handleModelNoChange = (e) => {
const value = parseInt(e?.target?.value);
if (!/^\d*\.?\d*$/.test(value)) {
return;
}
productAddInfoRef?.current?.setFieldsValue({
ModelNumber: value,
});
setSelectedRowRecord((prev) => ({ ...prev, ModelNumber: value }));
};
const handleAddtnlDtlsSubmit = async (values) => {
if (
selectedRowIndex == null ||
!Array.isArray(PurchaseData) ||
selectedRowIndex >= PurchaseData.length
) {
return;
}
const newData = { ...selectedRowRecord, ...values };
const updatedData = PurchaseData.map((item, index) =>
index === selectedRowIndex ? newData : item
);
console.log(updatedData, 'updatedData');
setPurchaseData(updatedData);
await handleAdditionalInfoClose();
};
const handleAdditionalInfoClose = async () => {
setAdditionalInfoModal(false);
setSelectedRowIndex(null);
setSelectedRowRecord({});
await productAddInfoRef?.current?.resetFields();
};
const handleModelDataOpen = () => {
const acceptedQty = parseInt(selectedRowRecord?.AcceptedQty) || 0;
const productIdentifiers = selectedRowRecord?.ProductIdentifierDtls || [];
let finalCombined = productIdentifiers.map((device, idx) => ({
key: idx,
column1: `Row ${idx + 1} Col 1`,
imei1: device?.IMEI1 || null,
imei2: device?.IMEI2 || null,
Macid: device?.MacId || null,
serialno: device?.SerialNumber || null,
}));
if (finalCombined.length > 0) {
if (finalCombined.length < acceptedQty) {
const rowsToAdd = acceptedQty - finalCombined.length;
for (let i = 0; i < rowsToAdd; i++) {
finalCombined.push({
key: finalCombined.length + i,
column1: `Row ${finalCombined.length + i + 1} Col 1`,
imei1: null,
imei2: null,
Macid: null,
serialno: null,
});
}
}
setDataSource(finalCombined);
setimeiSerialOpen(true);
} else {
if (acceptedQty > 0) {
if (dataSourceBackup.length === 0 || dataSource.length === 0) {
const newEmptyData = Array(acceptedQty)
.fill(null)
.map((_, index) => ({
key: index,
column1: `Row ${index + 1} Col 1`,
}));
setDataSource(newEmptyData);
} else {
setDataSource(dataSourceBackup);
}
setimeiSerialOpen(true);
} else {
setMessageType('error');
setMessageData('Enter Qty');
}
}
};
const handleModelDataSumbitOrClose = () => {
setimeiSerialOpen(false);
const productIdentifierDtls = dataSource
?.filter(
(item) => item.serialno || item.imei1 || item.imei2 || item.Macid
)
?.map((item) => ({
SerialNumber: item.serialno || '',
IMEI1: item.imei1 || '',
IMEI2: item.imei2 || '',
MacId: item.Macid || '',
}));
setSelectedRowRecord((prev) => ({
...prev,
ProductIdentifierDtls: productIdentifierDtls,
}));
};
const handleModalSubmited = () => {
setIsModalOpen(false);
};
const handleSupplierBasedProduct = async (SuppId) => {
const Type = SupplierData?.find((find) => find.SuppId === SuppId)?.Type;
const LocationType =
Type === 'Supplier'
? 'S'
: Type === 'Branch'
? 'B'
: Type === 'WareHouse'
? 'W'
: '';
const productResponse = await dispatch(
getSupplaierIdwithTypeBasedProducts({
CompId,
AppId,
BranchId,
SuppId,
LocationType,
})
).unwrap();
setPurchaseData([]);
if (productResponse?.data?.statusCode === 1) {
setProductData(productResponse?.data?.data);
return productResponse?.data?.data;
} else {
setProductData([]);
return [];
}
};
const validatePhoneNumber = (rule, value, callback) => {
if (value && value?.length !== 10) {
callback();
} else {
callback();
}
};
const validateEmail = (rule, value, callback) => {
const regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (!value || regex.test(value)) {
callback();
} else {
callback('Please enter a valid Mail Id');
}
};
const deliveryPerformance = async () => {
let response = await dispatch(
getConfigType({ TypeName: 'Delivery Performance' })
).unwrap();
SetDeleveryPerformanceData(response?.data?.data);
};
const discountLevel = async () => {
let response = await dispatch(
getConfigType({ TypeName: 'Discount Level' })
).unwrap();
setDiscountData(response?.data?.data);
};
const qualityofSupp = async () => {
let response = await dispatch(
getConfigType({ TypeName: 'Quality Of Supplier' })
).unwrap();
setQualityData(response?.data?.data);
};
const handleDeliveryPerformanceChange = (value) => {
formSupplierRef?.current?.setFieldsValue({ DeliveryPerformance: value });
setDeliveryValue(value);
};
const handleDiscountLevelChange = (value) => {
formSupplierRef?.current?.setFieldsValue({ DiscountLevel: value });
setDicountValue(value);
};
const handleQualityofSuppChange = (value) => {
formSupplierRef?.current?.setFieldsValue({ QualityofSupp: value });
setQualityValue(value);
};
const ViewMoreFields = () => setViewDtl((prev) => !prev);
const handlePaymentModeChange = (modeId) => {
setPayAmountDisable(
paymentOptions
?.find((option) => option?.ModeId === modeId)
?.ModeName?.toLowerCase() === 'credit'
);
setSelectedPaymentMode(modeId);
formRef.current?.setFieldsValue({ PaymentMode: modeId });
};
return (
<div className="pageOverAll" style={{ position: 'relative' }}>
{isLoading && (
<div className="loading-overlay">
<div className="loading-spinner" />
{loadingText && <div className="loading-text">{loadingText}</div>}
</div>
)}
<div className="userPage">
<div className="userPageContent">
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div className="purchase-entry-fh">
<div
className="formName"
style={{
flexWrap: 'wrap',
gap: '10px',
justifyContent: 'space-between',
}}
>
<FormHeader title={'Product Receipt'} />
{/* <div className="prurachseViewBtn" style={{ backgroundColor: '#25D366', }}>
<button onClick={() => navigate(`${subDirectory}setting/purchase-entry`)}> <FaEye size={18} />
View Entry List</button>
</div> */}
<div
className="header-buttons"
style={{ flexWrap: 'wrap', width: 'unset' }}
>
<div
className="pruchaseCatBTN scan-receipt-btn"
onClick={() => setExtractorModalVisible(true)}
>
<FaUpload size={18} /> <p> Scan Receipt (Auto-Fill)</p>
</div>
<div
className="pruchaseCatBTN"
onClick={() =>
navigate(`${subDirectory}setting/purchase-entry`)
}
>
<FaEye size={18} /> <p> View Entry List</p>
</div>
</div>
</div>
</div>
<div className="formDiv">
<Form
ref={formRef}
initialValues={editstate}
className="formDivAnt"
onFinish={onFinish}
>
<div className="purchase-entry-form">
<div className="formDivS">
<div className="purchase-entry-dtls">
<div className="pe-inward-date">
<label className="required">Inward Date</label>
<br />
<Form.Item
name={'InvoiceDate'}
rules={[
{
required: true,
message: 'Please Select Inward Date',
},
]}
>
<DatePicProd
canSelectPast={true}
onChange={handleInwardDateChange}
valueData={inwardDate}
disabled={formType == 'edit' ? true : false}
cancelFuture={true}
/>
</Form.Item>
</div>
<Form.Item
name="OrderType"
rules={[
{
required: true,
message: 'Please Select Order Type',
},
]}
>
<div className="switch-order-type">
<div className="switch-header required">Order Type</div>
<Switch
checked={orderType}
onChange={handleOrderTypeChange}
checkedChildren="New Order"
unCheckedChildren="Pending Orders"
/>
</div>
</Form.Item>
</div>
<div className="inputForm">
<div className="purchaseDetails">
<div className="supplierInfo">
<h2 className="supplier-dtls">Supplier Details</h2>
<div className="supplierInfo1">
{!orderType && (
<Form.Item
name="PurchaseOrderNo"
rules={[
{
required: true,
message: 'Please Select Purchase Order No.',
},
]}
>
<FloatLabel
label={
<label class="required">
Purchase Order No.
</label>
}
isOnChange={searchText ? true : false}
>
<AutoComplete
style={{ width: '180px' }}
options={filteredOptions}
className="supplier-invoice-select"
autoComplete="off"
allowClear
value={searchText}
onSelect={handleInvoiceSelect}
onSearch={handleInvoiceSearch}
filterOption={(inputValue, option) =>
option.label
?.toLowerCase()
.includes(inputValue?.toLowerCase())
}
/>
</FloatLabel>
</Form.Item>
)}
<Form.Item
name="CustSuppId"
rules={[
{
required: true,
message: 'Please Select Supplier',
},
]}
>
<DropDowns
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})`,
}))
: []
}
label={<label class="required">Supplier</label>}
className="field-DropDown"
onChangeFunction={handleSupplierDropDownChange}
valueData={selectedSupplierData}
disabled={
editstate?.SuppId
? true
: !orderType
? true
: false
}
/>
<Tooltip title="Add Supplier" placement="top">
<PlusCircleOutlined
className="product-add-iconMargin"
onClick={addSupplier}
/>
</Tooltip>
</Form.Item>
{!selectedSupplierName && (
<RadioGrpButton
content={[
{ value: 'own', label: 'Own' },
{ value: 'paid', label: 'With paid' },
]}
fieldState={true}
defaultSelect={SupplierOpen}
// Header={"Stock Available"}
onSelectFuntion={(e) => SupplierOpenfun(e)}
/>
)}
</div>
<div className="supplierInfo2">
{(SupplierOpen !== 'own' || selectedSupplierName) &&
selectedSupplierData && (
<>
<Form.Item name={'InvoiceType'}>
<RadioGrpButton
content={[
{ value: 'I', label: 'Invoice' },
{
value: 'DC',
label: 'Delivery Challan',
},
]}
defaultSelect={invoiceType}
onSelectFuntion={handleInvoiceTypeChange}
/>
</Form.Item>
<Form.Item
name="SuppInvoiceNo"
rules={[
{
required: true,
// pattern:/^[1-9]\d*(\.\d+)?$/,
message:
invoiceType === 'I'
? 'Please Enter Invoice Number'
: 'Please Enter Delivery Challan',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value?.length > 30) {
if (invoiceType === 'I') {
return Promise.reject(
'Invoice Number cannot exceeds more than 30 chars'
);
}
return Promise.reject(
'Delivery Challan cannot exceeds more than 30 chars'
);
}
return Promise.resolve();
},
},
]}
>
<div className="stock-input">
<InputField
autoComplete="off"
label={
<label class="required">
{invoiceType === 'I'
? 'Supplier Invoice Number'
: 'Delivery Challan No.'}
</label>
}
onChange={handleSuppInvoiceNoChange}
isOnChange={
extractorData?.invoiceNo ? true : false
}
value={extractorData?.invoiceNo}
/>
</div>
</Form.Item>
<Form.Item name="SuppInvoiceDate">
<div className="supplier-invoice-date">
<label className="required">
{invoiceType === 'I'
? 'Supplier Invoice Date'
: 'Delivery Challan Date'}
</label>
<DatePicProd
canSelectPast={true}
onChange={onSuppInvoiceDateChange}
valueData={SuppInvoiceDate}
disabled={
formType == 'edit' ? true : false
}
cancelFuture={true}
/>
</div>
</Form.Item>
</>
)}
</div>
</div>
{(SupplierOpen !== 'own' || selectedSupplierName) &&
selectedSupplierData && (
<div className="invoiceDetails">
<>
<Form.Item
name="PaymentType"
rules={[
{
required: true,
message: 'Please Select Pruchase Type ',
},
]}
>
<DropDowns
options={PurchaseTypeData?.map((option) => ({
value: option.ConfigId,
label:
option.ConfigName === 'Cash'
? 'Paid'
: option.ConfigName,
}))}
label={
<label class="required">Payment Type</label>
}
className="field-DropDown"
onChangeFunction={handlePurchaseTypeChange}
valueData={SelectedPurchaseType}
disabled={editstate?.SuppId ? true : false}
/>
</Form.Item>
{PurchaseTypeData?.some(
(item) =>
item.ConfigId === SelectedPurchaseType &&
item.ConfigName === 'Cash'
) && (
<>
<Form.Item
name="PaymentMode"
rules={[
{
required: true,
message: 'Please Select Payment Mode',
},
]}
>
<DropDowns
options={paymentOptions?.map((mode) => ({
value: mode.ModeId,
label: mode.ModeName,
}))}
label={
<label className="required">
Payment Mode
</label>
}
className="field-DropDown"
onChangeFunction={handlePaymentModeChange}
valueData={selectedPaymentMode}
/>
</Form.Item>
<Form.Item
name="PaymentAmount"
rules={[
{
required: true,
message: 'Please enter Payment Amount',
},
{
validator: (_, value) => {
if (
value === undefined ||
value === null ||
value === ''
) {
return Promise.resolve();
}
if (Number(value) === 0) {
return Promise.reject(
'Payment Amount cannot be 0'
);
}
if (
isNaN(value) ||
Number(value) < 0
) {
return Promise.reject(
'Payment Amount cannot be less than 0'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={
<label className="required">
Payment Amount
</label>
}
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);
}}
/>
</Form.Item>
</>
)}
<Form.Item name="DueDate">
<label className="required">Due Date</label>
<br />
<DatePicProd
canSelectPast={true}
onChange={onPurchaseDateChange}
valueData={PurchaseDate}
disabled={formType == 'edit' ? true : false}
cancelFuture={false}
/>
</Form.Item>
</>
</div>
)}
</div>
<div className="stockDiv">
<Form.Item name="ProdId">
<div className="product-scan">
<FloatLabel
label={'Product Name'}
value={selectedProductName}
>
<AutoComplete
className="field-DropDown"
value={selectedProductName}
filterOption={(input, option) => {
const product = productData.find(
(p) => p.ProdId === option.value
);
const nameMatch = option.label
?.toLowerCase()
.includes(productSearchText?.toLowerCase());
const qrMatch =
product?.QRCode?.toLowerCase() ==
productSearchText?.toLowerCase();
return nameMatch || qrMatch;
}}
options={
!scanner
? productData?.map((option) => ({
value: option.ProdId,
label: `${option.ProdName} (${option.Size} ${option.UomName})${option?.BrandName ? ` - ${option?.BrandName}` : ''}`,
}))
: []
}
onSelect={async (value, option) => {
const newProduct = await ProductDropDownChange(
value,
option
);
if (newProduct) {
form?.setFieldsValue({
[`SellPrice${newProduct?.localId}`]:
newProduct?.SellPrice,
[`PurchaseTax${newProduct?.localId}`]:
newProduct?.PurchaseTax,
});
setPurchaseData([
newProduct,
...PurchaseData,
]);
}
}}
onChange={handleProductSearch}
onKeyDown={(e) => {
if (scanner && e.key === 'Enter') {
e.preventDefault();
}
}}
style={{ width: '250px' }}
></AutoComplete>
</FloatLabel>
<Tooltip title={'BarCode/QrCode'} placement={'top'}>
<BsUpcScan
strokeWidth={0.5}
color="#000"
style={{
fontSize: '16px',
color: scanner ? '#52c41a' : '#888',
fontWeight: '600',
}}
className="product-scan-Icon"
onClick={handleScanSearch}
/>
</Tooltip>
</div>
{/* <Tooltip
title='Add Product'
placement="top"
>
<PlusCircleOutlined className='product-add-iconMargin'
onClick={addProduct}
/>
</Tooltip> */}
<Tooltip
title={'Supplier Product Mapping'}
placement={'top'}
>
<FaLink onClick={() => setIsModalOpen(true)} />
</Tooltip>
</Form.Item>
{isModalOpen && (
<SupplierProductMappingForm
isModalOpen={isModalOpen}
setIsModalOpen={() => {
(setIsModalOpen(false),
handleSupplierDropDownChange(
selectedSupplierData
));
}}
CompId={CompId}
BranchId={BranchId}
AppId={AppId}
setMessage={setMessage}
onMappingAdded={handleModalSubmited}
/>
)}
{Variants?.length > 1 && (
<Form.Item name="VarProdId">
<DropDowns
options={Variants?.map((option) => ({
value: option.ProdIdProdName,
label: option.ProdVariantName,
}))}
label={'Variant Name'}
className="field-DropDown"
onChangeFunction={(e) =>
ProductVariantDropDownChange(e)
}
valueData={selectedProductVariantData}
disabled={editstate?.ProdId ? true : false}
/>
{/* <Tooltip
title='Add Product'
placement="top"
>
<PlusCircleOutlined className='product-add-iconMargin'
onClick={addProduct}
/>
</Tooltip> */}
</Form.Item>
)}
</div>
<div
className="Product-table stockformTabele"
style={{
maxwidth: '500px',
overflowX: 'auto',
scrollbarWidth: 'thin',
}}
>
<Form form={form} component={false}>
<Table
className="purchase-receipt-table"
bordered
dataSource={PurchaseData}
columns={columns}
rowClassName="editable-row"
onRow={(record, index) => ({
onClick: () => {
edit(record, index);
},
})}
pagination={false}
/>
</Form>
</div>
{PurchaseData?.length > 0 && (
<div className="purchase-status-data">
<div className="total-purchase-amnt">
<label>Total Amount:&nbsp;</label>
<div>
{PurchaseData.reduce(
(acc, data) => acc + data?.Amount,
0
)}
2026-01-27 18:27:29 +05:30
</div>
</div>
{!orderType && (
<div className="purchase-status">
<RadioGrpButton
content={[
{ value: 'P', label: 'Pending' },
{ value: 'C', label: 'Completed' },
]}
Header={'Purchase Status'}
defaultSelect={purchaseStatus}
onSelectFuntion={purchaseStatusChange}
/>
</div>
)}
</div>
)}
</div>
</div>
</div>
<div className="submitButtonDiv">
<Buttons
buttonText="SUBMIT"
color="901D77"
icon={<ArrowRightOutlined />}
/>
</div>
</Form>
</div>
</div>
<DefaultModal
title="Add Supplier"
open={OpenSupplierModel}
footer={true}
buttonText="Submit"
children={
<Form ref={formSupplierRef} className="formDivAnt">
<div className="subRowFlex">
<Form.Item
name="SuppName"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Supplier Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value?.length > 30) {
return Promise.reject(
'Supplier Name cannot exceeds more than 30 chars'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={<label class="required">Supplier Name</label>}
autocomplete="off"
/>
</Form.Item>
<Form.Item
name="Address1"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Address1',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Address</label>}
/>
</Form.Item>
<Form.Item
name="Zip"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Zipcode',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Zipcode</label>}
maxLength="6"
onChange={pinCodeChange}
/>
</Form.Item>
<p
style={{ color: '#1292ee', justifyContent: 'end' }}
onClick={ViewMoreFields}
>
{' '}
{ViewDtl ? 'Less More' : 'View More'}
</p>
{ViewDtl && (
<>
<Form.Item
name="SuppGSTIN"
rules={[
{
pattern:
/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9A-Za-z]{1}$/,
message: 'Enter a valid GSTIN',
},
]}
>
<InputField
style={{ textTransform: 'uppercase' }}
autoComplete="off"
label="GST No"
autocapitalize="on"
// isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="SuppMobile"
rules={[
{
pattern: /^\d{10}$/,
message: 'Please Enter a Valid Mobile Number',
},
{ validator: validatePhoneNumber },
]}
>
<InputField
label={<label>Mobile Number</label>}
maxLength="10"
autocomplete="off"
// isOnChange={formType == 'edit' ? true : false}
inputMode="numeric"
onInput={(e) =>
(e.target.value = e.target.value.replace(
/[^0-9]/g,
''
))
}
/>
</Form.Item>
<Form.Item
name="SuppEmail"
rules={[{ validator: validateEmail }]}
>
<InputField
label={<label>MailId</label>}
autocomplete="off"
// isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="SuppPOC"
rules={[
{
pattern: /^(?!\s*$).+/,
message: 'Please Enter Point of Contact Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value?.length > 30) {
return Promise.reject(
'Point of Contact cannot exceeds more than 30 chars'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={<label class="">Point of Contact</label>}
autocomplete="off"
// isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="SuppPOCMobile"
rules={[
{
pattern: /^\d{10}$/,
message: 'Please Enter a Valid Mobile Number',
},
{
// required: true,
message: 'Please Enter Mobile Number',
},
{ validator: validatePhoneNumber },
]}
>
<InputField
label={<label class="">POC Mobile Number</label>}
autocomplete="off"
maxLength="10"
// isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="SuppPOCEmail"
rules={[{ validator: validateEmail }]}
>
<InputField
label={<label class="">POC MailId</label>}
autocomplete="off"
// isOnChange={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="DeliveryPerformance"
rules={[
{
required: false,
message: 'Please Select DeliveryPerformance',
},
]}
>
<DropDowns
options={deliveryPerformanceData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label>Delivery Performance</label>}
className="field-DropDown"
id="DeliveryPerformance"
onChangeFunction={(e) =>
handleDeliveryPerformanceChange(e)
}
// isOnChange={formType == 'edit' ? true : false}
valueData={Delivery}
/>
</Form.Item>
<Form.Item
name="DiscountLevel"
rules={[
{
required: false,
message: 'Please Select DiscountLevel',
},
]}
>
<DropDowns
options={DiscountData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label>Discount Level</label>}
className="field-DropDown"
id="DiscountLevel"
onChangeFunction={(e) => handleDiscountLevelChange(e)}
// isOnChange={formType == 'edit' ? true : false}
valueData={DicountValue}
/>
</Form.Item>
<Form.Item
name="QualityofSupp"
rules={[
{
required: false,
message: 'Please Select QualityofSupp',
},
]}
>
<DropDowns
options={QualityData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label>Quality of Supplier</label>}
className="field-DropDown"
id="QualityofSupp"
onChangeFunction={(e) => handleQualityofSuppChange(e)}
// isOnChange={formType == 'edit' ? true : false}
valueData={QualityValue}
/>
</Form.Item>
</>
)}
{zipCodeData ? (
<>
<Form.Item
name="City"
rules={[
{
required: true,
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
disabled={true}
isOnChange={true}
label="City"
/>
</Form.Item>
<Form.Item
name="Dist"
rules={[
{
required: true,
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
disabled={true}
isOnChange={true}
label="District"
/>
</Form.Item>
<Form.Item
name="State"
rules={[
{
required: true,
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
disabled={true}
isOnChange={true}
label="State"
/>
</Form.Item>
</>
) : (
''
)}
</div>
</Form>
}
handleSubmit={submitSupplier}
handleCancel={handleSupplier}
></DefaultModal>
<div>
<DefaultModal
open={AddProductDetail}
width={800}
footer={false}
title={'Add Product'}
children={
<Form
ref={formProductRef}
className="formDivAnt"
onFinish={onProductFinish}
>
<div className="subRowFlex">
<Form.Item
name="ProdName"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Product Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 50) {
return Promise.reject(
'Product Name should not exceed 50 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Product Name</label>}
// isOnChange={(editstate?.ProdName || QrcodeExistsData?.[0]?.ProdName) ? true : false}
onChange={(e) => setProductName(e?.target?.value)}
/>
</Form.Item>
<Form.Item
name="Size"
rules={[
{
required: true,
// pattern: /^[1-9]\d*(\.\d+)?$/,
message: 'Please Enter Quantity',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">Quantity</label>}
// isOnChange={(editstate?.Size || QrcodeExistsData?.[0]?.Size) ? true : false}
suffix={
<Tooltip title="Per Unit(eg: 1 kg,1 piece,500 g)">
<InfoCircleOutlined
style={{
color: 'rgba(0,0,0,.45)',
}}
/>
</Tooltip>
}
/>
</Form.Item>
<Form.Item
name="UOM"
rules={[
{
required: true,
message: 'Please Select Uom',
},
]}
>
<DropDowns
options={UomData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Uom</label>}
className="field-DropDown"
// isOnchanges={(editstate?.UOM || SelectedUom)?true:false}
onChangeFunction={handleUomDropDownChange}
valueData={SelectedUom}
disabled={formType == 'edit' ? true : false}
/>
</Form.Item>
<Form.Item
name="MRP"
rules={[
{
required: true,
pattern: /^[1-9]\d*(\.\d+)?$/,
message: 'Please Enter MRP',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label class="required">MRP</label>}
// isOnChange={(editstate?.MRP || QrcodeExistsData?.[0]?.MRP) ? true : false}
onChange={handleMRP}
/>
</Form.Item>
<Form.Item
name="SellPrice"
rules={[
{
required: true,
pattern: /^[1-9]\d*(\.\d+)?$/,
message: 'Please enter retail',
},
{ validator: handleSellPrice },
]}
>
<InputField
autoComplete="off"
label={<label class="required">Sales Price</label>}
// isOnChange={(editstate?.SellPrice || QrcodeExistsData?.[0]?.SellPrice)? true : false}
/>
</Form.Item>
<Form.Item
name="ProdCat"
// rules={[
// {
// // required: true,
// message:"Please Select Category"
// },
// ]}
>
<DropDowns
options={ProdCatData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Category</label>}
className="field-DropDown"
// isOnchanges={(editstate?.ProdCat || SelectedProdCat)?true:false}
onChangeFunction={handleProdCatDropDownChange}
valueData={SelectedProdCat}
disabled={
editstate?.ProdTypeName == 'Others' || formType == 'add'
? false
: true
}
/>
<Tooltip title="Add Category" placement="top">
<PlusCircleOutlined
className="product-add-iconMargin"
onClick={addCategory}
/>
</Tooltip>
</Form.Item>
<Form.Item name="ProdSubCat">
<DropDowns
options={ProdSubCatData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label>SubCategory</label>}
className="field-DropDown"
// isOnchanges={(editstate?.ProdSubCat || SelectedProdSubCat)?true:false}
onChangeFunction={handleProdSubCatDropDownChange}
valueData={SelectedProdSubCat}
disabled={
editstate?.ProdTypeName == 'Others' || formType == 'add'
? false
: true
}
/>
<Tooltip title="Add Sub-Category" placement="top">
<PlusCircleOutlined
className="product-add-iconMargin"
onClick={addSubCategory}
/>
</Tooltip>
</Form.Item>
<Form.Item name="Brand">
<DropDowns
options={BrandData?.map((option) => ({
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}
/>
<Tooltip title="Add Brand" placement="top">
<PlusCircleOutlined
className="product-add-iconMargin"
onClick={addBrand}
/>
</Tooltip>
</Form.Item>
<div className="productcollapse1">
<Collapse defaultActiveKey={expandCollapseActive}>
<Panel header="Qrcode and Token" key="1">
<div className="Qrcodediv">
<div>
<RadioGrpButton
content={[
{ value: 'Y', label: 'Yes' },
{ value: 'N', label: 'No' },
]}
fieldState={true}
defaultSelect={StockOpen}
Header={'Stock Available'}
onSelectFuntion={(e) => openStock(e)}
/>
</div>
<div>
<RadioGrpButton
content={[
{ value: 'Y', label: 'Yes' },
{ value: 'N', label: 'No' },
]}
fieldState={true}
defaultSelect={TokenOpen}
Header={'Token Available'}
onSelectFuntion={(e) => openToken(e)}
/>
</div>
<div>
<RadioGrpButton
content={[
{ value: 'Y', label: 'Yes' },
{ value: 'N', label: 'No' },
]}
fieldState={true}
defaultSelect={QrcodeAuto}
Header={'Auto Generate Qrcode'}
onSelectFuntion={(e) => openQrcodeAuto(e)}
disabled={editstate?.QRCode ? true : false}
/>
</div>
<div>
<RadioGrpButton
content={[
{ value: 'Y', label: 'Yes' },
{ value: 'N', label: 'No' },
]}
fieldState={true}
defaultSelect={AmountPerPieceAvailable}
Header={'Amount Per Piece'}
onSelectFuntion={(e) =>
openAmountPerPieceAvailable(e)
}
// disabled={editstate?.QRCode ? true : false}
/>
</div>
{(QrcodeAuto == 'N' || editstate?.QRCode) && (
<div className="scannerdiv">
<img
src={barcodeimg}
style={{ height: '50px' }}
></img>
<Form.Item
name="QRCode"
rules={[
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<ScannerInputField
autoComplete="off"
label="Scanner / AddQrcode"
onKeyPress={handleKeyPress}
valueData={QrcodeFinalVal}
isOnChange={QrcodeFinalVal ? true : false}
onChange={handleInput}
disabled={editstate?.QRCode ? true : false}
/>
{QrcodeExistsVal && QrcodeExistsVal}
</Form.Item>
</div>
)}
{AmountPerPieceAvailable == 'Y' && (
<>
<Form.Item
name="OnePcsPrice"
rules={[
{
pattern: /^[1-9]\d*(\.\d+)?$/,
message:
'Please Enter Valid Amount for Piece',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label="Amount Per Piece"
isOnChange={
editstate?.OnePcsPrice ? true : false
}
/>
</Form.Item>
<div>
<RadioGrpButton
content={[
{ value: 'Y', label: 'Yes' },
{ value: 'N', label: 'No' },
]}
fieldState={true}
defaultSelect={QrcodeAutoSingle}
Header={'Auto Generate One Piece Qrcode'}
onSelectFuntion={(e) =>
openQrcodeAutoSingle(e)
}
disabled={editstate?.OnePcQR ? true : false}
/>
</div>
{(QrcodeAutoSingle == 'N' ||
editstate?.OnePcQR) && (
<div className="scannerdiv">
<img
src={barcodeimg}
style={{ height: '50px' }}
></img>
<Form.Item
name="OnePcQR"
rules={[
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<ScannerInputField
autoComplete="off"
label="Scanner / AddOnePcQrcode"
onKeyPress={handleKeyPressSingle}
valueData={QrcodeSingleFinalVal}
isOnChange={
QrcodeSingleFinalVal ? true : false
}
onChange={handleInputSingle}
// disabled={editstate?.OnePcQR ? true : false}
/>
{QrcodeSingleExistsVal &&
QrcodeSingleExistsVal}
</Form.Item>
</div>
)}
</>
)}
{StockOpen == 'Y' &&
AmountPerPieceAvailable == 'Y' && (
<Form.Item
name="NoOfPcs"
rules={[
{
pattern: /^[1-9]\d*(\.\d+)?$/,
message:
'Please Enter Valid Number Of Piece',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label="Number of Piece inside"
// isOnChange={editstate?.NoOfPcs ? true : false}
/>
</Form.Item>
)}
</div>
</Panel>
</Collapse>
</div>
{OpenAdd && (
<>
<Form.Item name="TaxId">
<DropDowns
options={TaxData?.map((option) => ({
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}
/>
<Tooltip title="Add Tax" placement="top">
<PlusCircleOutlined
className="product-add-iconMargin"
onClick={addTax}
/>
</Tooltip>
</Form.Item>
<Form.Item
name="Cess"
rules={[
{
pattern: /^\d*\.?\d+$/,
message: 'Please Enter Cess',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField autoComplete="off" label="Cess" />
</Form.Item>
<Form.Item
name="HSNCode"
rules={[
{
pattern: /^(?!\s*$).+/,
message: 'Please Enter HSN',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField autoComplete="off" label="HSN" />
</Form.Item>
<Form.Item
name="WhSalePrice"
rules={[
{
pattern: /^[0-9]\d*(\.\d+)?$/,
message: 'Please Enter WholeSale',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label>WholeSale</label>}
/>
</Form.Item>
<Form.Item
name="splSalePrice"
rules={[
{
pattern: /^[0-9]\d*(\.\d+)?$/,
message: 'Please Enter Special Price',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label>splSale</label>}
/>
</Form.Item>
<Form.Item
name="offerSalePrice"
rules={[
{
pattern: /^[0-9]\d*(\.\d+)?$/,
message: 'Please Enter Offer Sale',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label>offerSale</label>}
/>
</Form.Item>
</>
)}
</div>
<div className="prodAddDetails" onClick={openAdditionalDetails}>
Additional Details
</div>
<div
className="submitButtonDiv"
style={{ display: 'flex', justifyContent: 'flex-end' }}
>
<Buttons
buttonText="SUBMIT"
color="901D77"
icon={<ArrowRightOutlined />}
htmlType={true}
/>
</div>
</Form>
}
handleCancel={handleQuickAddCancel}
/>
<DefaultModal
title="Add Category"
open={OpenCategoryModel}
footer={true}
buttonText="Submit"
children={
<Form ref={formCategoryRef} className="formDivAnt">
<div className="subRowFlex">
<div className="subColumnFlex">
<div>
<Form.Item
name="ConfigName"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Config Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 50) {
return Promise.reject(
'Config Name should not exceed 50 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={<label class="required">Config Name</label>}
autocomplete="off"
/>
</Form.Item>
</div>
</div>
<div className="subColumnFlex">
<div className="upload_btn">
<p>Upload Icon</p>
<br></br>
<Imageupload
singleImage={true}
updateImageUrl={updateCategoryImageUrl}
ImageLink={imageCategoryUrl ? imageCategoryUrl : ''}
/>
</div>
</div>
</div>
</Form>
}
handleSubmit={submitCategory}
handleCancel={handleCategory}
></DefaultModal>
<DefaultModal
title="Add Sub-Category"
open={OpenSubCategoryModel}
footer={true}
buttonText="Submit"
handleSubmit={submitSubCategory}
handleCancel={handleSubCategory}
children={
<Form ref={formSubCategoryRef} className="formDivAnt">
<div className="subRowFlex">
<div className="subColumnFlex">
<div className="subProdCatData">
<Form.Item
name="CategoryId"
rules={[
{
required: true,
message: 'Please Select Category',
},
]}
>
<DropDowns
options={ProdCatData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Category</label>}
className="field-DropDown"
onChangeFunction={handleCatDropDownChange}
valueData={SelectedCategory}
/>
</Form.Item>
<div className="upload_btn">
<p>Upload Icon</p>
<br></br>
<Imageupload
singleImage={true}
updateImageUrl={updateSubCategoryImageUrl}
ImageLink={
imageSubCategoryUrl ? imageSubCategoryUrl : ''
}
/>
</div>
</div>
</div>
<div className="subColumnFlex">
<div>
<Form.Item
name="SubConfigName"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Config Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 50) {
return Promise.reject(
'Config Name should not exceed 50 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={<label class="required">Config Name</label>}
autocomplete="off"
/>
</Form.Item>
</div>
</div>
</div>
</Form>
}
></DefaultModal>
<DefaultModal
title="Add Brand"
open={OpenBrandModel}
footer={true}
buttonText="Submit"
handleSubmit={submitBrand}
handleCancel={handleBrand}
children={
<Form ref={formBrandRef} className="formDivAnt">
<div className="subRowFlex">
<div className="subColumnFlex">
<div className="subProdCatData">
<Form.Item
name="SubCategoryId"
rules={[
{
required: true,
message: 'Please Select Sub-Category',
},
]}
>
<DropDowns
options={ProdSubCatData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label={<label class="required">Sub-Category</label>}
className="field-DropDown"
onChangeFunction={handleSubCatDropDownChange}
valueData={SelectedSubCategory}
/>
</Form.Item>
<div className="upload_btn">
<p>Upload Icon</p>
<br></br>
<Imageupload
singleImage={true}
updateImageUrl={updateBrandImageUrl}
ImageLink={imageBrandUrl ? imageBrandUrl : ''}
/>
</div>
</div>
</div>
<div className="subColumnFlex">
<div>
<Form.Item
name="SubConfigName"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Config Name',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value && value.length > 50) {
return Promise.reject(
'Config Name should not exceed 50 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={<label class="required">Config Name</label>}
autocomplete="off"
/>
</Form.Item>
</div>
</div>
</div>
</Form>
}
></DefaultModal>
<DefaultModal
title="Add Tax"
open={OpenTaxModel}
footer={true}
buttonText="Submit"
children={
<Form ref={formTaxRef} className="formDivAnt">
<div className="subRowFlex">
<Form.Item name="TaxName">
<DropDowns
options={ProdTaxData?.map((option) => ({
value: option.ConfigId,
label: option.ConfigName,
}))}
label="Tax Name"
className="field-DropDown"
onChangeFunction={handleTaxNameDropDownChange}
valueData={SelectedTaxNameId}
/>
</Form.Item>
<Form.Item
name="TaxPercentage"
rules={[
{
required: true,
pattern: /^(?:100(?:\.0+)?|\d{1,2}(?:\.\d+)?)$/,
message: 'Please Enter Valid Percentage',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField autoComplete="off" label="Tax Percentage" />
</Form.Item>
<Form.Item
name="Reference"
rules={[
{
pattern: /^(?!\s*$).+/,
message: 'Please Enter Reference',
},
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField label="Reference No" autoComplete="off" />
</Form.Item>
<div>
<label className="required">Effective From :</label>
</div>
<Form.Item
name="EffectiveFrom"
rules={[
{
required: true,
message: 'Please Enter Effective From',
},
]}
>
<DatePic
field="EffectiveFrom"
type="number"
min={1}
max={100}
fieldState={true}
/>
</Form.Item>
</div>
</Form>
}
handleSubmit={submitTax}
handleCancel={handleTax}
></DefaultModal>
<DefaultModal
title="IMEI /Serial Number / Mac Id"
open={imeiSerialOpen}
footer={true}
buttonText="Submit"
children={
<div>
<Table
components={components}
rowClassName={() => 'editable-row'}
bordered
dataSource={dataSource}
columns={IMEIcolumns}
pagination={{ showSizeChanger: false }}
/>
</div>
}
handleSubmit={handleModelDataSumbitOrClose}
handleCancel={handleModelDataSumbitOrClose}
></DefaultModal>
<DefaultModal
open={additionalInfoModal}
className={'additional-dtls-modal'}
footer={false}
children={
<>
<h3>{`${selectedRowRecord?.ProdName} (${selectedRowRecord?.ProdVariantName})`}</h3>
<Form ref={productAddInfoRef} onFinish={handleAddtnlDtlsSubmit}>
<div className="product-qty-info">
<Form.Item name="ReceivedQty">
<InputField
isOnChange={selectedRowRecord}
valueData={selectedRowRecord?.ReceivedQty}
label={'Received Qty'}
disabled={true}
/>
</Form.Item>
<Form.Item name="RejectedQty">
<InputField
isOnChange={selectedRowRecord}
value={selectedRowRecord?.RejectedQty}
onChange={handleRejectedQty}
label={'Rejected Qty'}
inputMode="decimal"
onInput={(e) => {
let cleanedValue = e.target.value.replace(
/[^0-9.]/g,
''
);
const parts = cleanedValue.split('.');
if (cleanedValue.startsWith('.')) {
cleanedValue = '0' + cleanedValue;
}
e.target.value =
parts.length > 2
? `${parts[0]}.${parts.slice(1).join('')}`
: cleanedValue;
}}
/>
</Form.Item>
<Form.Item name="AcceptedQty">
<InputField
autoComplete="off"
isOnChange={selectedRowRecord}
value={selectedRowRecord?.AcceptedQty}
label={'Accepted Qty'}
disabled={true}
/>
</Form.Item>
<Form.Item
name="FreeItem"
rules={[
{
validator: (_, value) => {
if (
value === undefined ||
value === null ||
value === ''
) {
return Promise.resolve();
}
if (!/^[0-9]\d*(\.\d+)?$/.test(value)) {
return Promise.reject(
'Please enter a valid FreeQty'
);
}
if (value.toString().length > 10) {
return Promise.reject(
'FreeQty cannot exceed more than 10 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
isOnChange={selectedRowRecord}
value={selectedRowRecord?.FreeItem}
label={'Free Qty'}
onChange={handleFreeQtyChange}
/>
</Form.Item>
</div>
<Form.Item
name={'PurchaseHSNCode'}
rules={[
{
validator: (_, value) => {
if (value === undefined || value === '')
return Promise.resolve();
if (value.length > 30) {
return Promise.reject(
'HSN cannot exceed 30 characters'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label="HSN"
isOnChange={
selectedRowRecord?.PurchaseHSNCode !== '' ? true : false
}
value={selectedRowRecord?.PurchaseHSNCode}
onChange={handleHSNChange}
/>
</Form.Item>
<div className="collapse-data">
<div className="pricing-dtls">
<Collapse defaultActiveKey={['1']}>
<Panel header="Pricing Details" key="1">
<div className="pricing-dtl-fields">
<Form.Item
name="MRP"
rules={[
{
required: true,
pattern: /^[1-9]\d*(\.\d+)?$/,
message: 'Please Enter MRP',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={<label className="required">MRP</label>}
isOnChange={
selectedRowRecord?.MRP !== '' ? true : false
}
value={selectedRowRecord?.MRP}
onChange={handleMRPChange}
/>
</Form.Item>
{/* <Form.Item
name="SellPrice"
rules={[{ validator: validateSellPrice(selectedRowRecord) }]}
>
<InputField
autoComplete="off"
label={
<label className="required">
Sales Price
</label>
}
isOnChange={
selectedRowRecord?.SellPrice !== ''
? true
: false
}
value={selectedRowRecord?.SellPrice}
onChange={(e) => {
const val =
e?.target?.value === ''
? 0
: parseFloat(e?.target?.value);
setSelectedRowRecord((prev) => ({
...prev,
SellPrice: val,
}));
}}
/>
</Form.Item> */}
{applicationRestrictedFields.AmountPerPieceDetail && (
<>
<Form.Item
name="AmountPerPiece"
rules={[
{
required: true,
message: 'Please enter Amount Per Piece',
},
{
pattern: /^[0-9]*\.?[0-9]+$/,
message: 'Enter valid Amount Per Piece',
},
]}
>
<InputField
autoComplete="off"
label={
<label className="required">
Amount / Piece
</label>
}
onChange={(e) =>
handleAmountPerPiecechange(e)
}
isOnChange={
selectedRowRecord?.AmountPerPiece !== ''
? true
: false
}
value={selectedRowRecord?.AmountPerPiece}
disabled={
selectedRowRecord?.OnePcsAvailable === 'Y'
? false
: true
}
/>
</Form.Item>
<Form.Item
name="NumberofPieceinside"
rules={[
{
required: true,
message:
'Please enter Number of Piece Inside',
},
{
pattern: /^[0-9]*\.?[0-9]+$/,
message:
'Enter valid Number of Piece Inside',
},
]}
>
<InputField
autoComplete="off"
label={
<label className="required">
Number of Piece Inside
</label>
}
onChange={(e) =>
handleNumberofPieceinsidechange(e)
}
isOnChange={
selectedRowRecord?.NumberofPieceinside !==
''
? true
: false
}
value={
selectedRowRecord?.NumberofPieceinside
}
disabled={
selectedRowRecord?.OnePcsAvailable === 'Y'
? false
: true
}
/>
</Form.Item>
</>
)}
</div>
</Panel>
</Collapse>
</div>
{applicationRestrictedFields.DatesAndExpiry && (
<div className="pricing-dtls">
<Collapse defaultActiveKey={['0']}>
<Panel header="Dates & Expiry" key="1">
<div className="pricing-dtl-fields">
<Form.Item name="ManufDate">
<div className="dates-and-expiry">
<label>Manufacture Date</label>
<DatePicProd
canSelectPast={true}
onPressEnter={(e) =>
handleKeyPress(e, record, index)
}
onChange={handleManufactureDate}
valueData={selectedRowRecord?.ManufDate}
/>
</div>
</Form.Item>
<Form.Item name="ExpDate">
<div className="dates-and-expiry">
<label>Expire Date</label>
<DatePicProd
canSelectPast={false}
onPressEnter={(e) =>
handleKeyPress(e, record, index)
}
onChange={handleExpireDate}
valueData={selectedRowRecord?.ExpDate}
/>
</div>
</Form.Item>
</div>
</Panel>
</Collapse>
</div>
)}
{applicationRestrictedFields.BatchAndModelDetails && (
<div className="pricing-dtls">
<Collapse defaultActiveKey={['0']}>
<Panel header="Batch & Model Details" key="1">
<div className="pricing-dtl-fields">
<Form.Item name="BatchRef">
<InputField
autoComplete="off"
isOnChange={
selectedRowRecord?.BatchRef &&
selectedRowRecord?.BatchRef !== ''
? true
: false
}
value={selectedRowRecord?.BatchRef}
label={'Batch No.'}
onChange={handleBatchRefChange}
/>
</Form.Item>
<Form.Item name="ModelNumber">
<InputField
autoComplete="off"
isOnChange={
selectedRowRecord?.ModelNumber &&
selectedRowRecord?.ModelNumber !== ''
? true
: false
}
value={selectedRowRecord?.ModelNumber}
label={'Model No.'}
onChange={handleModelNoChange}
/>
</Form.Item>
<div
className="model-data-add"
onClick={handleModelDataOpen}
>
<IoAddCircleSharp size={18} />
<span>Add Model Data</span>
</div>
</div>
</Panel>
</Collapse>
</div>
)}
<div className="submitButton">
<Buttons
buttonText="SUBMIT"
color="901D77"
icon={<ArrowRightOutlined />}
/>
</div>
</div>
</Form>
</>
}
handleCancel={handleAdditionalInfoClose}
buttonText="Submit"
/>
<InvoiceImageExtractorModal
visible={extractorModalVisible}
onClose={() => setExtractorModalVisible(false)}
onApply={handleExtractorApply}
productData={productData}
supplierData={SupplierData}
uomData={UomData}
setVisible={setExtractorModalVisible}
/>
</div>
</div>
<style jsx>{`
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`}</style>
</div>
);
};
export default StockForm;