299 lines
12 KiB
React
299 lines
12 KiB
React
|
|
import React, { useState, useEffect } from 'react';
|
||
|
|
import { useDispatch } from 'react-redux';
|
||
|
|
import { Space, Tooltip } from 'antd';
|
||
|
|
import { DeleteFilled, PlusCircleOutlined } from '@ant-design/icons';
|
||
|
|
import { Tables } from "../../Components/Tables/Table";
|
||
|
|
import { DropDowns } from "../../Components/Forms/DropDown.jsx";
|
||
|
|
import { DefaultModal } from "../../Components/Modal/DefaultModal.jsx";
|
||
|
|
import AddSupplierModal from '../SupplierMaster/QuickAddSupplier.jsx';
|
||
|
|
import FeaturesFunctionalities from '../BookingScreen/Components/BookingFunctionality/FeaturesFunctionalities.jsx';
|
||
|
|
import {
|
||
|
|
getSupplaierProducts,
|
||
|
|
postSupplaierProducts,
|
||
|
|
getSupplaierIdBasedProducts
|
||
|
|
} from '../../Features/SupplierProductMapping/SupplierProductMapping.js';
|
||
|
|
import { getsupplierBasedOnCmpId, getsupplierBasedOnCmpIdBrId } from '../../Features/SupplierMaster/SupplierMaster.js';
|
||
|
|
|
||
|
|
const SupplierProductMappingForm = ({
|
||
|
|
isModalOpen = false,
|
||
|
|
setIsModalOpen,
|
||
|
|
CompId,
|
||
|
|
BranchId,
|
||
|
|
AppId,
|
||
|
|
setMessage,
|
||
|
|
onMappingAdded
|
||
|
|
}) => {
|
||
|
|
const dispatch = useDispatch();
|
||
|
|
|
||
|
|
// State variables
|
||
|
|
const [supplierOptions, setSupplierOptions] = useState([]);
|
||
|
|
const [productOptions, setProductOptions] = useState([]);
|
||
|
|
const [tempProductOptions, setTempProductOptions] = useState([]);
|
||
|
|
const [modelTableData, setModelTableData] = useState([]);
|
||
|
|
const [addProduct, setAddProduct] = useState(false);
|
||
|
|
const [dropdownKey, setDropdownKey] = useState(0);
|
||
|
|
const [modalSelectedSupplier, setModalSelectedSupplier] = useState(null);
|
||
|
|
const [modalSelectedProduct, setModalSelectedProduct] = useState(null);
|
||
|
|
const [tabledata, setTabledata] = useState([]);
|
||
|
|
const [filteredTableData, setFilteredTableData] = useState([]);
|
||
|
|
const details = {
|
||
|
|
name :"tamil",
|
||
|
|
address : {
|
||
|
|
city : "hosur"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const {address : {city}} = details
|
||
|
|
|
||
|
|
// Fetch suppliers function
|
||
|
|
const fetchSypplaiers = async () => {
|
||
|
|
try {
|
||
|
|
const response = await dispatch(getsupplierBasedOnCmpIdBrId({cmpId : CompId,BranchId,AppId}))?.unwrap();
|
||
|
|
if (response?.data?.statusCode === 1) {
|
||
|
|
const filteredData = response?.data?.data?.filter(filter => filter.ActiveStatus === 'A');
|
||
|
|
setSupplierOptions(filteredData);
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error fetching suppliers:', error);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Fetch table data function
|
||
|
|
const TableData = async () => {
|
||
|
|
try {
|
||
|
|
const response = await dispatch(getSupplaierProducts({ CompId, BranchId, AppId }))?.unwrap();
|
||
|
|
if (response?.data?.statusCode === 1) {
|
||
|
|
setTabledata(response?.data?.data);
|
||
|
|
setFilteredTableData(response?.data?.data);
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error fetching table data:', error);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle supplier selection change
|
||
|
|
const handleModelSuplaierOnChange = async (event) => {
|
||
|
|
setModalSelectedSupplier(event);
|
||
|
|
try {
|
||
|
|
const response = await dispatch(getSupplaierIdBasedProducts({ CompId, BranchId, AppId, SuppId: event }))?.unwrap();
|
||
|
|
if (response?.data?.statusCode === 1) {
|
||
|
|
setTempProductOptions(response?.data?.data?.[0]?.ProductDetails);
|
||
|
|
setProductOptions(response?.data?.data?.[0]?.ProductDetails);
|
||
|
|
setModelTableData([]);
|
||
|
|
setModalSelectedProduct(null);
|
||
|
|
setDropdownKey(prev => prev + 1);
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error fetching supplier products:', error);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle product selection change
|
||
|
|
const handleModelProductOnChange = (prodId) => {
|
||
|
|
setModalSelectedProduct(null);
|
||
|
|
setDropdownKey(prev => prev + 1);
|
||
|
|
const isAlreadyAdded = modelTableData?.find(find => find.ProdId === prodId);
|
||
|
|
if (isAlreadyAdded) {
|
||
|
|
setMessage({ type: "error", data: "Product Already Added" });
|
||
|
|
} else {
|
||
|
|
setModelTableData(prev => [...prev, productOptions?.find(find => find.ProdId === prodId)]);
|
||
|
|
setProductOptions(prev => [...prev.filter(item => item.ProdId !== prodId)]);
|
||
|
|
setMessage({ type: "success", data: "Product Added Successfully" });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle product removal from table
|
||
|
|
const handleSelectedProductCancel = (prodId) => {
|
||
|
|
setModelTableData(prev => [...prev.filter(filter => filter.ProdId !== prodId)]);
|
||
|
|
setProductOptions(prev => [...prev, tempProductOptions?.find(find => find.ProdId === prodId)]);
|
||
|
|
setModalSelectedProduct(null);
|
||
|
|
setDropdownKey(prev => prev + 1);
|
||
|
|
setMessage({ type: "success", data: "Product Deleted Successfully" });
|
||
|
|
};
|
||
|
|
|
||
|
|
// Toggle add product modal
|
||
|
|
const addProductOnClick = () => {
|
||
|
|
setAddProduct(prev => !prev);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle product addition callback
|
||
|
|
const onProductAdded = async () => {
|
||
|
|
// addProductOnClick();
|
||
|
|
if (modalSelectedSupplier) {
|
||
|
|
try {
|
||
|
|
const response = await dispatch(getSupplaierIdBasedProducts({ CompId, BranchId, AppId, SuppId: modalSelectedSupplier }))?.unwrap();
|
||
|
|
if (response?.data?.statusCode === 1) {
|
||
|
|
if (modelTableData?.length > 0) {
|
||
|
|
setProductOptions(response?.data?.data?.[0]?.ProductDetails?.filter(item => !modelTableData?.some(some => some.ProdId === item.ProdId)));
|
||
|
|
} else {
|
||
|
|
setProductOptions(response?.data?.data?.[0]?.ProductDetails);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error refreshing products:', error);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
setProductOptions([]);
|
||
|
|
setModelTableData([]);
|
||
|
|
}
|
||
|
|
setAddProduct(false)
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle modal cancel
|
||
|
|
const handleModalCancel = () => {
|
||
|
|
setIsModalOpen(false);
|
||
|
|
setModalSelectedSupplier(null);
|
||
|
|
setModalSelectedProduct(null);
|
||
|
|
setModelTableData([]);
|
||
|
|
setProductOptions([]);
|
||
|
|
setTempProductOptions([]);
|
||
|
|
setDropdownKey(0);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle modal submit
|
||
|
|
const handleModalSubmit = async () => {
|
||
|
|
if (!modalSelectedSupplier) {
|
||
|
|
setMessage({ type: "error", data: "Please select a supplier" });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (modelTableData.length === 0) {
|
||
|
|
setMessage({ type: "error", data: "Please add at least one product" });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const payload = {
|
||
|
|
CompId,
|
||
|
|
BranchId,
|
||
|
|
AppId,
|
||
|
|
SuppId: modalSelectedSupplier,
|
||
|
|
ProductDetails: modelTableData.map(item => ({ ProdId: item.ProdId }))
|
||
|
|
};
|
||
|
|
|
||
|
|
const response = await dispatch(postSupplaierProducts(payload))?.unwrap();
|
||
|
|
if (response?.data?.statusCode === 1) {
|
||
|
|
setMessage({ type: "success", data: "Supplier product mapping saved successfully" });
|
||
|
|
handleModalCancel();
|
||
|
|
if (onMappingAdded) {
|
||
|
|
onMappingAdded();
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
setMessage({ type: "error", data: response?.data?.message || "Failed to save mapping" });
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error saving mapping:', error);
|
||
|
|
setMessage({ type: "error", data: "Failed to save supplier product mapping" });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Initialize data on component mount
|
||
|
|
useEffect(() => {
|
||
|
|
if (isModalOpen) {
|
||
|
|
fetchSypplaiers();
|
||
|
|
}
|
||
|
|
}, [isModalOpen, CompId]);
|
||
|
|
|
||
|
|
const tableColumns = [
|
||
|
|
{
|
||
|
|
title: "SL.No",
|
||
|
|
key: "ProdId",
|
||
|
|
align: "center",
|
||
|
|
width: "80px",
|
||
|
|
render: (text, object, index) => <span>{index + 1}</span>,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "Product Name",
|
||
|
|
dataIndex: "ProdName",
|
||
|
|
key: "ProdName",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "Action",
|
||
|
|
key: "Action",
|
||
|
|
dataIndex: "Action",
|
||
|
|
render: (_, record, index) =>
|
||
|
|
<Space size="middle">
|
||
|
|
<DeleteFilled
|
||
|
|
style={{ color: "#FF4D4F", cursor: "pointer" }}
|
||
|
|
onClick={() => handleSelectedProductCancel(record.ProdId)}
|
||
|
|
/>
|
||
|
|
</Space>
|
||
|
|
}
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<DefaultModal
|
||
|
|
open={isModalOpen}
|
||
|
|
title="Add Supplier Product Mapping"
|
||
|
|
handleCancel={handleModalCancel}
|
||
|
|
handleSubmit={handleModalSubmit}
|
||
|
|
buttonText="SAVE"
|
||
|
|
width={800}
|
||
|
|
destroyOnClose={true}
|
||
|
|
footer={true}
|
||
|
|
>
|
||
|
|
<div className="modal-content">
|
||
|
|
<div className="modal-dropdowns">
|
||
|
|
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem", position: "relative" }}>
|
||
|
|
<DropDowns
|
||
|
|
label={<label className='required'>Supplier Name</label>}
|
||
|
|
options={supplierOptions?.map(item => ({
|
||
|
|
value: item.SuppId,
|
||
|
|
label: item.SuppName ?? item.SuppMobile ?? "No Name"
|
||
|
|
}))}
|
||
|
|
valueData={modalSelectedSupplier}
|
||
|
|
onChangeFunction={handleModelSuplaierOnChange}
|
||
|
|
isOnchanges={false}
|
||
|
|
alphabetfilter="Yes"
|
||
|
|
/>
|
||
|
|
<AddSupplierModal onSupplierAdded={fetchSypplaiers} message={setMessage} />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{modalSelectedSupplier && (
|
||
|
|
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem", position: "relative" }}>
|
||
|
|
<DropDowns
|
||
|
|
key={`product-dropdown-${dropdownKey}`}
|
||
|
|
label={<label className='required'>Product Name</label>}
|
||
|
|
options={productOptions.map(item => {
|
||
|
|
const size = (item.Size === null ? "" : " (" + item.Size + " " + (item.UomName === null ? "" : item.UomName) + ") ")
|
||
|
|
const brand = item.BrandName === null ? "" : item.BrandName
|
||
|
|
return {
|
||
|
|
value: item.ProdId,
|
||
|
|
label: item.ProdName + size + brand
|
||
|
|
}
|
||
|
|
})}
|
||
|
|
valueData={modalSelectedProduct}
|
||
|
|
onChangeFunction={handleModelProductOnChange}
|
||
|
|
isOnchanges={false}
|
||
|
|
alphabetfilter="Yes"
|
||
|
|
/>
|
||
|
|
<div style={{ position: "absolute", left: "16rem", top: "1px" }}>
|
||
|
|
<Tooltip title={"Add Product"} placement={"top"}>
|
||
|
|
<PlusCircleOutlined
|
||
|
|
onClick={addProductOnClick}
|
||
|
|
style={{ cursor: "pointer", fontSize: "16px" }}
|
||
|
|
/>
|
||
|
|
</Tooltip>
|
||
|
|
<FeaturesFunctionalities
|
||
|
|
handleQuickAddCancel={onProductAdded}
|
||
|
|
QuickAdd={addProduct}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="modal-table" style={{ marginTop: "1rem" }}>
|
||
|
|
<Tables
|
||
|
|
columns={tableColumns}
|
||
|
|
data={modelTableData}
|
||
|
|
dataSource={modelTableData}
|
||
|
|
pagination={false}
|
||
|
|
rowKey="ProdId"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</DefaultModal>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default SupplierProductMappingForm;
|