Android_Retail/src/Pages/StockinHand/StockinHand.jsx

586 lines
21 KiB
JavaScript

import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { Space, DatePicker, Checkbox, Input } from 'antd';
import {
PlusOutlined,
} from '@ant-design/icons';
import {
changeBreadCrumb,
} from '../../Features/AppPage/CenterPage.js';
import { Tables } from '../../Components/Tables/Table';
import FormHeader from '../PageComponents/FormHeader.jsx';
import { useNavigate, useLocation } from 'react-router-dom';
import Buttons from '../../Components/Forms/Buttons';
import { getSession } from '../../Services/Others';
import { Messages } from '../../Components/Notifications/Messages';
import dayjs from 'dayjs';
import { SearchIcon } from 'lucide-react';
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
import "./stockinhand.scss"
import { getConfigTypeData } from '../../Features/ConfigMasterPage/ConfigMasterPage.js';
import { getStocksinHand } from '../../Features/StockinHand/StockinHand.js';
import { Search } from '../../../ownLib/my-ui-lib.js';
const subDirectory = import.meta.env.BASE_URL;
const { RangePicker } = DatePicker;
const items = [
{
name: 'Home',
link: `${subDirectory}app-page/home`,
},
{
name: 'Stock In Hand',
link: `${subDirectory}report/stock-in-hand`,
},
];
const StockInhand = () => {
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const AppId = getSession('AppId');
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [TableData, setTableData] = useState([]);
const [filteredInfo, setFilteredInfo] = useState({});
const [sortedInfo, setSortedInfo] = useState({});
const [searchedText, setSearchedText] = useState('');
const [searchedTextdata, setsearchedTextdata] = useState('');
const [sortConfig, setSortConfig] = useState({ key: null, direction: null });
const [page, setpage] = useState(1);
const [OrderFromDate, setOrderFromDate] = useState(null);
const [OrderToDate, setOrderToDate] = useState(null);
const [selectedOptionData, setselectedOptionData] = useState(null);
const [SearchMethodDatas, setSearchMethodDatas] = useState([]);
const [Checkgodown, setCheckgodown] = useState(null)
console.log(Checkgodown, "Checkgodown")
useEffect(() => {
getSearchMethods()
if (location.state?.message) {
setMessageType(location.state.type);
setMessageData(location.state.message);
}
dispatch(changeBreadCrumb({ items: items }));
}, []);
async function getSearchMethods() {
try {
let Res = await dispatch(getConfigTypeData({ TypeName: "Stock In Hand Search Methods" })).unwrap()
if (Res?.data?.statusCode == 1) {
setSearchMethodDatas(Res?.data?.data)
let Data = Res?.data?.data?.find((e) => e?.ConfigName == "Product Name")
setselectedOptionData(Data?.ConfigId)
setCheckgodown(Data?.ConfigName)
}
}
catch (err) {
console.log('error', err?.message)
}
}
// const handleChange = (pagination, filters, sorter) => {
// setFilteredInfo(filters);
// setSortedInfo(sorter);
// };
// const handlePageChange = (current) => {
// setpage(current);
// };
const handleSort = (key) => {
let direction = 'asc';
if (sortConfig.key === key && sortConfig.direction === 'asc') {
direction = 'desc';
}
setSortConfig({ key, direction });
};
const filteredTableData = useMemo(() => {
let filtered = TableData;
if (searchedTextdata) {
filtered = TableData.filter(item =>
item?.ProductName?.toLowerCase().includes(searchedTextdata.toLowerCase())
);
}
if (!sortConfig.key) return filtered;
return [...filtered].sort((a, b) => {
const aValue = a[sortConfig.key] ? new Date(a[sortConfig.key]) : new Date(0);
const bValue = b[sortConfig.key] ? new Date(b[sortConfig.key]) : new Date(0);
if (sortConfig.direction === 'asc') {
return aValue - bValue;
}
return bValue - aValue;
});
}, [TableData, searchedTextdata, sortConfig]);
const onSearch = (value) => {
setSearchedText(value);
};
const onSearchChange = (e) => {
setSearchedText(e?.target?.value);
};
const onSearchData = (value) => {
setsearchedTextdata(value);
};
const onSearchChangeData = (e) => {
setsearchedTextdata(e?.target?.value); s
};
// {
// title: 'Brand',
// key: 'Brand',
// dataIndex: 'Brand',
// align: 'center',
// width: '80px',
// },
// const columns = [
// {
// title: 'Sl.No',
// key: 'sno',
// align: 'center',
// width: '80px',
// render: (text, object, index) => (
// <a style={{ color: 'black', fontWeight: 450 }}>{(page - 1) * 10 + index + 1}</a>
// ),
// },
// {
// title: 'Name',
// key: 'ProductName',
// dataIndex: 'ProductName',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// // {
// // title: 'Category',
// // key: 'ProdCatName',
// // dataIndex: 'ProdCatName',
// // align: 'center',
// // width: '80px',
// // render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// // },
// // {
// // title: 'Sub.Category',
// // key: 'ProdSubCatName',
// // dataIndex: 'ProdSubCatName',
// // align: 'center',
// // width: '80px',
// // render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// // },
// {
// title: 'Variant',
// key: 'ProdVariantName',
// dataIndex: 'ProdVariantName',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'Qty',
// key: 'BalanceQty',
// dataIndex: 'BalanceQty',
// align: 'center',
// width: '80px',
// render: (text, record, index) => {
// return <span style={{ fontWeight: 600, color: (typeof text === 'number' && text <= 0) || !text ? 'red' : 'black' }}> {text ?? 0} </span>
// }
// },
// {
// title: 'Batch',
// key: 'BatchRef',
// dataIndex: 'BatchRef',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'Barcode',
// key: 'QRCode',
// dataIndex: 'QRCode',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'IMEI 1',
// key: 'IMEI1',
// dataIndex: 'IMEI1',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'IMEI 2',
// key: 'IMEI2',
// dataIndex: 'LegalName',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'Rack',
// key: 'RackName',
// dataIndex: 'RackName',
// align: 'center',
// width: '80px',
// render: (text) => <span style={{ color: text ? 'black' : '#999', fontWeight: 450 }}>{text ?? ''}</span>
// },
// {
// title: 'Received Date',
// key: 'InwardDate',
// dataIndex: 'InwardDate',
// align: 'center',
// width: '120px',
// render: (text, record) => (
// <span style={{ color: record?.InwardDate ? 'black' : '#999', fontWeight: 450 }}>{record?.InwardDate ? dayjs(record?.InwardDate).format('DD-MM-YYYY') : ''}</span>
// ),
// sorter: (a, b) => {
// const da = a?.InwardDate ? new Date(a.InwardDate) : 0;
// const db = b?.InwardDate ? new Date(b.InwardDate) : 0;
// return da - db;
// },
// sortDirections: ['ascend', 'descend'],
// },
// {
// title: 'Mfg Date',
// key: 'MfgDate',
// dataIndex: 'MfgDate',
// align: 'center',
// width: '120px',
// render: (text, record) => (
// <span style={{ color: record?.MfgDate ? 'black' : '#999', fontWeight: 450 }}>{record?.MfgDate ? dayjs(record?.MfgDate).format('DD-MM-YYYY') : ''}</span>
// ),
// sorter: (a, b) => {
// const da = a?.MfgDate ? new Date(a.MfgDate) : 0;
// const db = b?.MfgDate ? new Date(b.MfgDate) : 0;
// return da - db;
// },
// sortDirections: ['ascend', 'descend'],
// },
// {
// title: 'Exp Date',
// key: 'ExpDate',
// dataIndex: 'ExpDate',
// align: 'center',
// width: '120px',
// render: (text, record) => (
// <span style={{ color: record?.ExpDate ? 'black' : '#999', fontWeight: 450 }}>{record?.ExpDate ? dayjs(record?.ExpDate).format('DD-MM-YYYY') : ''}</span>
// ),
// sorter: (a, b) => {
// const da = a?.ExpDate ? new Date(a.ExpDate) : 0;
// const db = b?.ExpDate ? new Date(b.ExpDate) : 0;
// return da - db;
// },
// sortDirections: ['ascend', 'descend'],
// },
// ];
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
const OrderDateRangeFetch = (dates, dateStrings) => {
const [from, to] = dates || [];
const [fromStr, toStr] = dateStrings || [];
if (!from || !fromStr) {
setOrderFromDate(undefined);
} else {
const DateFrom = `${fromStr.split('-').reverse().join('-')}T00:00:00`;
setOrderFromDate(DateFrom);
}
if (!to || !toStr) {
setOrderToDate(undefined);
} else {
const toIso = `${toStr.split('-').reverse().join('-')}T23:59:59`;
setOrderToDate(toIso);
}
};
const searchMethodDropDownChange = (e) => {
setselectedOptionData(e);
setSearchedText('')
const isCheckGodown = SearchMethodDatas?.find(item => item?.ConfigId == e)?.ConfigName
setCheckgodown(isCheckGodown);
}
const handlePost = async () => {
if (!searchedText) {
setMessageData('Please enter the search text')
setMessageType('warning')
return
}
let GetData = {
CompId: CompId,
AppId: AppId,
BranchId: BranchId,
SearchType: selectedOptionData,
SearchText: searchedText,
OrderFromDate: OrderFromDate?.split("T")?.[0],
OrderToDate: OrderToDate?.split("T")?.[0]
}
try {
let Res = await dispatch(getStocksinHand(GetData)).unwrap()
if (Res?.data?.statusCode == 1) {
setTableData(Res?.data?.data)
setsearchedTextdata('') // Clear search input
}
else {
setTableData([])
setsearchedTextdata('') // Clear search input
setMessageData(Res?.data?.response)
setMessageType('error')
}
}
catch (err) {
console.log('error', err?.message)
}
}
return (
<div className="userPageTable">
<div className="userPageContentStockInHand">
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div>
<div className='stockinhandInputHeader'>
<FormHeader title={'Stock In Hand'} />
<div className='stockinhandInputHeader2'>
<div>
<DropDowns
options={SearchMethodDatas?.map((option) => ({
value: option?.ConfigId,
label: option?.ConfigName,
}))}
label={<label>Method Type</label>}
id="searchMethod"
field="searchMethod"
fieldState={true}
fieldApi={true}
className="field-DropDown-Emp"
onChangeFunction={(e) => searchMethodDropDownChange(e)}
isOnchanges={selectedOptionData ? true : false}
valueData={selectedOptionData}
/>
</div>
<div className="formSearch">
<Input
// ref={ref}
maxLength={50}
value={searchedText}
className="searchDiv"
placeholder={`${Checkgodown?.toLowerCase() === "godown"
? "Search By Godown Products"
: `Enter the ${Checkgodown}`
}`}
// onPressEnter={onSearch}
onChange={onSearchChange}
/>
</div>
<div>
<RangePicker
format="DD-MM-YYYY"
allowClear
disabledDate={(current) => current && current > dayjs()} // Disable future dates
onChange={(dates, dateStrings) => {
OrderDateRangeFetch(dates, dateStrings);
}}
placeholder={['From Date', 'To Date']}
style={{ width: "200px" }}
/>
</div>
</div>
<div>
<Buttons
buttonText={'Search'}
handleSubmit={handlePost}
color="901D77"
icon={<SearchIcon size={16} />}
>
OPEN
</Buttons>
</div>
</div>
</div>
<div className='searchProInputSH'>
<Search
value={searchedTextdata}
placeholder={`Search`}
onSearch={onSearchData}
onSearchChange={onSearchChangeData}
/>
</div>
{/* <div className="reportTable stockinhandTable">
<Tables
columns={columns}
data={filteredTableData}
dataSource={filteredTableData}
pagination={handlePageChange}
onChange={handleChange}
/>{' '}
</div> */}
<div className='StockinHand-table'>
<table className="product-table-stockinHand">
<thead>
<tr>
<th>Sl.No</th>
<th>Name</th>
<th>Variant</th>
<th>Balance Qty</th>
<th>Batch</th>
<th>Barcode</th>
<th>IMEI 1</th>
<th>IMEI 2</th>
<th>Rack</th>
<th>Received Date</th>
<th onClick={() => handleSort('MfgDate')} style={{ cursor: 'pointer' }}>
Mfg Date {sortConfig.key === 'MfgDate' && (sortConfig.direction === 'asc' ? '↑' : '↓')}
</th>
<th onClick={() => handleSort('ExpDate')} style={{ cursor: 'pointer' }}>
Exp Date {sortConfig.key === 'ExpDate' && (sortConfig.direction === 'asc' ? '↑' : '↓')}
</th>
</tr>
</thead>
<tbody>
{filteredTableData?.length > 0 ? (
filteredTableData?.map((item, index) => (
<tr key={index}>
<td>{(page - 1) * 10 + index + 1}</td>
<td>{item?.ProductName || ""}</td>
<td>{item?.ProdVariantName || ""}</td>
<td
style={{
fontWeight: 600,
color: !item?.BalanceQty || item?.BalanceQty <= 0 ? "red" : "black",
textAlign: "center"
}}
>
{item?.BalanceQty ?? 0}
</td>
<td>{item?.BatchRef || ""}</td>
<td>{item?.QRCode || ""}</td>
<td>{item?.IMEI1 || ""}</td>
<td>{item?.IMEI2 || ""}</td>
<td>{item?.RackName || ""}</td>
<td>
{item?.InwardDate
? dayjs(item.InwardDate).format("DD-MM-YYYY")
: ""}
</td>
<td>
{item?.MfgDate
? dayjs(item.MfgDate).format("DD-MM-YYYY")
: ""}
</td>
<td>
{item?.ExpDate
? dayjs(item.ExpDate).format("DD-MM-YYYY")
: ""}
</td>
</tr>
))) : (<tr>
<td colSpan="12" className="no-data" style={{ textAlign: "center", padding: "20px", color: "#888", fontWeight: "500" }}>
No products found
</td>
</tr>)
}
</tbody>
</table>
</div>
</div>
</div>
);
};
export default StockInhand;