import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { ImWarning } from 'react-icons/im'; import { Form, Table, Input, Select, AutoComplete, Button, Tooltip, } from 'antd'; import { BsUpcScan } from 'react-icons/bs'; import { FaLink } from 'react-icons/fa'; import { DeleteFilled, ArrowRightOutlined, SearchOutlined, } from '@ant-design/icons'; import { Messages } from '../../Components/Notifications/Messages.jsx'; import { InputField } from '../../Components/Forms/InputField.jsx'; import Buttons from '../../Components/Forms/Buttons.jsx'; import { getSession, pdfDiv, printDiv, validateSafeInput, } from '../../Services/Others'; import FormHeader from '../PageComponents/FormHeader.jsx'; import { DropDowns } from '../../Components/Forms/DropDown.jsx'; import { CiBarcode } from 'react-icons/ci'; import { AdminUserData, Emailsend, getProdQuoaVariantdata, getPurProductData, postPurcQuotation, } from '../../Features/PurchaseQuotation/PurchaseQuotation.js'; import '../../Styles/PurchaseQuotation/PurchaseQuotation.scss'; import PurchaseQuotationPrint from './PurchaseQuotationPrint.jsx'; import { getPurchaseTaxTypeData } from '../../Features/StockMaster/StockMaster.js'; import { changeBreadCrumb, getEmpAccess, } from '../../Features/AppPage/CenterPage.js'; import { useAuth } from '../../AuthContext.jsx'; import { getAllCustomer, getPreferenceData, } from '../../Features/BookingScreen/BookingData/BookingData.js'; const subDirectory = import.meta.env.BASE_URL; import TooltipWrapper from '../../Components/Tooltip/Tooltip'; import { FaEye, FaPrint } from 'react-icons/fa'; import { MdOutlineMail } from 'react-icons/md'; import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx'; import FloatLabel from '../../Components/Forms/FloatLabel/index.jsx'; import { debounce } from 'lodash'; import { getPrintSelectionComponentData } from '../../Features/ThemeChange/ThemeChange.js'; import { PrintStyleFunction } from '../paymentpdfPage/PrintStyleFunction.js'; import { isMobile } from 'react-device-detect'; import { PurchaseQtMobilePrint } from './PurchaseQtMobilePrint.js'; import BarCodeScan from '../../Services/BarCodeScan.jsx'; const SalesQuotationForm = () => { const { SadminuserAccess } = useAuth(); let SAAccessCommonMaster = SadminuserAccess?.find( (e) => e?.MenuName === 'Sales Quotation' ); const formRef = useRef(null); const [form] = Form.useForm(); const [emailform] = Form.useForm(); const dispatch = useDispatch(); const navigate = useNavigate(); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserId = getSession('UserId'); const UserType = getSession('UserType'); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [AdminUser, setAdminUser] = useState([]); const [SelecAdminUser, setSelecAdminUser] = useState(null); const [SelTaxType, setSelTaxType] = useState(null); const [SelTaxTypeName, setSelTaxTypeName] = useState(null); const [ProductData, setProductData] = useState([]); const [AllCustomer, setAllCustomer] = useState(null); const [SelProduct, setSelProduct] = useState(null); const [selectedProductName, setSelectedProductName] = useState(null); const [productSearchText, setProductSearchText] = useState(''); const [scanner, setScanner] = useState(false); console.log(SelTaxTypeName, 'SelTaxTypeName'); const [selectedProductVariantData, setselectedProductVariantData] = useState(null); const [Variants, setVariants] = useState(); const [TableData, setTableData] = useState([]); const [editingKey, setEditingKey] = useState(''); const [index, setindex] = useState(); const [Delete, setDelete] = useState(false); const [allowDecimal, setAllowDecimal] = useState(false); const [TotalBillAmount, setTotalBillAmount] = useState(null); const [TotalCgst, setTotalCgst] = useState(null); const [TotalSgst, setTotalSgst] = useState(null); const [TotalIgst, setTotalIgst] = useState(null); const [TotalAmount, setTotalAmount] = useState(null); const [PurcTaxTypeData, setPurcTaxTypeData] = useState(null); const [PrintData, setPrintData] = useState([]); const isEditing = (record, index) => index === editingKey; const [empData, setEmpData] = useState(); const [addnewAccess, setaddnewAccess] = useState(true); const [isbarcode, setisbarcode] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); const [usrMailDataModel, setusrMailDataModel] = useState(false); const [EnteredMailId, setEnteredMailId] = useState(null); const [PrintTempData, setPrintTempData] = useState([]); console.log(TableData, 'TableData'); const items = [ { name: 'Home', link: `${subDirectory}app-page/home`, }, { name: 'Sales Quotation', link: `${subDirectory}setting/sales-quotation`, }, ]; // const QuotationStylepdf = ``; // const QuotationStyle = ``; const PurchaseOrderStyle = ``; useEffect(() => { dispatch(changeBreadCrumb({ items: items })); getAdminUserdata(); getProduct(); getPurchaseTaxType(); fetchdata(); getPreference(); // if (UserType === "Employee") { // fetchApi() // } }, []); // console.log(TableData, "TableDataTableData") const debouncedScannerSearch = useCallback( debounce((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}` : ''}`; ProductDropDownChange(matchedProduct.ProdId, productName); if (matchedProduct?.ProdVariantPriceDetails?.length < 2) { setSelectedProductName(''); setSelProduct(null); } } else { setMessageType('error'); setMessageData('The Scanned Product not Available in Product List'); } }, 300), [ProductData] ); const getPreference = async () => { const data = { AppId: AppId, CompId: CompId, BranchId: BranchId, UserId: UserId }; const { data: res } = await dispatch(getPreferenceData(data)).unwrap(); const decimalSetting = res?.data?.[0]?.SettingDtlDetails?.find( (setting) => setting?.SettingIdName?.toLowerCase() === 'decimal' && setting?.SettingValue === 'Y' ); if (decimalSetting) { setAllowDecimal(true); } }; const changebarcode = useCallback(() => { setisbarcode((prev) => !prev); }, []); useEffect(() => { if (UserType === 'Employee') { fetchApi(); } }, [UserType]); useEffect(() => { let hasAccess = false; if (UserType === 'Admin' || UserType === 'Super Admin') { hasAccess = true; } else if (UserType === 'Employee') { hasAccess = empData?.AddAccess === 'Y'; } else if (UserType === 'Super Admin User') { hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; } setaddnewAccess(!hasAccess); }, [empData, SAAccessCommonMaster, UserType]); const fetchApi = async () => { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, EmpId: UserId, }; let response = await dispatch(getEmpAccess(data)).unwrap(); let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( (item) => item.ConfigName === 'Sales Quotation' ); setEmpData(datas?.[0]); }; // useEffect(() => { // Print(); // }, [PrintData]); useEffect(() => { let total = TableData?.reduce((accumulator, currentValue) => { return accumulator + currentValue.NetAmt; }, 0); setTotalAmount(total); let cgst = TableData?.filter( (item) => item.TaxName?.toLowerCase() === 'cgst,sgst' ); let totalgst = cgst?.reduce((accumulator, currentValue) => { return accumulator + currentValue.TaxAmt; }, 0); setTotalCgst(totalgst / 2); setTotalSgst(totalgst / 2); let igst = TableData?.filter( (item) => item.TaxName?.toLowerCase() === 'igst' ); let totaligst = igst?.reduce((accumulator, currentValue) => { return accumulator + currentValue.TaxAmt; }, 0); setTotalIgst(totaligst); let billtotal = TableData?.reduce((accumulator, currentValue) => { return accumulator + currentValue.BillAmount; }, 0); setTotalBillAmount(billtotal); }, [TableData]); const getProduct = async () => { let Product = await dispatch( getPurProductData({ CompId: CompId, AppId: AppId, BranchId: BranchId, ActiveStatus: 'A', }) ).unwrap(); if (Product?.data?.statusCode === 1) { let Productonlydata = Product?.data?.data?.filter( (item) => item?.ProdTypeName === 'Product' && (item?.StockAvailable === 'Y' ? item?.BalanceQty > 0 : true) ); setProductData(Productonlydata); } else { setProductData([]); } }; const getAdminUserdata = async () => { let adminuser = await dispatch(AdminUserData()).unwrap(); if (adminuser?.data?.statusCode === 1) { setAdminUser(adminuser?.data?.data); console.log(adminuser?.data?.data, 'adminuser'); } else { setAdminUser([]); } }; const fetchdata = async () => { let res = await dispatch( getAllCustomer({ CompId: CompId, AppId: AppId, branchId: BranchId }) ).unwrap(); await setAllCustomer(res?.data?.data); const Data = { AppId, CompId, BranchId }; const printtemp = await dispatch( getPrintSelectionComponentData(Data) ).unwrap(); const printTypeName = printtemp?.data?.data ?.flatMap((template) => template.ComponentDetails || []) ?.find( (comp) => comp.SetasDefault === 'Y' && comp.PrintTypeName === 'Sales Quotation' ); setPrintTempData(printTypeName); }; 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() === 'withtax' ); setSelTaxType(tempniltax?.ConfigId); setSelTaxTypeName(tempniltax?.ConfigName); formRef.current?.setFieldsValue({ TaxType: tempniltax?.ConfigId }); } else { setPurcTaxTypeData(null); } }; // const Print = async () => { // if (PrintData?.length > 0) { // await printDiv(`Pur-Quot-Print`, QuotationStyle); // } // }; const handleAdminUserDropDownChange = (UserId) => { setSelecAdminUser(UserId); formRef.current?.setFieldsValue({ CustId: UserId }); setIsSubmitted(); }; const handleQuoTaxTypeChange = (taxtype) => { setSelTaxType(taxtype); formRef.current?.setFieldsValue({ TaxType: taxtype }); let taxname = PurcTaxTypeData?.find((item) => item.ConfigId === taxtype); setSelTaxTypeName(taxname?.ConfigName); let taxchange = TableData?.map((item) => { return { ...item, TaxAmt: taxname?.ConfigName?.toLowerCase() === 'withtax' ? (item?.NetAmt * parseInt(item?.TaxPercentage)) / (100 + parseInt(item?.TaxPercentage))?.toFixed(2) : 0, }; }); setTableData(taxchange); }; 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 handleProductSearch = (value) => { if (scanner) { debouncedScannerSearch(value); } setProductSearchText(value); setSelectedProductName(value); setselectedProductVariantData([]); setVariants([]); }; const ProductDropDownChange = async (ProdId, option) => { setProductSearchText(''); setSelectedProductName(option?.label ? option?.label : ''); formRef?.current?.resetFields(['VarProdId']); console.log(ProductData, 'ProdIdProdId'); setSelProduct(ProdId); formRef.current?.setFieldsValue({ ProdId: ProdId }); let x = ProductData?.find((e) => e.ProdId === ProdId)?.ProdName; let variantValues1 = await dispatch( getProdQuoaVariantdata({ CompId: CompId, AppId: AppId, BranchId: BranchId, prodName: x, }) ).unwrap(); let variants1 = variantValues1?.data?.data; // let cc = variants1?.[0]?.ProductDetail; let cc = variants1?.filter((item) => item?.ProdName == x)?.[0] ?.ProductDetail; setVariants( cc?.[0]?.ProdVariantDetails?.map((detail) => ({ ...detail, ProdIdProdName: `${detail.ProdVariantName} ${detail.ProdId}`, })) ); if (cc?.[0]?.ProdVariantDetails?.length < 2) { if (TableData?.some((e) => e.ProdId == ProdId)) { setMessageType('error'); setMessageData('Already Product Exists'); } else { let ProductData1 = ProductData?.find((e) => e.ProdId === ProdId); console.log(ProductData1, 'ProductData1ProductData1'); let ProduData2 = { ProdId: ProductData1?.ProdId, ProdName: ProductData1?.ProdName, UomName: ProductData1?.UomName, Price: ProductData1?.SellPrice, TaxName: ProductData1?.TaxName, HSNCode: ProductData1?.HSNCode, Size: ProductData1?.Size, // OnePcsAvailable:ProductData1?.OnePcsAvailable, // NumberofPieceinside: ProductData1?.NoOfPcs, // AmountPerPiece: ProductData1?.OnePcsPrice, TaxId: ProductData1?.TaxId, TaxPercentage: ProductData1?.TaxPercentage, }; let tempPurData = { ...ProduData2, Qty: 0, // 'InwardPrice': 0, PurcDisc: 0, NetAmt: 0, BillAmount: 0, DiscType: 'P', // 'WhSalePrice': 0, // 'ReceivedQty': 0, // 'AcceptedQty': 0, // 'RejectedQty': 0, // "OfferPrice": 0, // "SpecialPrice": 0, ProdVariantName: 'Variant 1', // "FreeItem": 0, // 'TaxPerc': PurcselectedTax ? PurcselectedTax : 0, TaxAmt: 0, // 'TaxType': SelectedPurcTaxType ? SelectedPurcTaxType : 0, }; form.setFieldsValue({ [`BalanceQty${TableData.length + 1}`]: undefined, // [`ReceivedQty${index}`]: undefined, // [`AcceptedQty${index}`]: undefined, // [`RejectedQty${index}`]: undefined, [`Amount${TableData.length + 1}`]: ProductData1?.SellPrice, // [`FreeQty${index}`]: undefined, // [`InwardPrice${index}`]: undefined, // [`MRP${index}`]: undefined, [`PurcDisc${TableData.length + 1}`]: 0, [`SellPrice${TableData.length + 1}`]: ProductData1?.SellPrice, // [`WhSalePrice${index}`]: undefined, // [`offerSalePrice${index}`]: undefined, // [`splSalePrice${index}`]: undefined }); setTableData([...TableData, tempPurData]); } } }; const ProductVariantDropDownChange = (value) => { const ProdName2 = Variants?.filter( (item) => item.ProdIdProdName === value )?.[0]?.ProdVariantName; const ProdName1 = TableData?.some( (e) => e.ProdId == SelProduct && e.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 x = VariantData1?.filter((e) => e.InwardDtlId == value); // let u = ProductData?.find((e) => e.ProdId == selectedProductData); // console.log(first) let ProductData1 = ProductData?.find((e) => e.ProdId == SelProduct); console.log(ProductData1, 'ProductData1ProductData1'); 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 ProduData2 = { ProdId: ProductData1?.ProdId, // MRP: mrp, ProdName: ProductData1?.ProdName, UomName: ProductData1?.UomName, Price: sellprice, TaxName: ProductData1?.TaxName, HSNCode: ProductData1?.HSNCode, // StockAvailable: ProductData1?.StockAvailable, // OnePcsAvailable:ProductData1?.OnePcsAvailable, // NumberofPieceinside: ProductData1?.NoOfPcs, // AmountPerPiece: ProductData1?.OnePcsPrice, Size: ProductData1?.Size, TaxId: ProductData1?.TaxId, TaxPercentage: ProductData1?.TaxPercentage, }; // ProduData2["StockAvailable"]="Y" let tempPurData = { ...ProduData2, Qty: 0, PurcDisc: 0, NetAmt: 0, BillAmount: 0, DiscType: 'P', ProdVariantName: ProdName, TaxAmt: 0, }; setTableData([...TableData, tempPurData]); } }; const onComplete = useCallback(() => { setMessageData(null); setMessageType(null); }, []); 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 = [...TableData]; // const index = newData.findIndex((item) => recordKey === item.InwardDtlId); if (index > -1) { const item = newData[index]; newData.splice(index, 1, { ...item, ...modifiedObject }); setTableData(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 getColumns = (data, seltax) => { const hasDiscount = data?.some((record) => record.PurcDisc > 0); const baseColumns = [ { title: 'Sl.No', align: 'center', key: 'sno', render: (text, object, index) => ( {index + 1} ), }, { title: 'Product Name', dataIndex: 'ProdName', key: 'ProdName', width: '230px', align: 'right', render: (text, record, index) => ( {record?.ProdName + '(' + record?.Size + '-' + record?.UomName + ')' + '(' + record?.ProdVariantName + ')'} ), }, { title: 'Qty', dataIndex: 'Qty', key: 'Qty', editable: true, // with: '100px', render: (text, record, index) => { return isEditing(record, index) ? ( handleKeyPress(e, record, index)} onBlur={(e) => handleQtyChange(e, record)} onChange={(e) => handleQtyChange(e, record, index)} autoComplete="off" inputMode="decimal" onInput={(e) => { let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); // Remove invalid characters const parts = cleanedValue.split('.'); if (cleanedValue.startsWith('.')) { cleanedValue = '0' + cleanedValue; } e.target.value = parts.length > 2 ? `${parts[0]}.${parts.slice(1).join('')}` : cleanedValue; }} /> ) : ( text ); }, }, // { // title: 'Hsn Code', // dataIndex: 'HSNCode', // key: 'HSNCode', // }, { title: 'Uom', dataIndex: 'UomName', key: 'UOMName', }, { title: 'Rate', dataIndex: 'Price', key: 'Price', editable: true, render: (text, record, index) => { return isEditing(record, index) ? ( handleKeyPress(e, record, index)} onChange={(e) => handlePurrateChange(e, record, index)} onBlur={(e) => handlePurrateChange(e, record, index)} autoComplete="off" inputMode="decimal" onInput={(e) => { let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); // Remove invalid characters const parts = cleanedValue.split('.'); if (cleanedValue.startsWith('.')) { cleanedValue = '0' + cleanedValue; } e.target.value = parts.length > 2 ? `${parts[0]}.${parts.slice(1).join('')}` : cleanedValue; }} /> ) : ( text ); }, }, { title: 'Discount', dataIndex: 'PurcDisc', key: 'PurcDisc', editable: true, render: (text, record, index) => { return isEditing(record, index) ? ( { const PurcDiscType = form.getFieldValue([ `DiscType${index}`, ]); console.log(PurcDiscType, 'PurcDiscType'); if (value === undefined || value === '') return Promise.resolve(); if (PurcDiscType === 'P') { console.log(PurcDiscType, 'PurcDiscType'); if ( !/^(100(\.0{1,2})?|[0-9]{1,2}(\.\d{1,2})?)$/.test(value) ) { return Promise.reject( 'Please enter a valid discount (0-100%)' ); } } return Promise.resolve(); }, }, ]} > handleKeyPress(e, record, index)} onChange={(e) => handlePurdiscChange(e, record, index)} onBlur={(e) => handlePurdiscChange(e, record)} autoComplete="off" inputMode="decimal" onInput={(e) => { let cleanedValue = e.target.value.replace(/[^0-9.]/g, ''); // Remove invalid characters const parts = cleanedValue.split('.'); if (cleanedValue.startsWith('.')) { cleanedValue = '0' + cleanedValue; } e.target.value = parts.length > 2 ? `${parts[0]}.${parts.slice(1).join('')}` : cleanedValue; }} /> ) : ( text ); }, }, { title: 'Amount', dataIndex: 'NetAmt', key: 'NetAmt', editable: true, }, ]; // Conditionally add the Discount Type column if there's a discount if (hasDiscount) { baseColumns.splice(6, 0, { title: 'Discount Type', dataIndex: 'DiscType', key: 'DiscType', editable: true, render: (text, record, index) => { const purchaseDiscount = record.PurcDisc || 0; // Ensure a valid number return isEditing(record, index) && purchaseDiscount > 0 ? ( { const PurcDisc = form.getFieldValue([`PurcDisc${index}`]); const PurcDiscType = form.getFieldValue([ `DiscType${index}`, ]); if (value === undefined || value === '') return Promise.resolve(); if (PurcDisc > 99 && PurcDiscType == 'P') { console.log( PurcDiscType, PurcDisc, 'record.DiscountType' ); const newData = TableData.map((item, index1) => { if (index1 === index) { return { ...item, PurcDisc: 0, NetAmt: item.Price * item.Qty, // TaxAmt: taxamount, BillAmount: item.Price * item.Qty - item.taxamount, }; } return item; }); setTableData(newData); form.setFieldsValue({ ...form.getFieldsValue(), [`PurcDisc${index}`]: 0, }); // if ( // !/^(100(\.0{1,2})?|[0-9]{1,2}(\.\d{1,2})?)$/.test(value) // ) { // return Promise.reject('enter a valid discount (0-100%)'); // } } return Promise.resolve(); }, }, ]} > ) : ( text ); }, }); } if (seltax !== 'WOT') { baseColumns.splice(8, 0, { title: 'Tax %', dataIndex: 'TaxPercentage', key: 'TaxPercentage', editable: true, }); baseColumns.splice(9, 0, { title: 'Tax Name', dataIndex: 'TaxName', key: 'TaxName', editable: true, }); } baseColumns.push({ title: 'Action', dataIndex: 'Action', key: 'Action', align: 'center', editable: false, render: (_, record, index) => ( { e.stopPropagation(); // Stop event from bubbling up to row statusFormatters(record, index); }} /> ), }); return baseColumns; }; const columns = getColumns(TableData, SelTaxType); const edit = (record, index) => { form.setFieldsValue({ ...record }); setEditingKey(index); setindex(index); form.setFieldsValue({ [`Qty${index}`]: record?.Qty, [`NetAmt${index}`]: !isNaN(record?.NetAmt) ? record?.NetAmt : 0, [`PurcDisc${index}`]: record?.PurcDisc, [`Price${index}`]: record?.Price, }); }; const statusFormatters = (record, index) => { // Remove the row from table data const newData = TableData.filter((_, i) => i !== index); setTableData(newData); setDelete(true); setEditingKey(''); // Get all current form values const currentFormValues = form.getFieldsValue(); // Clear all form fields first const allFieldsToClear = []; for (let i = 0; i < TableData.length; i++) { allFieldsToClear.push( `BalanceQty${i}`, `Amount${i}`, `PurcDisc${i}`, `SellPrice${i}`, `Qty${i}`, `NetAmt${i}`, `Price${i}`, `DiscType${i}` ); } const clearAllValues = {}; allFieldsToClear.forEach((field) => { clearAllValues[field] = undefined; }); // Set new form values with correct indices const newFormValues = {}; newData.forEach((item, newIndex) => { newFormValues[`Qty${newIndex}`] = item.Qty; newFormValues[`NetAmt${newIndex}`] = item.NetAmt; newFormValues[`PurcDisc${newIndex}`] = item.PurcDisc; newFormValues[`Price${newIndex}`] = item.Price; newFormValues[`DiscType${newIndex}`] = item.DiscType; }); // Apply the new form values form.setFieldsValue({ ...clearAllValues, ...newFormValues }); console.log(form.getFieldsValue(), 'jjij'); }; const handleQtyChange = (e, record, index) => { const qty = e.target.value; if (!/^\d*\.?\d*$/.test(qty)) { setMessageType('error'); setMessageData('Only numeric values are allowed'); return; } const sellprice = parseInt(record.Price); const Amount = !isNaN(sellprice * parseInt(qty)) ? sellprice * parseInt(qty) : 0; const taxamt = SelTaxTypeName?.toLowerCase() === 'withtax' ? (Amount * parseInt(record?.TaxPercentage)) / (100 + parseInt(record?.TaxPercentage)) : 0; const newData = TableData.map((item, index1) => { if (index1 === index) { return { ...item, Qty: qty, NetAmt: Amount, TaxAmt: taxamt, BillAmount: Amount - taxamt, }; } return item; }); setTableData(newData); form.setFieldsValue({ ...form.getFieldsValue(), [`Qty${index}`]: qty, [`NetAmt${index}`]: Amount, [`PurcDisc${index}`]: 0, [`DiscType${index}`]: 'P', }); }; const handleDiscountTypeChange = (value, record, index) => { const tempamt = record.Qty * record.Price; const DisType = value; const amount = value === 'A' ? tempamt - record.PurcDisc : tempamt - tempamt * (record.PurcDisc / 100); const taxamt = SelTaxTypeName?.toLowerCase() === 'withtax' ? (amount * parseInt(record?.TaxPercentage)) / (100 + parseInt(record?.TaxPercentage))?.toFixed(2) : 0; // You can calculate acceptedQty based on your requirement const newData = TableData.map((item, index1) => { if (index1 === index) { return { ...item, NetAmt: amount, TaxAmt: taxamt, BillAmount: amount - taxamt, DiscType: DisType, }; } return item; }); setTableData(newData); }; const handlePurrateChange = (e, record, index) => { const inputValue = e.target.value; // Validate if inputValue is numeric if (!/^\d*\.?\d*$/.test(inputValue)) { setMessageType('error'); setMessageData('Only numeric values are allowed'); return; } const PurcRate = inputValue; // const PurcRate = e.target.value const tempamt = !isNaN(parseInt(PurcRate) * parseInt(record?.Qty)) ? parseInt(PurcRate) * parseInt(record?.Qty) : 0; const amount = record?.PurcDisc === 0 ? tempamt : record?.DiscType === 'A' ? tempamt - record.PurcDisc : tempamt - tempamt * (record.PurcDisc / 100); const taxamt = SelTaxTypeName?.toLowerCase() === 'withtax' ? (amount * parseInt(record?.TaxPercentage)) / (100 + parseInt(record?.TaxPercentage))?.toFixed(2) : 0; // You can calculate acceptedQty based on your requirement const newData = TableData.map((item, index1) => { if (index1 === index) { return { ...item, Price: PurcRate, NetAmt: amount, TaxAmt: taxamt, BillAmount: amount - taxamt, }; } return item; }); setTableData(newData); form.setFieldsValue({ ...form.getFieldsValue(), [`Price${index}`]: PurcRate, [`NetAmt${index}`]: amount, }); }; const handlePurdiscChange = (e, record, index) => { console.log(e.target.value, record, 'discountdiscount'); const PurcDisc = e.target.value; const PurcRate = record?.Price; const tempamt = parseInt(record?.Price) * record?.Qty; const amount = record.DiscType === 'A' ? tempamt - PurcDisc : tempamt - tempamt * (parseFloat(PurcDisc) / 100); const taxamount = SelTaxTypeName?.toLowerCase() === 'withtax' ? (amount * parseInt(record?.TaxPercentage)) / (100 + parseInt(record?.TaxPercentage))?.toFixed(2) : 0; form.setFields([{ name: [`PurcDisc${index}`], errors: [] }]); // Check if PurcDisc is a valid number if (!isNaN(parseFloat(PurcDisc)) && isFinite(PurcDisc)) { if (record?.Qty > 0) { const newData = TableData.map((item, index1) => { if (index1 === index) { return { ...item, PurcDisc: PurcDisc, NetAmt: amount, TaxAmt: taxamount, BillAmount: amount - taxamount, }; } return item; }); setTableData(newData); form.setFieldsValue({ ...form.getFieldsValue(), [`PurcDisc${index}`]: PurcDisc, [`NetAmt${index}`]: amount, // [`DiscType${index}`]: 'P', }); } else { form.setFields([ { name: [`PurcDisc${index}`], errors: [' Please Enter Purchase Quantity'], }, ]); } } else { // Set error if PurcDisc is not a valid number form.setFields([ { name: [`PurcDisc${index}`], errors: [' Discount must be a number'] }, ]); } }; const PrintQuotation = async () => { // await printDiv(`Pur-Quot-Print`, QuotationStyle) if ( TableData?.length > 0 && TableData?.every((item) => item.Qty !== 0 && item.Amount !== 0) ) { let PostData = formRef.current?.getFieldsValue(); PostData['ProductDetails'] = TableData; PostData['BillAmount'] = parseFloat(TotalBillAmount?.toFixed(2)); PostData['NetAmount'] = parseFloat(TotalAmount?.toFixed(2)); PostData['TaxAmount'] = parseFloat( (TotalCgst + TotalSgst + TotalIgst)?.toFixed(2) ); ((PostData['CompId'] = CompId), (PostData['BranchId'] = BranchId), (PostData['AppId'] = AppId)); let res = await dispatch(postPurcQuotation(PostData)).unwrap(); if (res?.data?.statusCode === 1) { setMessageType('success'); setMessageData(res?.data?.response); const custId = formRef.current?.getFieldValue('CustId'); const customer = AllCustomer?.find((c) => c.UserId === custId); console.log(customer, 'customertrt'); setPrintData(res?.data?.data); setIsSubmitted(true); formRef?.current?.resetFields([ 'CustId', 'ProdId', 'QRCode', 'VarProdId', 'TaxType', ]); setTableData([]); setSelProduct(null); setSelectedProductName(null); setSelecAdminUser(null); setSelTaxType(null); setSelTaxTypeName(null); setVariants(null); setselectedProductVariantData(null); // Reset totals setTotalBillAmount(null); setTotalCgst(null); setTotalSgst(null); setTotalIgst(null); setTotalAmount(null); // Reset editing state setEditingKey(''); setindex(null); // Clear form values for all table rows const clearFields = {}; TableData.forEach((_, index) => { clearFields[`Qty${index}`] = undefined; clearFields[`Price${index}`] = undefined; clearFields[`PurcDisc${index}`] = undefined; clearFields[`NetAmt${index}`] = undefined; clearFields[`DiscType${index}`] = undefined; }); form.setFieldsValue(clearFields); } else { setMessageType('error'); setMessageData(res?.data?.response); } } else { setMessageType('error'); setMessageData('Please give Product Quantity for all Product '); } }; const onChangeprodFunction = (e) => { console.log(e, 'yyyyyyyyyyyyyy'); if (isbarcode) { // When in barcode mode, search by QRCode const productByQR = ProductData.find( (p) => p.QRCode && p.QRCode?.toLowerCase() === e?.toLowerCase() ); if (productByQR) { const productValue = productByQR.ProdName + ' ' + '(' + productByQR.Size + productByQR.UomName + ')'; form.setFieldsValue({ ProdId: productValue }); setSelProduct(productValue); ProductDropDownChange({ value: productValue }); } } else { // Normal mode - search by product name form.setFieldsValue({ ProdId: e }); setSelProduct(e); } }; const handlePrint = async () => { const style = await PrintStyleFunction( PrintTempData?.StyleName == undefined ? 'Style 13' : PrintTempData?.StyleName, 'Quotation' ); const stylesMap = { 'Style 1': 'SQPrintStyle1', 'Style 2': 'SQPrintStyle2', 'Style 3': 'SQPrintStyle3', 'Style 4': 'SQPrintStyle4', 'Style 5': 'SQPrintStyle5', 'Style 6': 'SQPrintStyle6', 'Style 7': 'SQPrintStyle7', 'Style 8': 'SQPrintStyle8', 'Style 9': 'SQPrintStyle9', 'Style 10': 'SQPrintStyle10', 'Style 11': 'SQPrintStyle11', 'Style 12': 'SQPrintStyle12', 'Style 13': 'Pur-Quot-Print', A4: 'SQPrintStyleA4', A5: 'SQPrintStyleA5', A4Standard: 'SQA4Standard', TaxInvoice: 'TaxInvoice', }; const selectedStyle = stylesMap[ PrintTempData?.StyleName == undefined ? 'Style 13' : PrintTempData?.StyleName ]; if (isMobile) { PurchaseQtMobilePrint({ PrintTempData: PrintTempData, PrintOrderDetails: PrintData, UserId: UserId, dispatch, }); } else if (selectedStyle) { await printDiv(`${selectedStyle}`, style); } }; const handleEmailClick = async (mail, data) => { let record = mail == 'mail' ? data : PrintData?.[0]; if (record?.Email) { setTimeout(async () => { try { const blob = await pdfDiv('Pur-Quot-Print', PurchaseOrderStyle); const payload = { fileBlob: blob, toEmail: record?.Email, type: 'Quotation', messageTemplatesList: [], }; const res = await dispatch(Emailsend(payload)).unwrap(); if (res?.data?.status === 1) { setMessageData(res?.data?.response); setMessageType('success'); } else { setMessageData(res?.data?.response); setMessageType('error'); } // setMessageData("Email sent successfully"); // setMessageType('success'); } catch (error) { console.error('❌ Email send failed:', error); // alert('❌ Email failed to send'); setMessageData('Email failed to send'); setMessageType('error'); } }, 300); } else { setusrMailDataModel(true); } }; const handleUserMailmodalCancel = () => { setusrMailDataModel(false); setEnteredMailId(null); emailform.resetFields(); // setQuotationProductdata([]) }; const emailSubmit = (values) => { let data = { ...PrintData?.[0], ...{ CustMail: values.email }, ...{ Email: values.email }, }; handleEmailClick('mail', data); setEnteredMailId(null); emailform.resetFields(); emailform.setFieldsValue({ email: '' }); setusrMailDataModel(false); }; return (
navigate(`${subDirectory}setting/sales-quotation/list`) } > View Quotation
({ value: option.CustId, label: option.CustName || option.CustShortName || option.CustMobile, }))} label={} className="field-DropDown" onChangeFunction={handleAdminUserDropDownChange} /> ({ value: option.ConfigId, label: option.ConfigName, }))} label={ } className="field-DropDown" onChangeFunction={(e) => handleQuoTaxTypeChange(e)} valueData={SelTaxType} />
{ 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={ProductDropDownChange} onChange={handleProductSearch} onKeyDown={(e) => { if (scanner && e.key === 'Enter') { e.preventDefault(); } }} disabled={ProductData?.length === 0} >
{!isMobile ? : { debouncedScannerSearch(value); }} />}
{ProductData?.length === 0 && (

All Products have no Stock

)}
{Variants?.length > 1 && ( ({ value: option.ProdIdProdName, label: option.ProdVariantName, }))} label={'Variant Name'} className="field-DropDown" onChangeFunction={(e) => ProductVariantDropDownChange(e) } /> )}
0 ? 'auto' : 'hidden', // overflowX: TableData?.length > 0 ? "auto" : "hidden", }} > ({ onClick: () => { edit(record, index); }, })} pagination={false} />
} htmlType={true} /> {isSubmitted && PrintData?.length > 0 && ( <>
)}
{TableData?.length > 0 && (
{' '} Gross Total:{' '} {allowDecimal ? TotalBillAmount?.toFixed(2) : TotalBillAmount}
{' '} Total GST:{' '} {allowDecimal ? (TotalCgst + TotalSgst + TotalIgst)?.toFixed(2) : TotalCgst + TotalSgst + TotalIgst}
{/*
Total SGST: {TotalSgst?.toFixed(2)}
Total IGST: {TotalIgst?.toFixed(2)}
*/}
{' '} Total Amount:{' '} {allowDecimal ? Math.round(TotalAmount)?.toFixed(2) : Math.round(TotalAmount)}
)}
} />
); }; export default SalesQuotationForm;