reports update

This commit is contained in:
joshikannan
2025-11-14 18:42:26 +05:30
parent b27c27a444
commit 12df2e9dc4
15 changed files with 2159 additions and 633 deletions

View File

@@ -8,6 +8,7 @@ import { useTheme } from '@mui/material/styles';
import { SlLocationPin } from 'react-icons/sl';
import MapWithRoute from './mapWithRoute';
import { enqueueSnackbar } from 'notistack';
import MyLocationIcon from '@mui/icons-material/MyLocation';
// material-ui
import {
@@ -27,7 +28,6 @@ import {
IconButton,
Tooltip,
Chip,
Paper,
FormControl,
OutlinedInput,
InputAdornment,
@@ -72,6 +72,7 @@ function formatNumberToRupees(value) {
// ==============================|| MUI TABLE - ENHANCED ||============================== //
export default function OrdersDetails() {
const tenId = localStorage.getItem('tenantid');
const textFieldRef = useRef(null);
const loadMoreRef = useRef();
const containerRef = useRef();
@@ -88,29 +89,42 @@ export default function OrdersDetails() {
const [riderEnd, setRiderEnd] = useState();
const [mapOpen, setMapOpen] = useState(false);
const [mapTenant, setMapTenant] = useState({});
let [total, settotal] = useState(0);
let [coveredLenght, setCoveredLenght] = useState(0);
let [uncoveredLenght, setUncoveredLenght] = useState(0);
let [cancelLenght, setCancelLenght] = useState(0);
let [assignLenght, setAssignLenght] = useState(0);
let [pickedLenght, setPickedLenght] = useState(0);
let [activeLenght, setActiveLenght] = useState(0);
let [arrivesLenght, setArrivedLenght] = useState(0);
const [currentStatus, setCurrentStatus] = useState('All');
const [statusLabel, setStatuslabel] = useState('All');
const [statusCount, setStatusCount] = useState(0);
const [tenantLocations, setTenantlocations] = useState([]);
const [locationId, setLocationId] = useState(0);
const [locoName, setLocoName] = useState('Select Location');
const status = [
{ id: 0, status: 'All', statusLow: 'All', count: total },
{ id: 1, status: 'Pending', statusLow: 'pending', count: assignLenght },
{ id: 2, status: 'Accepted', statusLow: 'accepted', count: uncoveredLenght },
{ id: 3, status: 'Arrived', statusLow: 'arrived', count: arrivesLenght },
{ id: 4, status: 'Picked', statusLow: 'picked', count: pickedLenght },
{ id: 5, status: 'Active', statusLow: 'active', count: activeLenght },
{ id: 6, status: 'Delivered', statusLow: 'delivered', count: coveredLenght },
{ id: 7, status: 'Cancelled', statusLow: 'cancelled', count: cancelLenght }
{ id: 0, status: 'All', statusLow: 'All' },
{ id: 1, status: 'Pending', statusLow: 'pending' },
{ id: 2, status: 'Accepted', statusLow: 'accepted' },
{ id: 3, status: 'Arrived', statusLow: 'arrived' },
{ id: 4, status: 'Picked', statusLow: 'picked' },
{ id: 5, status: 'Active', statusLow: 'active' },
{ id: 6, status: 'Delivered', statusLow: 'delivered' },
{ id: 7, status: 'Cancelled', statusLow: 'cancelled' }
];
// ============================================= || gettenantlocations (branches) || =============================================
const gettenantlocations = async (id) => {
try {
const res = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantlocations/?tenantid=${id}`);
console.log('gettenantlocations', res.data.details);
if (res.data.details.length == 1) {
setIsLocation(true);
setTenantlocations(res.data.details);
setPickCust(res.data.details[0]);
} else {
setTenantlocations(res.data.details);
}
} catch (err) {
console.log('gettenantlocations', err);
}
};
useEffect(() => {
gettenantlocations(tenId);
}, []);
const getdeliverylogs = async (id) => {
console.log('deliveryid', id);
try {
@@ -162,15 +176,6 @@ export default function OrdersDetails() {
// ==============================|| fetchorderdetails (orders)||============================== //
// const {
// isLoading: isLoadingOrderDetails,
// isError: isErrorOrderDetails, //true or false
// data: rows,
// error: orderDetailsError
// } = useQuery({
// queryKey: [startdate, enddate, currentStatus],
// queryFn: fetchorderdetails
// });
const {
data: rowdata,
isError: isErrorOrderDetails,
@@ -181,7 +186,7 @@ export default function OrdersDetails() {
isFetchingNextPage
// status: rowdataStatus
} = useInfiniteQuery({
queryKey: [startdate, enddate, currentStatus],
queryKey: [startdate, enddate, currentStatus, locationId],
queryFn: fetchorderdetails,
getNextPageParam: (lastPage) => lastPage.nextPage
});
@@ -212,13 +217,8 @@ export default function OrdersDetails() {
// ==================================== || fetchDeliverySummary || ====================================
const {
data: deliverycount,
isLoading,
isError,
error
} = useQuery({
queryKey: ['deliverycount', startdate, enddate, currentStatus],
const { data: deliverycount } = useQuery({
queryKey: ['deliverycount', startdate, enddate, currentStatus, locationId],
queryFn: fetchDeliverySummary
});
@@ -266,7 +266,6 @@ export default function OrdersDetails() {
// ==============================|| fetchAppLocations ||============================== //
if (isLoadingOrderDetails) return <Loader />;
if (isErrorOrderDetails) return 'An error has occurred:(isErrorOrderDetails) ' + orderDetailsError.message;
const filteredOrders = rows.filter((row) =>
@@ -345,127 +344,165 @@ export default function OrdersDetails() {
};
return (
<>
{isLoadingOrderDetails && <Loader />}
<TitleCard title="Orders Details" />
<Paper content={false} sx={{ border: '1px solid #eeeeee', borderBottom: 'none' }}>
<Stack
display={'flex'}
flexDirection={{ xs: 'column', md: 'row' }}
alignItems={'center'}
justifyContent={'space-between'}
sx={{ p: 2 }}
spacing={1}
>
<Stack direction="column" alignItems="flex-start" spacing={1}>
{startdate && enddate && (
<Stack direction="row" spacing={2}>
<Badge
badgeContent={`${statusCount}`}
max={99999}
color="primary"
sx={{
bgcolor: '#f3e5f5',
p: 0.2,
borderRadius: '3px',
color: '#7b1fa2'
}}
>{`Orders-${datestatus}`}</Badge>
<Chip
label={
<Typography noWrap color="secondary">
{dayjs(startdate).format('DD/MM/YYYY')} - {dayjs(enddate).format('DD/MM/YYYY')}
</Typography>
}
variant="combined"
color="warning"
size="small"
/>
</Stack>
)}
{(!startdate || !enddate) && (
<>
<MainCard
content={false}
title={
<Stack display={'flex'} flexDirection={'row'} alignItems={'center'} justifyContent={'space-between'} flexWrap="wrap">
<Stack alignItems="flex-start" spacing={1}>
{startdate && enddate && (
<Stack direction="row" spacing={2}>
<Chip label="Orders-All" color="primary" variant="light" size="small" />
{/* <Chip label={<Typography noWrap color="secondary">ALL</Typography>} variant="combined" color='warning' size='small' /> */}
<Badge
badgeContent={`${statusCount}`}
max={99999}
color="primary"
sx={{
bgcolor: '#f3e5f5',
p: 0.2,
borderRadius: '3px',
color: '#7b1fa2'
}}
>{`Orders-${datestatus}`}</Badge>
<Chip
label={
<Typography noWrap color="secondary">
{dayjs(startdate).format('DD/MM/YYYY')} - {dayjs(enddate).format('DD/MM/YYYY')}
</Typography>
}
variant="combined"
color="warning"
size="small"
/>
</Stack>
</>
)}
</Stack>
<Stack sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 2 }}>
<Autocomplete
sx={{ minWidth: 200 }}
disablePortal
id="combo-box-demo"
options={status}
getOptionLabel={(option) => `${option.status}`}
onChange={(event, value, reason) => {
if (reason === 'clear') {
setCurrentStatus('All');
} else {
console.log('status', value);
setCurrentStatus(value.statusLow);
}
}}
renderInput={(params) => <TextField {...params} label={statusLabel || 'Select Status'} />}
/>
<FormControl sx={{ width: 250 }}>
<OutlinedInput
inputRef={textFieldRef}
aria-describedby="header-search-text"
inputProps={{
'aria-label': 'weight'
)}
{(!startdate || !enddate) && (
<div>
<Stack direction="row" spacing={2}>
<Chip label="Orders-All" color="primary" variant="light" size="small" />
{/* <Chip label={<Typography noWrap color="secondary">ALL</Typography>} variant="combined" color='warning' size='small' /> */}
</Stack>
</div>
)}
</Stack>
<Stack sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 2 }}>
<Stack direction={'row'} alignItems={'center'} justifyContent={'space-between'}>
{tenantLocations.length == 1 ? (
<TextField
// disabled={!isAppLocation || !isClient}
variant="outlined"
fullWidth
label={'Business Location'}
value={tenantLocations[0].locationname}
focused
sx={{ width: '350px' }}
InputProps={{
style: { color: theme.palette.primary.main },
startAdornment: (
<InputAdornment position="start">
<MyLocationIcon color="primary" />
</InputAdornment>
)
}}
/>
) : (
<Autocomplete
fullWidth
// disabled={!isAppLocation || !isClient}
id="combo-box-demo"
options={tenantLocations || []}
getOptionLabel={(option) => `${option.locationname} (${option.suburb})` || ''}
renderInput={(params) => <TextField {...params} label={locoName} color="primary" />}
sx={{ width: '300px' }}
onChange={(event, value, reason) => {
if (value) {
console.log('Business Locations', value);
setLocationId(value.locationid);
setLocoName(value.locationname);
}
if (reason == 'clear') {
setLocationId(0);
setLocoName('Select Location');
}
}}
/>
)}
</Stack>
<Autocomplete
sx={{ minWidth: 200 }}
disablePortal
id="combo-box-demo"
options={status}
getOptionLabel={(option) => `${option.status}`}
onChange={(event, value, reason) => {
if (reason === 'clear') {
setCurrentStatus('All');
} else {
console.log('status', value);
setCurrentStatus(value.statusLow);
}
}}
sx={{ background: 'white' }}
size="large"
id="header-search"
placeholder="Search (ctrl+k)"
value={searchword}
onChange={(e) => {
setSearchword(e.target.value);
}}
autoComplete="off"
startAdornment={
<InputAdornment position="start" sx={{ mr: -0.5 }}>
<SearchOutlined />
</InputAdornment>
}
endAdornment={
<Tooltip title="clear">
<IconButton
sx={{ visibility: searchword ? 'visible' : 'hidden' }}
onClick={() => {
setSearchword('');
}}
>
<ClearIcon style={{ fontSize: 'medium', color: '#65387A' }} />
</IconButton>
</Tooltip>
}
renderInput={(params) => <TextField {...params} label={'Select Status'} />}
/>
</FormControl>
<FormControl sx={{ width: 250 }}>
<OutlinedInput
inputRef={textFieldRef}
aria-describedby="header-search-text"
inputProps={{
'aria-label': 'weight'
}}
sx={{ background: 'white' }}
size="large"
id="header-search"
placeholder="Search (ctrl+k)"
value={searchword}
onChange={(e) => {
setSearchword(e.target.value);
}}
autoComplete="off"
startAdornment={
<InputAdornment position="start" sx={{ mr: -0.5 }}>
<SearchOutlined />
</InputAdornment>
}
endAdornment={
<Tooltip title="clear">
<IconButton
sx={{ visibility: searchword ? 'visible' : 'hidden' }}
onClick={() => {
setSearchword('');
}}
>
<ClearIcon style={{ fontSize: 'medium', color: '#65387A' }} />
</IconButton>
</Tooltip>
}
/>
</FormControl>
<Tooltip title="Order Filter">
<IconButton
color="secondary"
variant="light"
sx={{
color: 'text.primary',
bgcolor: 'grey.200',
mx: 2
}}
aria-haspopup="true"
onClick={() => setOpen(true)}
>
<FilterList />
</IconButton>
</Tooltip>
<Tooltip title="Order Filter">
<IconButton
color="secondary"
variant="light"
sx={{
color: 'text.primary',
bgcolor: 'grey.200',
mx: 2
}}
aria-haspopup="true"
onClick={() => setOpen(true)}
>
<FilterList />
</IconButton>
</Tooltip>
<CSVExport data={csvData} filename={`Orders_Detail_${dayjs().format('YYYY-MM-DD_HHmmss')}.csv`} />
<CSVExport data={csvData} filename={`Orders_Detail_${dayjs().format('YYYY-MM-DD_HHmmss')}.csv`} />
</Stack>
</Stack>
</Stack>
</Paper>
<MainCard content={false}>
}
>
<TableContainer
onScroll={handleScroll}
ref={containerRef}