Android_Retail/src/Pages/PurchaseOrder/PurchaseOrder.jsx

2500 lines
85 KiB
JavaScript

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation, useNavigate } from 'react-router-dom';
import {
ArrowRightOutlined,
PlusCircleOutlined,
DeleteFilled,
EditFilled,
} from '@ant-design/icons';
import { Messages } from '../../Components/Notifications/Messages';
import { Form, Tooltip, Space, Input, Button, AutoComplete } from 'antd';
import { IoWarningOutline } from 'react-icons/io5';
import {
getSession,
pdfDiv,
printDiv,
validateSafeInput,
} from '../../Services/Others.js';
import FormHeader from '../PageComponents/FormHeader.jsx';
import Buttons from '../../Components/Forms/Buttons.jsx';
import { InputField } from '../../Components/Forms/InputField.jsx';
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
import {
getPurProductData,
getPurProdvaraiantdata,
getPurcProdTaxData,
getPurcTaxTypeData,
getPurchaseSupplierData,
postPurcOrderData,
getProductData,
Emailsend,
getPurchaseSupplierAndWareHouseData,
getProductStockDetails,
} from '../../Features/PurchaseOrder/PurchaseOrder.js';
import { Tables } from '../../Components/Tables/Table.jsx';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import { postSupplier } from '../../Features/ProductPage/ProductPage.js';
import { changeBreadCrumb } from '../../Features/AppPage/CenterPage.js';
import { DropDowns1 } from '../../Components/Forms/DropDown1.jsx';
import PurchaseOrderPrint from './PurchaseOrderPrint.jsx';
import { FaEye, FaLink, FaPrint } from 'react-icons/fa';
import { MdOutlineMail } from 'react-icons/md';
import { getSupplaierIdwithTypeBasedProducts } from '../../Features/SupplierProductMapping/SupplierProductMapping.js';
import SupplierProductMappingForm from '../SupplierProductMapping/SuplierProductMappingForm.jsx';
import { getConfigType } from '../../Features/BookingScreen/BookingData/BookingData.js';
import FloatLabel from '../../Components/Forms/FloatLabel/index.jsx';
import '../../Styles/OverAllStyle/OverAllStyle.scss';
import { BsUpcScan } from 'react-icons/bs';
import { debounce } from 'lodash';
import { getPrintSelectionComponentData } from '../../Features/ThemeChange/ThemeChange.js';
import { PrintStyleFunction } from '../paymentpdfPage/PrintStyleFunction.js';
import { PurchaseOrderMobilePrint } from './PurchsasePrintStyle/PurchaseOrderMobilePrint.js';
import { isMobile } from 'react-device-detect';
import { CiEdit } from 'react-icons/ci';
const subDirectory = import.meta.env.BASE_URL;
const stylesMap = {
'Style 1': 'PurchaseStyle1',
'Style 2': 'PrintStyle2',
'Style 3': 'PrintStyle3',
'Style 4': 'PrintStyle4',
'Style 5': 'PrintStyle5',
'Style 6': 'PrintStyle6',
'Style 7': 'PrintStyle7',
'Style 8': 'PrintStyle8',
'Style 9': 'PrintStyle9',
'Style 10': 'PrintStyle10',
'Style 11': 'PrintStyle11',
'Style 12': 'PrintStyle12',
'Style 13': 'Pur-Order-Print',
A4: 'PrintStyleA4',
A5: 'PrintStyleA5',
A4Standard: 'A4Standard',
TaxInvoice: 'TaxInvoice',
};
const PurchaseOrder = () => {
const [form] = Form.useForm();
const navigate = useNavigate();
const formRef = useRef(null);
const location = useLocation();
const formProductRef = useRef(null);
const formSupplierRef = useRef(null);
const deliveryAddressRef = useRef(null);
const dispatch = useDispatch();
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const AppId = getSession('AppId');
const UserId = getSession('UserId');
const [message, setMessage] = useState({ type: null, data: null });
const [Supplierdata, setSupplierdata] = useState([]);
const [selecPurSupplier, setselecPurSupplier] = useState(null);
const [selectedProductName, setSelectedProductName] = useState(null);
const [productSearchText, setProductSearchText] = useState('');
const [scanner, setScanner] = useState(false);
const [selecPurSupplierDetails, setselecPurSupplierDetails] = useState(null);
const [selecSuppDetails, setselecSuppDetails] = useState(null);
const [OpenPurSupplierModel, setOpenPurSupplierModel] = useState(false);
const [PurProductdata, setPurProductdata] = useState([]);
const [selectedPurProductData, setselectedPurProductData] = useState(null);
const [VariantDetails, setVariantDetails] = useState(null);
const [SelProductVariant, setSelProductVariant] = useState(null);
const [ProductTableData, setProductTableData] = useState([]);
const [zipCodeData, setZipCodeData] = useState(false);
const [Edit, setEdit] = useState(false);
const [currentIndex, setCurrentIndex] = useState(null);
const [PrintData, setPrintData] = useState([]);
const [printTrigger, setPrintTrigger] = useState(false); // <-- add this line
const [isSubmitted, setIsSubmitted] = useState(false);
const [submittedOrderData, setSubmittedOrderData] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLowStockModel, setisLowStockModel] = useState(false);
const [addressModel, setAddressModel] = useState(false);
const [deliveryAddress, setDeliveryAddress] = useState('');
const [searchedText, setSearchedText] = useState('');
const [iSEmail, setiSEmail] = useState(false);
const [enteredEmail, setEnteredEmail] = useState('');
const [pendingOrderDetails, setPendingOrderDetails] = useState(null);
const [pendingRecord, setPendingRecord] = useState(null);
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 [selectedStyleData, setselectedStyleData] = useState();
const [ProductStockData, seProductStockData] = useState([]);
const [selectedStockDetails, setSelectedStockDetails] = useState({
StockDetails: [],
});
console.log(ProductStockData, 'ProductStockData');
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage] = useState(20);
const [searchTerm, setSearchTerm] = useState('');
const [minQty, setMinQty] = useState('');
// const filteredData = currentData.filter((item) => {
// const matchesSearch =
// item.ProdName.toLowerCase().includes(searchTerm.toLowerCase()) ||
// item.ProdVariantName.toLowerCase().includes(searchTerm.toLowerCase());
// const matchesMinQty = minQty === "" || item.BalanceQty <= Number(minQty);
// return matchesSearch && matchesMinQty;
// });
// const styleName = selectedStyleData == undefined ? 'Pur-Order-Print' : selectedStyleData;
// const selectedStyle = stylesMap[styleName] || 'Pur-Order-Print';
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
{
name: 'Purchase Order',
link: `${subDirectory}setting/purchase-order/new`,
},
{
name: 'New',
link: null,
},
];
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
getSupplierData();
}, []);
useEffect(() => {
dispatch(changeBreadCrumb({ items: items }));
getSupplierData();
// Handle incoming navigation state
if (location.state) {
const { selecPurSupplierDetails, OrderId, ProductTableData } =
location.state;
if (selecPurSupplierDetails) {
setselecPurSupplierDetails(selecPurSupplierDetails);
if (selecPurSupplierDetails[0]?.SuppId) {
setselecPurSupplier(selecPurSupplierDetails[0].SuppId);
getProductDatas(selecPurSupplierDetails[0].SuppId);
formRef.current?.setFieldsValue({
SuppId: selecPurSupplierDetails[0].SuppId,
});
}
}
if (ProductTableData) {
setProductTableData(ProductTableData);
}
}
}, [location.state]);
useEffect(() => {
SetSelfSupplier();
}, [Supplierdata]);
useEffect(() => {
deliveryPerformance();
discountLevel();
qualityofSupp();
printsyleget();
ProductStockFun();
}, []);
const handleSaveLowStock = () => {
let ChoosenLowStockProd = ProductStockData?.filter(
(e) => e?.needQty > 0
)?.map((e) => ({
OrderQty: e?.needQty,
ProdId: e?.ProdId,
ProdName: `${e?.ProdName}(${e?.Size}${e?.UOMName})`,
ProdVariantName: e?.ProdVariantName,
}));
setProductTableData((prev) => [...ChoosenLowStockProd]);
setisLowStockModel(false);
};
const ProductStockFun = async (qty = 5) => {
console.log(qty, 'qtyqty');
try {
const Data = { AppId, CompId, BranchId, qty: qty };
let response = await dispatch(getProductStockDetails(Data)).unwrap();
if (response?.data?.statusCode === 1) {
seProductStockData(response?.data?.data);
}
} catch (err) {
console.error('Error fetching stock details:', err);
}
};
console.log('hi');
const debouncedFetchStock = useMemo(() => debounce(ProductStockFun, 600), []);
const handleMinQtyChange = (e) => {
const value = e.target.value;
setMinQty(value);
debouncedFetchStock(value || 0);
};
const filteredData = ProductStockData.filter(
(row) =>
!searchTerm ||
(row.ProdName &&
row.ProdName?.toLowerCase()?.includes(searchTerm?.toLowerCase()))
);
const totalPages = Math.ceil(filteredData.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const currentData = filteredData.slice(startIndex, endIndex);
const printsyleget = async () => {
const Data = { AppId, CompId, BranchId };
let response = await dispatch(
getPrintSelectionComponentData(Data)
).unwrap();
if (response?.data?.statusCode == 1) {
setselectedStyleData(
response?.data?.data?.[0]?.ComponentDetails?.find(
(e) => e?.PrintTypeName == 'Purchase Order' && e?.SetasDefault == 'Y'
)?.StyleName
);
} else {
setselectedStyleData(null);
}
};
const debouncedScannerSearch = useCallback(
debounce((value) => {
const qr = value?.trim();
if (qr === '') return;
const matchedProduct = PurProductdata.find(
(p) => p.QRCode?.toLowerCase() === qr?.toLowerCase()
);
if (matchedProduct) {
let productName = {};
productName.label = `${matchedProduct?.ProdName} (${matchedProduct.Size} ${matchedProduct.UomName})${matchedProduct?.BrandName ? ` - ${matchedProduct?.BrandName}` : ''}`;
PurcProductDropDownChange(matchedProduct.ProdId, productName);
if (matchedProduct?.ProdVariantPriceDetails?.length < 2) {
setSelProduct(null);
}
} else {
setMessage({
type: 'error',
data: 'The Scanned Product not Available in Product List',
});
}
}, 300),
[PurProductdata]
);
const handlePrevious = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
const handleNext = () => {
if (currentPage < totalPages) {
setCurrentPage(currentPage + 1);
}
};
const SetSelfSupplier = async () => {
let SupplierId = Supplierdata?.filter(
(item) => item.SuppName?.toLowerCase() === 'self'
)?.[0]?.['SuppId'];
let SelectSupDetails = Supplierdata?.filter(
(item) => item.SuppName?.toLowerCase() === 'self'
); //naresh
setselecPurSupplierDetails(SelectSupDetails);
formRef.current?.setFieldsValue({ SuppId: SupplierId });
setselecPurSupplier(SupplierId);
getProductDatas(SupplierId);
};
const getSupplierData = async () => {
try {
let Supplier = await dispatch(
getPurchaseSupplierAndWareHouseData({
CompId,
AppId,
BranchId,
})
).unwrap();
if (Supplier?.statusCode == 1) {
setSupplierdata(Supplier?.data);
} else {
setSupplierdata([]);
}
} catch (error) {
setMessage({
type: 'error',
data: error,
});
}
};
const getProductDatas = async (SuppId) => {
if (!SuppId) {
setPurProductdata([]);
return;
}
// Supplierdata
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();
if (productResponse?.data?.statusCode == 1) {
setPurProductdata(productResponse?.data?.data);
} else {
// setMessage({
// type: "error",
// data: productResponse?.data?.response
// })
setPurProductdata([]);
}
};
const handleSupplierDropDownChange = async (SuppId) => {
let SelectSupDetails = Supplierdata?.filter(
(item) => item.SuppId?.toLowerCase() === SuppId?.toLowerCase()
); //naresh
setselecPurSupplierDetails(SelectSupDetails);
formRef.current?.setFieldsValue({ SuppId: SuppId });
setselecPurSupplier(SuppId);
getProductDatas(SuppId);
formProductRef.current.resetFields(['ProdId']);
setselectedPurProductData(null);
setProductTableData([]);
let SelectSuppData = Supplierdata?.filter((item) => item.SuppId === SuppId);
if (SelectSuppData?.length > 0) {
setselecSuppDetails(SelectSuppData?.[0]);
setIsSubmitted(false);
} else {
setselecSuppDetails(null);
}
// let productdtl = await dispatch(getPurProductData({ SuppId: SuppId })).unwrap();
// if (productdtl?.data?.statusCode == 1) {
// console.log(productdtl?.data?.data, "setPurProductdata")
// setPurProductdata(productdtl?.data?.data)
// }
// else {
// setPurProductdata(null)
// }
};
const addPurSupplier = () => {
setOpenPurSupplierModel(true);
};
const PurcProductDropDownChange = async (Prodid, option) => {
setSelProductVariant(null);
setProductSearchText('');
setSelectedProductName(option?.label ? option?.label : '');
formProductRef?.current?.resetFields(['ProdVariantName']);
formProductRef.current?.setFieldsValue({ ProdId: Prodid });
setselectedPurProductData(Prodid);
let x = PurProductdata.find((e) => e.ProdId == Prodid)?.ProdName;
let variantValues1 = await dispatch(
getPurProdvaraiantdata({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
prodName: x,
})
).unwrap();
if (variantValues1?.data?.statusCode === 1) {
console.log(variantValues1?.data?.data, 'productdetail');
setVariantDetails(
variantValues1?.data?.data?.[0]?.ProductDetail?.[0]?.ProdVariantDetails
);
} else {
setVariantDetails(null);
}
};
const handleQRCodeChange = async (e) => {
let qrcode = e.target.value;
formProductRef.current?.setFieldsValue({ QRCode: qrcode });
console.log(PurProductdata, 'PurProductdata');
let x = PurProductdata.find((e) => e.QRCode === qrcode);
if (x !== undefined) {
formProductRef.current?.setFieldsValue({ ProdId: x?.ProdId });
setselectedPurProductData(x?.ProdId);
let variantValues1 = await dispatch(
getPurProdvaraiantdata({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
prodName: x?.ProdName,
})
).unwrap();
if (variantValues1?.data?.statusCode === 1) {
console.log(variantValues1?.data?.data, 'productdetail');
setVariantDetails(
variantValues1?.data?.data?.[0]?.ProductDetail?.[0]
?.ProdVariantDetails
);
} else {
setVariantDetails(null);
}
}
};
const ProductVariantDropDownChange = async (Variant) => {
setSelProductVariant(Variant);
formProductRef.current?.setFieldsValue({ ProdVariantName: Variant });
console.log(Variant, 'VariantVariant');
};
const handleProductSearch = (value) => {
if (scanner) {
debouncedScannerSearch(value);
}
setProductSearchText(value);
setSelectedProductName(value);
setVariantDetails([]);
};
const handleScanSearch = () => {
if (scanner === false) {
setMessage({ type: 'success', data: 'Search by QrCode/BarCode Enabled' });
} else {
setMessage({
type: 'success',
data: 'Search by QrCode/BarCode Disabled',
});
}
setScanner((prev) => !prev);
setSelectedProductName(null);
setVariantDetails(null);
formRef?.current?.setFieldsValue({
ProdId: null,
VarProdId: null,
});
};
const PurchaseOrderStyle = `<style>
@media print {
@page {
size: A4;
margin: 0;
}
.Quo-Print-Body {
width: 195mm;
margin: 0 auto;
padding: 10mm;
}
}
.Quo-Print-Body {
margin: 0;
padding: 10px;
background: white;
font-family: Poppins, sans-serif;
}
.Quo-Print-Content {
display: flex;
flex-direction: column;
max-width: 240mm;
margin: 0 auto;
border: 1px solid rgb(170, 164, 164);
padding: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
min-height: 257mm;
background-color: white;
}
.Quo-print-Logo {
width: 50px;
height: 50px;
margin: 5px 0 0 5px;
}
.Quo-Print-ComCus {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.Quo-Print-Tabsum {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 1rem;
}
.Quo-Print-Header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.Quo-Print-Company {
display: flex;
flex-direction: column;
padding: 10px;
gap: 0.1rem;
}
.Quo-Print-Cname {
font-size: 25px;
}
.Quo-Print-address {
font-size: 19px;
display: flex;
flex-wrap: wrap;
}
.Quo-Print-Qno {
display: flex;
flex-direction: column;
padding: 5px;
gap: 0.1rem;
}
.Quo-Print-Customer {
display: flex;
flex-direction: column;
padding-left: 10px;
gap: 0.1rem;
/* Removed fixed height */
/* height: 18vh; */
}
.Horizondal-line {
border-bottom: 0.5px solid rgb(170, 164, 164);
}
.Quo-Print-Table {
display: flex;
}
.Quo-Print-ProTable {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
}
.Quo-Print-DataRow {
border-bottom: 1px solid #eee;
}
.Quo-Print-tableheader {
background-color: #f8f9fa;
border-top: 1px solid rgb(170, 164, 164);
border-bottom: 1px solid rgb(170, 164, 164);
line-height: 3rem;
}
.Quo-Print-TableData {
text-align: right;
padding: 8px;
font-size: 20px;
}
.Quo-Print-TableDataSno {
text-align: center;
padding: 8px;
font-size: 14px;
width: 60px;
}
.Quo-Print-TableDataName {
text-align: left;
padding: 8px;
font-size: 20px;
}
.Quo-Print-headingData {
text-align: center;
padding: 8px;
font-size: 22px;
font-weight: bold;
}
.Quo-Print-TableDataAmt {
text-align: right;
padding-right: 5px;
font-size: 25px;
}
.Quo-Print-Summary {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.Quo-Print-SummTableData {
text-align: right;
padding: 1px;
font-size: 22px;
}
.Quo-Print-Total {
display: flex;
justify-content: flex-end;
border: 0.5px solid black;
width: 300px;
margin-right: 10px;
font-size: 20px;
}
</style>`;
const AddProduct = async () => {
let ProductNameadd = {};
let variant;
let ProductDetail = formProductRef.current?.getFieldsValue();
console.log(typeof ProductDetail?.ProdVariantName, 'ProductDetail');
if (
ProductDetail?.OrderQty &&
ProductDetail?.ProdId &&
new RegExp(`^P${AppId}(-[0-9]+)+$`).test(ProductDetail.ProdId)
) {
let ProductName = PurProductdata?.find(
(item) => item?.ProdId === ProductDetail?.ProdId
);
if (!ProductName) {
setMessage({ type: 'error', data: 'Please Enter Product Details' });
return;
}
if (ProductDetail?.hasOwnProperty('ProdVariantName')) {
variant = ProductDetail?.ProdVariantName
? ProductDetail?.ProdVariantName
: 'Variant 1';
delete ProductDetail?.ProdVariantName;
ProductNameadd = {
ProdName:
ProductName?.ProdName +
'(' +
ProductName?.Size +
ProductName?.UomName +
')',
ProdVariantName: variant,
...ProductDetail,
};
} else {
ProductNameadd = {
ProdName:
ProductName?.ProdName +
'(' +
ProductName?.Size +
ProductName?.UomName +
')',
ProdVariantName: 'Variant 1',
UomName: ProductName?.UomName,
...ProductDetail,
};
}
if (ProductTableData?.length > 0) {
let filterTableData = ProductTableData?.filter(
(item) =>
!(
item.ProdId === ProductNameadd?.ProdId &&
item.ProdVariantName === ProductNameadd?.ProdVariantName
)
);
setProductTableData([ProductNameadd, ...filterTableData]);
} else {
setProductTableData([ProductNameadd]);
}
console.log(ProductTableData, 'ProductDetailProductDetail');
} else if (ProductDetail?.OrderQty && ProductDetail?.QRCode) {
let ProductName = PurProductdata?.find(
(item) => item?.QRCode === ProductDetail?.QRCode
);
if (ProductDetail?.hasOwnProperty('ProdVariantName')) {
variant = ProductDetail?.ProdVariantName
? ProductDetail?.ProdVariantName
: 'Variant 1';
delete ProductDetail?.ProdVariantName;
ProductNameadd = {
ProdName:
ProductName?.ProdName +
'(' +
ProductName?.Size +
ProductName?.UomName +
')',
ProdVariantName: variant,
...ProductDetail,
};
} else {
ProductNameadd = {
ProdName:
ProductName?.ProdName +
'(' +
ProductName?.Size +
ProductName?.UomName +
')',
ProdVariantName: 'Variant 1',
...ProductDetail,
};
}
if (ProductTableData?.length > 0) {
let filterTableData = ProductTableData?.filter(
(item) =>
!(
item.ProdId === ProductNameadd?.ProdId &&
item.ProdVariantName === ProductNameadd?.ProdVariantName
)
);
setProductTableData([ProductNameadd, ...filterTableData]);
} else {
setProductTableData([ProductNameadd]);
}
} else {
setMessage({ type: 'error', data: 'Please Enter Product Details' });
}
// after adding reset field values
formProductRef?.current?.resetFields();
setselectedPurProductData(null);
setSelProductVariant(null);
setEdit(false);
setSelectedProductName(null);
};
const cancelEdit = (e) => {
e.preventDefault();
e.stopPropagation();
formProductRef.current?.resetFields();
setCurrentIndex(null);
setEdit(false);
setSelectedProductName(null);
setSelProductVariant(null);
};
const updateProduct = async (e) => {
e.preventDefault();
e.stopPropagation();
let productDetail = formProductRef.current?.getFieldsValue();
console.log(productDetail, 'productDetail');
if (!productDetail?.OrderQty || !productDetail?.ProdId) {
console.error('Please fill all required product details');
return;
}
// Find product name from PurProductdata
let ProductName = PurProductdata?.find(
(item) => item?.ProdId === productDetail?.ProdId
);
// Determine variant
let variant = productDetail?.ProdVariantName
? productDetail?.ProdVariantName
: 'Variant 1';
let updatedProduct = {
ProdName:
ProductName?.ProdName +
'(' +
ProductName?.Size +
ProductName?.UomName +
')',
ProdVariantName: variant,
...productDetail,
};
// Check if product already exists (excluding current index)
let exists = ProductTableData.some(
(item, index) =>
index !== currentIndex && // exclude current editing row
item.ProdId === updatedProduct.ProdId &&
item.ProdVariantName === updatedProduct.ProdVariantName
);
if (exists) {
setMessage({ type: 'error', data: 'Product Already Exists' });
return;
}
// Update product in the table
let newData = [...ProductTableData];
newData[currentIndex] = updatedProduct;
setProductTableData(newData);
// Reset form state
formProductRef?.current?.resetFields();
setselectedPurProductData(null);
setSelProductVariant(null);
setEdit(false);
setCurrentIndex(null);
setSelectedProductName(null);
};
console.log(ProductTableData, 'ProductDetailProductDetail');
const onComplete = useCallback(() => {
setMessage({ type: null, data: null });
}, []);
const columns = [
{
title: 'Sl.No',
align: 'center',
key: 'sno',
width: '50px',
render: (text, object, index) => (
<a style={{ color: 'black' }}>{index + 1}</a>
),
},
{
title: 'Product Name',
dataIndex: 'ProdName',
key: 'ProdName',
width: '50px',
// align: "right",
render: (text) => <a style={{ color: 'black' }}>{text}</a>,
},
{
title: 'Variant Name',
dataIndex: 'ProdVariantName',
key: 'ProdVariantName',
width: '50px',
// align: "right",
render: (text) => <a style={{ color: 'black' }}>{text}</a>,
},
{
title: 'Quantity',
dataIndex: 'OrderQty',
key: 'OrderQty',
width: '20px',
align: 'right',
render: (text) => <a style={{ color: 'black' }}>{text}</a>,
},
{
title: 'Action',
dataIndex: 'Action',
width: '60px',
key: 'Action',
render: (_, record, index) => (
<Space size="middle">
<a>
<EditFilled
style={{
color: isSubmitted ? '#ccc' : '#1292EE',
cursor: isSubmitted ? 'not-allowed' : 'pointer',
}}
onClick={() => !isSubmitted && actionsFormatter(record, index)}
/>
</a>
<a>
<DeleteFilled
style={{
color: isSubmitted ? '#ccc' : '#FF4D4F',
cursor: isSubmitted ? 'not-allowed' : 'pointer',
}}
onClick={() => !isSubmitted && statusFormatter(index)}
/>
</a>
</Space>
),
},
];
const statusFormatter = (index) => {
setProductTableData((prevData) => {
const rows = [...prevData];
rows.splice(index, 1);
if (index === currentIndex) {
formProductRef.current?.resetFields();
setCurrentIndex(null);
setEdit(false);
setSelectedProductName(null);
setSelProductVariant(null);
} else if (index < currentIndex) {
setCurrentIndex((prev) => prev - 1);
}
return rows;
});
};
const actionsFormatter = async (record, index) => {
setEdit(true);
setCurrentIndex(index);
console.log(record, index, 'actionsFormatter');
let x = PurProductdata.find((e) => e.ProdId == record?.ProdId)?.ProdName;
let variantValues1 = await dispatch(
getPurProdvaraiantdata({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
prodName: x,
})
).unwrap();
if (variantValues1?.data?.statusCode === 1) {
console.log(variantValues1?.data?.data, 'productdetail');
setVariantDetails(
variantValues1?.data?.data?.[0]?.ProductDetail?.[0]?.ProdVariantDetails
);
} else {
setVariantDetails(null);
}
formProductRef.current?.setFieldsValue({
ProdId: record?.ProdId,
OrderQty: record?.OrderQty,
ProdVariantName: record?.ProdVariantName,
});
setselectedPurProductData(record?.ProdId);
setSelProductVariant(record?.ProdVariantName);
setSelectedProductName(record?.ProdName);
};
const onFinish = async () => {
if (ProductTableData?.length === 0) {
setMessage({ type: 'error', data: 'Please Enter Product Detail' });
} else {
let PostData = {};
PostData = formRef.current?.getFieldsValue();
PostData['OrderDetails'] = ProductTableData;
PostData['AppId'] = AppId;
PostData['CompId'] = CompId;
PostData['BranchId'] = BranchId;
PostData['PurOrderDate'] = new Date().toJSON();
PostData['CreatedBy'] = UserId;
PostData['LocationType'] = Supplierdata?.find(
(find) => find.SuppId === selecPurSupplier
)?.Type;
PostData['DeliveryAddressDetails'] = deliveryAddress;
let PostPurOrder = await dispatch(postPurcOrderData(PostData)).unwrap();
if (PostPurOrder?.data?.statusCode === 1) {
setMessage({ type: 'success', data: PostPurOrder?.data?.response });
ProductStockFun();
const orderData = {
OrderId: PostPurOrder?.data?.OrderId,
PurOrderDate: PostData.PurOrderDate,
SupplierName: selecPurSupplierDetails?.[0]?.SuppName,
SuppMobile: selecPurSupplierDetails?.[0]?.SuppMobile,
SuppGSTIN: selecPurSupplierDetails?.[0]?.SuppGSTIN,
SuppEmail: selecPurSupplierDetails?.[0]?.SuppEmail,
Remarks: PostData.Remarks,
ProductDetails: ProductTableData,
};
// Set all necessary states
setSubmittedOrderData(orderData);
setPrintData([orderData]);
setIsSubmitted(true);
// Reset form fields
formProductRef?.current?.resetFields();
formRef?.current?.resetFields();
deliveryAddressRef?.current?.resetFields();
setDeliveryAddress('');
setselecPurSupplier(null);
getProductDatas(null);
setselecSuppDetails(null);
setselectedPurProductData(null);
setSelProductVariant(null);
setProductTableData([]);
setSelectedProductName(null);
// navigate(`${subDirectory}purchaseordermail`, {
// state: {
// selecPurSupplierDetails: selecPurSupplierDetails,
// OrderId: PostPurOrder?.data?.OrderId,
// ProductTableData: ProductTableData,
// },
// });
} else {
setMessage({ type: 'error', data: PostPurOrder?.data?.response });
}
}
};
// Suppier details
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'],
});
deliveryAddressRef.current?.setFieldsValue({
City: response[0]['PostOffice'][0]['Block'],
Dist: response[0]['PostOffice'][0]['District'],
State: response[0]['PostOffice'][0]['State'],
});
} else {
setZipCodeData(false);
}
};
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) {
setMessage({ type: 'success', data: response?.data?.response });
formSupplierRef?.current?.resetFields();
setZipCodeData(false);
setOpenPurSupplierModel(false);
setDeliveryValue();
setDicountValue();
setQualityValue();
setViewDtl(false);
let response1 = await dispatch(
getSupplierData({
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
ActiveStatus: 'A',
})
).unwrap();
if (response1.data?.statusCode == 1) {
setOpenPurSupplierModel(false);
}
} else {
setMessage({ type: 'error', data: response?.data?.response });
formSupplierRef?.current?.resetFields();
}
};
const handleSupplier = () => {
setOpenPurSupplierModel(false);
formSupplierRef?.current?.resetFields();
setZipCodeData(false);
};
// const handleEmailClick = () => {
// if (!submittedOrderData) {
// setMessage({ type: 'error', data: 'Please submit the order first before sending email' });
// return;
// }
// navigate(`${subDirectory}purchaseordermail`, {
// state: {
// selecPurSupplierDetails: selecPurSupplierDetails,
// ProductTableData: ProductTableData,
// orderData: submittedOrderData,
// },
// });
// };
const handleEmailClick = async (ProductDetails, record) => {
const toEmail = record?.SuppEmail;
if (toEmail) {
try {
const blob = await pdfDiv('Pur-Order-Print', PurchaseOrderStyle);
console.log(blob, 'blobblob');
const payload = {
fileBlob: blob,
toEmail: toEmail,
type: 'PurchaseOrder',
messageTemplatesList: [],
};
const res = await dispatch(Emailsend(payload))?.unwrap();
console.log('✅ API Response:', res?.data || res);
setMessage({ type: 'success', data: 'Email sent successfully' });
} catch (error) {
setMessage({ type: 'error', data: 'Email failed to send' });
console.error('❌ Email send failed:', error);
}
} else {
setPendingOrderDetails(ProductDetails);
setPendingRecord(record);
setiSEmail(true);
}
};
const handleSendEmailWithEnteredEmail = async (values) => {
const recordWithEmail = { ...pendingRecord, SuppEmail: values.email };
setiSEmail(false);
await handleEmailClick(pendingOrderDetails, recordWithEmail);
setPendingOrderDetails(null);
setPendingRecord(null);
form.resetFields();
};
const handlePrint = () => {
setPrintData([submittedOrderData]);
setPrintTrigger(true); // trigger print after render
};
useEffect(() => {
if (printTrigger && PrintData.length > 0) {
setTimeout(() => {
let style;
if (selectedStyleData) {
style = stylesMap[selectedStyleData]
? PrintStyleFunction(selectedStyleData)
: PurchaseOrderStyle;
} else {
style = PurchaseOrderStyle;
}
const styleName =
selectedStyleData == undefined ? 'Style 13' : selectedStyleData;
const selectedStyle = stylesMap[styleName] || 'Style 13';
// printDiv(`${selectedStyle}`, style);
setPrintTrigger(false);
if (isMobile) {
PurchaseOrderMobilePrint({
PrintTempData: selectedStyleData,
PrintOrderDetails: PrintData,
setPrintOrderDetails: setPrintData,
});
} else {
printDiv(selectedStyle, style);
}
}, 100);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [printTrigger, PrintData, selectedStyleData]);
const handleModalSubmited = () => {
setIsModalOpen(false);
getProductDatas(selecPurSupplier);
};
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 = () => {
if (ViewDtl) {
setViewDtl(false);
} else {
setViewDtl(true);
}
};
const handleAddressSubmit = async () => {
try {
const values = await deliveryAddressRef.current?.validateFields();
const formattedAddress = {
Address1: values.Address1,
Address2: values.Address2,
Zip: Number(values.Zip),
City: values.City,
Dist: values.Dist,
State: values.State,
Latitude: values.Latitude ?? 0,
Longitude: values.Longitude ?? 0,
CreatedBy: UserId
};
setDeliveryAddress(formattedAddress);
setAddressModel(false);
} catch (err) {
console.log('Validation error:', err);
}
};
return (
<div className="pageOverAll">
<div className="userPage">
<div className="userPageContent">
<Messages
messageType={message.type}
messageData={message.data}
onComplete={onComplete}
/>
<div
className="formName"
style={{
display: 'flex',
justifyContent: 'space-between',
marginTop: '5px',
}}
>
<FormHeader title={'Purchase Order'} />
<div
className="pruchaseCatBTN"
onClick={() => navigate(`${subDirectory}setting/purchase-order`)}
>
<FaEye /> <p>View Order</p>
</div>
</div>
<div className="formDiv" style={{ paddingTop: '0px', rowGap: '0px' }}>
<Form
ref={formRef}
// initialValues={editstate}
className="formDivAnt"
onFinish={onFinish}
>
<div
className="formDivS"
style={{ paddingTop: '0px', rowGap: '0px' }}
>
<div className="inputForm">
<Form.Item
name="SuppId"
rules={[
{
required: true,
message: 'Please Select Supplier',
},
]}
>
<div
className="supplierRating"
style={{ position: 'relative', width: '250px' }}
>
<DropDowns1
className="field-DropDown"
value={selecPurSupplier}
onChange={handleSupplierDropDownChange}
label={'Supplier Name'}
isOnchanges={selecPurSupplier ? true : false}
options={Supplierdata?.map((option) => ({
value: option.SuppId,
label: (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
}}
>
<label>
{option.SuppName + ' ' + `(${option.Type})`}
</label>
{option.DeliveryPerformanceImage && (
<img
src={option.DeliveryPerformanceImage}
alt=""
style={{
width: 20,
height: 20,
marginLeft: 8,
}}
/>
)}
</div>
),
searchLabel: option.SuppName, // <<--- Add this line
}))}
/>
{/* {renderPerformanceImg(selecSuppDetails?.DeliveryPerformance)} */}
</div>
<Tooltip title="Add Supplier" placement="top">
<PlusCircleOutlined onClick={addPurSupplier} />
</Tooltip>
</Form.Item>
<div className='deliveryaddress'>
{selecSuppDetails !== null &&
(() => {
const fields = [];
if (selecSuppDetails?.SuppName) {
fields.push(
<p>
<strong>Name:</strong> {selecSuppDetails.SuppName}
</p>
);
}
if (selecSuppDetails?.Address1) {
fields.push(
<p>
<strong>Address:</strong>{' '}
{selecSuppDetails.Address1}
</p>
);
}
if (selecSuppDetails?.SuppMobile) {
fields.push(
<p>
<strong>Mobile Number:</strong>{' '}
{selecSuppDetails.SuppMobile}
</p>
);
}
if (selecSuppDetails?.DiscountLevel) {
fields.push(
<p>
<strong>Discount Level:</strong>{' '}
{selecSuppDetails.DiscountLevel}
</p>
);
}
if (selecSuppDetails?.QualityofSupp) {
fields.push(
<p>
<strong>Quality of Supplier:</strong>{' '}
{selecSuppDetails.QualityofSupp}
</p>
);
}
if (selecSuppDetails?.OtherInfo) {
fields.push(
<p>
<strong>Other Info:</strong>{' '}
{selecSuppDetails.OtherInfo}
</p>
);
}
const firstColumn = fields.slice(0, 3);
const secondColumn = fields.slice(3);
return (
<div
style={{
display: 'flex',
columnGap: '2rem',
flexWrap: 'wrap',
}}
>
<div>
<h3>{`${selecSuppDetails?.Type} Details:`}</h3>
{firstColumn}
</div>
{secondColumn.length > 0 && (
<div>
<p>
<br />
</p>
{secondColumn}
</div>
)}
</div>
);
})()}
</div>
<div
className="lowStock-button"
onClick={() => setisLowStockModel(true)}
>
<IoWarningOutline size={18} />
<span>Low Stock</span>
</div>
{!deliveryAddress && <div
className="Address-button"
onClick={() => setAddressModel(true)}
>
<span>Delivery Address</span>
</div>}
{deliveryAddress && (
<div className="deliveryaddress">
<strong className='deliveryaddress_edit' onClick={() => setAddressModel(true)}>Delivery Address Details: <CiEdit size={18} /></strong>
{deliveryAddress?.Address1 && <p>
<strong>Address:</strong>{' '}
{deliveryAddress?.Address1}
</p>}
{deliveryAddress?.City && <p>
<strong>City:</strong> {deliveryAddress?.City}
</p>}
{deliveryAddress?.Dist && <p>
<strong>district:</strong> {deliveryAddress?.Dist}
</p>}
{deliveryAddress?.State && <p>
<strong>State:</strong> {deliveryAddress?.State}
</p>}
{deliveryAddress?.Zip && <p>
<strong>Zip:</strong> {deliveryAddress?.Zip}
</p>}
</div>
)}
</div>
{(() => {
const styleName =
selectedStyleData === undefined
? 'Style 13'
: selectedStyleData;
const selectedStyle =
stylesMap[styleName] || stylesMap['Style 13'];
return (
<div style={{ display: 'none' }}>
<PurchaseOrderPrint
PrintingData={PrintData}
selectedStyleData={selectedStyle}
/>
</div>
);
})()}
{/* <div style={{ display: 'none' }} >
<PurchaseOrderPrint
PrintingData={PrintData}
selectedStyleData={selectedStyleData}
/>
</div> */}
<Form ref={formProductRef}>
<div className="inputForm" style={{ marginTop: '2rem' }}>
<Form.Item
name="ProdId"
// rules={[
// {
// required: true,
// message: "Please Select Product Name",
// },
// ]}
>
{/* <DropDowns
// options={PurProductdata?.map((option) => ({
// value: option.ProdId,
// label: option.ProdName + "( " + option.Size + " " + option.UomName + " )",
// }))}
options={PurProductdata?.map((option) => ({
value: option.ProdId,
label:
option.ProdName +
'( ' +
option.Size +
' ' +
option.UomName +
' )',
}))}
filterOption={(input, option) => {
const product = PurProductdata.find(
(p) => p.ProdId === option.value
);
const nameMatch = option.label
.toLowerCase()
.includes(input.toLowerCase());
const qrMatch =
product?.QRCode?.toLowerCase() ==
input.toLowerCase();
console.log(
qrMatch,
'qrMatch',
product?.QRCode?.toLowerCase(),
input.toLowerCase()
);
return nameMatch || qrMatch;
}}
label={'Product Name'}
className="field-DropDown"
onChangeFunction={(e) => PurcProductDropDownChange(e)}
valueData={selectedPurProductData}
disabled={Edit ? true : false}
/> */}
<div className="product-name-scan">
<FloatLabel
label={'Product Name'}
value={selectedProductName}
>
<AutoComplete
className="field-DropDown productNameDDAuto"
value={selectedProductName}
filterOption={(input, option) => {
const product = PurProductdata.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
? PurProductdata?.map((option) => ({
value: option.ProdId,
label: `${option.ProdName} (${option.Size} ${option.UomName})${option?.BrandName ? ` - ${option?.BrandName}` : ''}`,
}))
: []
}
onSelect={PurcProductDropDownChange}
onChange={handleProductSearch}
onKeyDown={(e) => {
if (scanner && e.key === 'Enter') {
e.preventDefault();
}
}}
></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>
</Form.Item>
<Tooltip
title={'Supplier Product Mapping'}
placement={'top'}
>
<FaLink onClick={() => setIsModalOpen(true)} />
</Tooltip>
{isModalOpen && (
<SupplierProductMappingForm
isModalOpen={isModalOpen}
setIsModalOpen={() => setIsModalOpen(false)}
CompId={CompId}
BranchId={BranchId}
AppId={AppId}
setMessage={setMessage}
onMappingAdded={handleModalSubmited}
/>
)}
{/* <Form.Item
name="QRCode"
rules={[
{
validator: async (_, value) => {
await validateSafeInput(value); // To block HTML tags & SQL keywords
return Promise.resolve();
},
},
]}
>
<InputField
autoComplete="off"
label={"QR Code"}
onChange={(e) => handleQRCodeChange(e)}
/>
</Form.Item> */}
{VariantDetails?.length > 1 && (
<Form.Item name="ProdVariantName">
<DropDowns
options={VariantDetails?.map((option) => ({
value: option.ProdVariantName,
label: option.ProdVariantName,
}))}
label={'Variant Name'}
className="field-DropDown"
onChangeFunction={(e) =>
ProductVariantDropDownChange(e)
}
valueData={SelProductVariant}
// disabled={Edit ? true : false}
/>
</Form.Item>
)}
<div style={{ width: '160px' }}>
<Form.Item
name="OrderQty"
rules={[
{
required: true,
pattern: /^[1-9]\d*(\.\d+)?$/,
message: 'Please Enter Quantity',
},
{
validator: async (_, value) => {
await validateSafeInput(value);
if (value?.length > 10) {
return Promise.reject(
'Quantity cannot exceeds more than 10 chars'
);
}
return Promise.resolve();
},
},
]}
>
<InputField
label={
<label class="required">Purchase Quantity</label>
}
autocomplete="off"
isOnChange={
formProductRef.current?.getFieldsValue()?.OrderQty
? true
: false
}
inputMode="numeric"
onInput={(e) =>
(e.target.value = e.target.value.replace(
/[^0-9]/g,
''
))
}
/>
</Form.Item>
</div>
{!Edit ? (
<div
className="addVariant"
onClick={() => !isSubmitted && AddProduct()}
style={{
cursor: isSubmitted ? 'not-allowed' : 'pointer',
opacity: isSubmitted ? 0.5 : 1,
}}
>
{'Add'}
</div>
) : (
<div className="update-and-cancel">
<button onClick={updateProduct}>Update</button>
<button onClick={cancelEdit}>Cancel</button>
</div>
)}
<div className="component-table-purchae">
<Tables
columns={columns}
data={ProductTableData}
dataSource={ProductTableData}
/>{' '}
</div>
</div>
</Form>
</div>
<div
style={{
display: 'flex',
gap: '2rem',
alignItems: 'center',
width: '100%',
justifyContent: 'flex-end',
}}
>
<Buttons
buttonText="SUBMIT"
color="901D77"
icon={<ArrowRightOutlined />}
/>
{isSubmitted && (
<>
<div>
<MdOutlineMail
size={39}
color="#25D366"
style={{ cursor: 'pointer' }}
onClick={() =>
handleEmailClick(
submittedOrderData.ProductDetails,
submittedOrderData
)
}
title="Share by Email"
/>
</div>
<div>
<FaPrint
size={32}
color="#1292EE"
style={{ cursor: 'pointer' }}
onClick={handlePrint}
title="Print"
/>
</div>
</>
)}
</div>
</Form>
</div>
<DefaultModal
title="Add Supplier"
open={OpenPurSupplierModel}
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 && value.length > 30) {
return Promise.reject(
'Supplier Name should not exceed 30 characters'
);
}
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', cursor: 'pointer' }}
onClick={ViewMoreFields}
>
{' '}
{ViewDtl ? 'View Less' : '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>
<DefaultModal
width={400}
open={iSEmail}
title="User Mail"
handleCancel={() => setiSEmail(false)}
footer={false}
children={
<div>
<Form
form={form}
layout="vertical"
onFinish={handleSendEmailWithEnteredEmail}
>
<Form.Item
label="Mail ID"
name="email"
rules={[
{ required: true, message: 'Email is required' },
{ type: 'email', message: 'Enter a valid email address' },
]}
>
<Input autoComplete="off" placeholder="Enter your email" />
</Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form>
</div>
}
/>
<DefaultModal
width={600}
open={isLowStockModel}
title="Low Stock Products"
handleCancel={() => setisLowStockModel(false)}
footer={false}
children={
<div>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: '15px',
}}
>
<input
type="text"
placeholder="Search Product..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{
padding: '8px 10px',
width: '60%',
border: '1px solid #ccc',
borderRadius: '6px',
}}
/>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
}}
>
<label style={{ fontSize: '14px' }}>Min Qty:</label>
<input
type="number"
placeholder="0"
value={minQty}
onChange={handleMinQtyChange}
style={{
padding: '8px 10px',
width: '80px',
border: '1px solid #ccc',
borderRadius: '6px',
textAlign: 'center',
}}
min="0"
/>
</div>
</div>
<div className="ItemWiseReport-table">
<table
className="custom-table"
style={{ width: '100%', borderCollapse: 'collapse' }}
>
<thead>
<tr>
<th style={{ textAlign: 'center' }}>SI NO</th>
<th style={{ textAlign: 'center' }}>Product Name</th>
<th style={{ textAlign: 'center' }}>Balance Qty</th>
<th style={{ textAlign: 'center' }}>Required Qty</th>
</tr>
</thead>
<tbody>
{currentData.length > 0 ? (
currentData.map((row, idx) => (
<tr key={idx}>
<td style={{ textAlign: 'center' }}>
{startIndex + idx + 1}
</td>
<td style={{ textAlign: 'left' }}>
{row.ProdName} ({row.ProdVariantName})
</td>
<td style={{ textAlign: 'center' }}>
{row.BalanceQty}
</td>
<td style={{ textAlign: 'center' }}>
<input
type="number"
style={{ width: '80px', textAlign: 'center' }}
value={row.needQty || ''}
onChange={(e) => {
const newQty = e.target.value;
seProductStockData((prev) =>
prev.map((item, i) =>
i === startIndex + idx
? { ...item, needQty: newQty }
: item
)
);
}}
min="0"
/>
</td>
</tr>
))
) : (
<tr>
<td
colSpan="4"
style={{ textAlign: 'center', padding: '10px' }}
>
Data not found
</td>
</tr>
)}
</tbody>
</table>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
marginTop: '20px',
gap: '10px',
}}
>
<p
onClick={handlePrevious}
style={{
padding: '8px 12px',
border: '1px solid #ccc',
cursor: currentPage === 1 ? 'not-allowed' : 'pointer',
opacity: currentPage === 1 ? 0.5 : 1,
}}
>
&lt;
</p>
<span
style={{
margin: '0',
fontFamily: 'Poppins',
fontSize: '14px',
}}
>
Page {currentPage} of {totalPages}
</span>
<p
onClick={handleNext}
style={{
padding: '8px 12px',
border: '1px solid #ccc',
cursor:
currentPage === totalPages ? 'not-allowed' : 'pointer',
opacity: currentPage === totalPages ? 0.5 : 1,
}}
>
&gt;
</p>
</div>
<div style={{ display: 'flex', justifyContent: 'end' }}>
<div
onClick={handleSaveLowStock}
className="lowStock-SaveButton"
>
SAVE
</div>
</div>
</div>
}
/>
{/* Address model */}
<DefaultModal
width={600}
open={addressModel}
title="Delivery Address"
handleSubmit={handleAddressSubmit}
buttonText="Submit"
handleCancel={() => setAddressModel(false)}
footer={true}
children={
<div>
<Form ref={deliveryAddressRef} className="formDivAnt">
<div className="subRowFlex">
<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="Address2"
rules={[
{
required: true,
pattern: /^(?!\s*$).+/,
message: 'Please Enter Address2',
},
{
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>
{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>
</div>
}
/>
</div>
</div >
</div >
);
};
export default PurchaseOrder;