899 lines
32 KiB
JavaScript
899 lines
32 KiB
JavaScript
import React from 'react';
|
|
import Loader from 'components/Loader';
|
|
import { useEffect, useState, Fragment } from 'react';
|
|
import { useTheme } from '@mui/material/styles';
|
|
import MainCard from 'components/MainCard';
|
|
import axios from 'axios';
|
|
import ClearIcon from '@mui/icons-material/Clear';
|
|
import { SearchOutlined, CloseOutlined } from '@ant-design/icons';
|
|
import { Empty } from 'antd';
|
|
import MyLocationIcon from '@mui/icons-material/MyLocation';
|
|
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
import dayjs from 'dayjs';
|
|
var utc = require('dayjs/plugin/utc');
|
|
dayjs.extend(utc);
|
|
import { enqueueSnackbar } from 'notistack';
|
|
import { useNavigate } from 'react-router';
|
|
import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api';
|
|
|
|
import {
|
|
FormControl,
|
|
InputAdornment,
|
|
Grid,
|
|
Typography,
|
|
Stack,
|
|
Button,
|
|
TextField,
|
|
Autocomplete,
|
|
Divider,
|
|
Dialog,
|
|
DialogTitle,
|
|
DialogContent,
|
|
Checkbox,
|
|
DialogActions,
|
|
CircularProgress,
|
|
IconButton,
|
|
OutlinedInput,
|
|
FormGroup,
|
|
FormControlLabel,
|
|
Table,
|
|
TableContainer,
|
|
TableCell,
|
|
TableBody,
|
|
TableRow,
|
|
Paper,
|
|
TableHead,
|
|
Box
|
|
} from '@mui/material';
|
|
import CircularLoader from 'components/nearle_components/CircularLoader';
|
|
// import RidersPinPointOSM from './RidersPinPointOSM';
|
|
import RidersPinPoint from './ridersPinPoint';
|
|
|
|
const MultipleOrders = () => {
|
|
const navigate = useNavigate();
|
|
const theme = useTheme();
|
|
const [loading, setLoading] = useState(false);
|
|
const [btnLoading, setBtnLoading] = useState(false);
|
|
const [appId, setAppId] = useState(0);
|
|
|
|
const [tenantLocations, setTenantlocations] = useState([]);
|
|
const userid = localStorage.getItem('userid');
|
|
const tenId = localStorage.getItem('tenantid');
|
|
const [tid, setTid] = useState(0);
|
|
const [isLocation, setIsLocation] = useState(false);
|
|
const [basePrice, setBasePrice] = useState(0);
|
|
const [pricePerKm, setPricePerKm] = useState(0);
|
|
const [minKm, setMinKm] = useState(0);
|
|
const [pickCust, setPickCust] = useState(null);
|
|
const [dropCust, setDropCust] = useState([]);
|
|
const [isCustomerOpen, setIsCustomerOpen] = useState(false);
|
|
const [searchCustList, setSearchCustList] = useState('');
|
|
const [customerlist, setCustomerlist] = useState([]);
|
|
const [startdate, setStartdate] = useState(dayjs().format('MM-DD-YYYY'));
|
|
const [timeslotarr, setTimeslotarr] = useState([]);
|
|
const [starttime, setStatrttime] = useState();
|
|
const [endtime, setEndtime] = useState();
|
|
const [alertmessage, setAlertmessage] = useState('');
|
|
const [otherinstructions, setOtherinstructions] = useState('');
|
|
const [admintoken, setAdmintoken] = useState();
|
|
const [totaldist, settotaldist] = useState(0);
|
|
const [totalAmt, settotalAmt] = useState(0);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [showMap, setShowMap] = useState(false);
|
|
|
|
useEffect(() => {
|
|
dropCust && console.log('dropCust', dropCust);
|
|
}, [dropCust]);
|
|
|
|
// =============================================== || opentoast || ===============================================
|
|
const opentoast = (message, variant, time) => {
|
|
enqueueSnackbar(message, {
|
|
variant: variant,
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: time ? time : 1500
|
|
});
|
|
console.log(alertmessage);
|
|
};
|
|
// ==============================|| fetchAppLocations ||============================== //
|
|
const fetchAppLocations = async () => {
|
|
try {
|
|
const locationRes = await axios.get(`${process.env.REACT_APP_URL}/partners/getlocations/?userid=${userid}`);
|
|
console.log('fetchAppLocations', locationRes.data.details);
|
|
} catch (err) {
|
|
console.log('locationRes', err);
|
|
}
|
|
};
|
|
useEffect(() => {
|
|
fetchAppLocations();
|
|
}, []);
|
|
|
|
// ============================================= || fetchTenantPricing || =============================================
|
|
|
|
const fetchTenantPricing = async (id) => {
|
|
try {
|
|
const pricingResponse = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantpricing/?tenantid=${tenId}`);
|
|
console.log('pricingResponse', pricingResponse.data.details);
|
|
setBasePrice(pricingResponse.data.details.baseprice);
|
|
setPricePerKm(pricingResponse.data.details.priceperkm);
|
|
setMinKm(pricingResponse.data.details.minkm);
|
|
} catch (error) {
|
|
console.log('fetchTenantPricing error', error);
|
|
}
|
|
};
|
|
useEffect(() => {
|
|
fetchTenantPricing();
|
|
}, []);
|
|
// ============================================= || 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);
|
|
}, []);
|
|
// ========================================================= || clientdetails || =========================================================
|
|
const clientdetails = async () => {
|
|
try {
|
|
let url =
|
|
searchCustList == ''
|
|
? `${process.env.REACT_APP_URL}/customers/gettenantcustomers/?tenantid=${tenId}&pageno=1&pagesize=10`
|
|
: `${process.env.REACT_APP_URL}/customers/search/?tenantid=${tenId}&keyword=${searchCustList}`;
|
|
await axios
|
|
.get(url)
|
|
.then((res) => {
|
|
if (res.data.status) {
|
|
console.log('clientdetails', res.data.details);
|
|
|
|
setCustomerlist(res.data.details);
|
|
let arr = [];
|
|
res.data.details.map((val) => {
|
|
arr.push({
|
|
label: `${val.firstname} | ${val.contactno}`,
|
|
...val
|
|
});
|
|
});
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
opentoast('server error', 'warning');
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
};
|
|
useEffect(() => {
|
|
if (tenId) {
|
|
clientdetails();
|
|
}
|
|
}, [searchCustList.length > 3, searchCustList == '', tenId]);
|
|
|
|
// ========================================================= || calculateTotal(dist , charge) || =========================================================
|
|
const calculateTotal = () => {
|
|
let a1 = 0;
|
|
let a2 = 0;
|
|
dropCust?.map((customer) => {
|
|
a1 += customer.distance;
|
|
a2 += customer.totalcharge;
|
|
});
|
|
settotaldist(a1);
|
|
settotalAmt(a2);
|
|
};
|
|
useEffect(() => {
|
|
dropCust && calculateTotal();
|
|
}, [dropCust]);
|
|
|
|
// ========================================================= || handleCheckboxChange || =========================================================
|
|
const handleCheckboxChange = async (event, customer) => {
|
|
setIsLoading(true);
|
|
console.log('event', event.target.checked);
|
|
console.log('customer', customer);
|
|
if (event.target.checked) {
|
|
// If the checkbox is checked, calculate the distance and add the customer
|
|
try {
|
|
const obj = await calculateDistance(customer);
|
|
console.log('return of calculateDistance', obj);
|
|
|
|
const { roundedDistance, totalcharge } = obj;
|
|
// Create a new customer object with the distance property
|
|
const updatedCustomer = {
|
|
...customer,
|
|
distance: roundedDistance,
|
|
totalcharge: totalcharge
|
|
};
|
|
|
|
// Add the updated customer object to dropCust
|
|
setDropCust((prevDropCust) => [...prevDropCust, updatedCustomer]);
|
|
|
|
// Log the rounded distance
|
|
console.log(`Rounded Distance: ${roundedDistance} km`);
|
|
} catch (error) {
|
|
console.error('Failed to calculate distance:', error);
|
|
}
|
|
setIsLoading(false);
|
|
} else {
|
|
// If the checkbox is unchecked, remove the customer from dropCust
|
|
setDropCust((prevDropCust) => {
|
|
return prevDropCust.filter((cust) => cust.customerid !== customer.customerid);
|
|
});
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// ========================================================= || calculateDistance || =========================================================
|
|
const calculateDistance = async (customer) => {
|
|
console.log('Distance calculation starts');
|
|
const service = new google.maps.DistanceMatrixService();
|
|
// Helper function to get the distance matrix
|
|
const getDistanceMatrix = async (origins, destinations) => {
|
|
console.log('origins', origins);
|
|
console.log('destinations', destinations);
|
|
return new Promise((resolve, reject) => {
|
|
console.log('calculation starts');
|
|
service.getDistanceMatrix(
|
|
{
|
|
origins: [new google.maps.LatLng(origins.latitude, origins.longitude)],
|
|
destinations: [new google.maps.LatLng(destinations.latitude, destinations.longitude)],
|
|
travelMode: 'DRIVING',
|
|
unitSystem: google.maps.UnitSystem.METRIC // Distances in metric units (km)
|
|
},
|
|
(response, status) => {
|
|
console.log('cal response', response);
|
|
console.log('cal status', status);
|
|
if (status === 'OK') {
|
|
console.log('calcualtion resolved');
|
|
resolve(response);
|
|
} else {
|
|
console.log('calcualtion rejected');
|
|
|
|
reject(new Error(`Error calculating distance: ${status}`));
|
|
}
|
|
}
|
|
);
|
|
});
|
|
};
|
|
|
|
try {
|
|
// Call getDistanceMatrix and wait for the response
|
|
const response = await getDistanceMatrix(pickCust, customer);
|
|
|
|
// Extract distance from the first result
|
|
const distanceInMeters = response.rows[0].elements[0].distance.value;
|
|
|
|
// Convert distance from meters to kilometers
|
|
const distanceInKilometers = distanceInMeters / 1000;
|
|
|
|
// Round the distance to the nearest integer
|
|
const roundedDistance = Math.round(distanceInKilometers);
|
|
let totalcharge;
|
|
if (roundedDistance < minKm) {
|
|
console.log('minKm', minKm);
|
|
console.log('pricePerKm', pricePerKm);
|
|
console.log('basePrice', basePrice);
|
|
totalcharge = basePrice;
|
|
} else {
|
|
console.log('minKm', minKm);
|
|
console.log('pricePerKm', pricePerKm);
|
|
console.log('basePrice', basePrice);
|
|
totalcharge = (roundedDistance - minKm) * pricePerKm + basePrice;
|
|
console.log('totalcharge', totalcharge);
|
|
}
|
|
|
|
// Return the rounded distance
|
|
return { roundedDistance, totalcharge };
|
|
} catch (error) {
|
|
console.error('Error calculating distance:', error);
|
|
throw error; // Rethrow the error to be handled by the caller
|
|
}
|
|
};
|
|
|
|
// ==================================================== || fetchTiming || ====================================================
|
|
const fetchTiming = async () => {
|
|
setLoading(true);
|
|
await axios
|
|
.get(`${process.env.REACT_APP_URL}/utils/getapplocations/?applocationid=${appId}`)
|
|
.then((res) => {
|
|
console.log('fetchTiming', res);
|
|
const { opentime, closetime, latitude, longitude, radius } = res.data.details[0];
|
|
if (res.data.status) {
|
|
setStatrttime(`${dayjs().format('MM-DD-YYYY')} ${opentime}`);
|
|
setEndtime(`${dayjs().format('MM-DD-YYYY')} ${closetime}`);
|
|
console.log('starttime', `${dayjs().format('MM-DD-YYYY')} ${opentime}`);
|
|
console.log('endtime', `${dayjs().format('MM-DD-YYYY')} ${closetime} `);
|
|
let arr = [];
|
|
for (
|
|
let i = `${dayjs().format('MM-DD-YYYY')} ${opentime}`, j = 0;
|
|
dayjs(`${dayjs().format('MM-DD-YYYY')} ${closetime} `).diff(i, 'm') >= 0;
|
|
j++, i = dayjs(i).add(30, 'm')
|
|
) {
|
|
arr.push(i);
|
|
}
|
|
console.log('setTimeslotarr', arr);
|
|
setTimeslotarr(arr);
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
};
|
|
useEffect(() => {
|
|
if (appId) {
|
|
fetchTiming();
|
|
}
|
|
}, [starttime, endtime, appId]);
|
|
|
|
const fetchAppAdminTokens = async () => {
|
|
setLoading(true);
|
|
await axios
|
|
.get(`${process.env.REACT_APP_URL}/utils/getapplocationconfig/?applocationid=${appId}`)
|
|
.then((res) => {
|
|
const userfcmtokemArray = res.data.details.applocationadmins.map((admin) => admin.userfcmtokem); // fcm => firebase cloud messaging
|
|
console.log('fetchAppAdminTokens', res);
|
|
console.log('userfcmtokemArray', userfcmtokemArray);
|
|
if (res.data.status) {
|
|
setAdmintoken(userfcmtokemArray);
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (starttime && endtime) {
|
|
fetchAppAdminTokens();
|
|
}
|
|
}, [starttime, endtime]);
|
|
|
|
useEffect(() => {
|
|
console.log('pickCust', pickCust);
|
|
}, [pickCust]);
|
|
|
|
// ==================================================== || fetchtenantinfo || ====================================================
|
|
const fetchtenantinfo = async () => {
|
|
setLoading(true);
|
|
console.log('tid', tid);
|
|
|
|
await axios
|
|
.get(`${process.env.REACT_APP_URL}/tenants/gettenantinfo/?tenantid=${tid}`)
|
|
.then((res) => {
|
|
console.log('fetchtenantinfo', res);
|
|
if (res.data.status) {
|
|
fetchAppAdminTokens();
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
};
|
|
useEffect(() => {
|
|
if (tid) {
|
|
fetchtenantinfo();
|
|
}
|
|
}, [tid]);
|
|
// ================================================== || sendnotifications || ==================================================
|
|
const sendnotifications = async () => {
|
|
setLoading(true);
|
|
await axios
|
|
.post(`${process.env.REACT_APP_URL}/utils/sendnotifications`, {
|
|
priority: 'high',
|
|
registration_ids: admintoken,
|
|
data: {
|
|
accessid: process.env.REACT_APP_RIDER_ACCESS_ID
|
|
},
|
|
notification: {
|
|
title: 'Nearle Merchant',
|
|
body: 'An Order has been placed successfully,kindly process the same',
|
|
sound: 'ring'
|
|
}
|
|
})
|
|
.then((res) => {
|
|
console.log(res);
|
|
if (res.data.message == 'Success') {
|
|
enqueueSnackbar('Notification sent Successfully', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 1000
|
|
});
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
enqueueSnackbar(err.message, {
|
|
variant: 'error',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 1000
|
|
});
|
|
setLoading(false);
|
|
});
|
|
};
|
|
// =============================================== || creategrouporders || ===============================================
|
|
const creategrouporders = async () => {
|
|
const arr = dropCust?.map((customer) => ({
|
|
applocationid: pickCust.applocationid,
|
|
cancellled: '',
|
|
// categoryid: +tenant.categoryid,
|
|
configid: 9,
|
|
customerid: customer.customerid,
|
|
deliveryaddress: customer.address || '',
|
|
deliverycharge: +customer.totalcharge || 0,
|
|
deliverycity: customer.city || '',
|
|
deliverycontactno: customer.contactno || '',
|
|
deliverycustomer: customer.firstname || '',
|
|
deliveryid: +customer.customerid,
|
|
deliverylandmark: customer.landmark || '',
|
|
deliverylat: customer.latitude,
|
|
deliverylocation: customer.suburb || '',
|
|
deliverylocationid: customer.deliverylocationid || 0,
|
|
deliverylong: customer.longitude,
|
|
// deliverytime: `${dayjs(startdate).format('YYYY-MM-DD HH:mm:ss')} `,
|
|
deliverytime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
deliverytype: 'B',
|
|
delivered: '',
|
|
itemcount: 1,
|
|
kms: customer.distance.toString() || 0,
|
|
locationid: +pickCust.locationid,
|
|
moduleid: +pickCust.moduleid,
|
|
orderamount: +customer.totalcharge || 0,
|
|
ordercharges: 0.0,
|
|
orderdate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
orderheaderid: 0,
|
|
orderid: '', //
|
|
ordernotes: otherinstructions,
|
|
orderstatus: 'created',
|
|
ordervalue: +customer.totalcharge || 0,
|
|
partnerid: pickCust.partnerid,
|
|
partneruserid: +userid,
|
|
paymentstatus: 1,
|
|
paymenttype: 42,
|
|
pending: '',
|
|
pickupaddress: pickCust.address || '',
|
|
pickupcity: pickCust.locationcity || '',
|
|
pickupcontactno: pickCust.contactno || '',
|
|
pickupcustomer: pickCust.locationname || '',
|
|
pickuplandmark: pickCust.landmark || '',
|
|
pickuplat: pickCust.latitude,
|
|
pickuplocation: pickCust.suburb || '',
|
|
pickuplocationid: pickCust.locationid || 0,
|
|
pickuplong: pickCust.longitude,
|
|
processing: '',
|
|
ready: '',
|
|
remarks: '',
|
|
taxamount: 0.0,
|
|
tenantid: pickCust.tenantid,
|
|
tenantuserid: 0
|
|
}));
|
|
console.log('arr', arr);
|
|
|
|
if (!tenId) {
|
|
opentoast('Choose Client ', 'warning');
|
|
} else {
|
|
setLoading(true);
|
|
|
|
await axios
|
|
.post(`${process.env.REACT_APP_URL}/orders/createorders`, arr)
|
|
.then((res) => {
|
|
if (res.data.status) {
|
|
enqueueSnackbar('Order Created Successfully', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 1000
|
|
});
|
|
if (admintoken) {
|
|
// notifyadmin(admintoken);
|
|
sendnotifications();
|
|
}
|
|
navigate('/nearle/orders');
|
|
} else {
|
|
opentoast(res.data.message, 'warning');
|
|
}
|
|
setLoading(false);
|
|
console.log(res);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
// opentoast(err.data.message, 'warning');
|
|
setLoading(false);
|
|
});
|
|
}
|
|
console.log(arr);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{loading && <Loader />}
|
|
{/* <RidersPinPointOSM /> */}
|
|
<Grid container sx={{ mb: 2 }}>
|
|
<Grid item xs={12} sm={3} md={6}>
|
|
<Stack>
|
|
<Typography variant="h3" whiteSpace="nowrap">
|
|
Multiple Orders
|
|
</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12} sm={9} md={6}>
|
|
<Stack
|
|
sx={{}}
|
|
width={'100%'}
|
|
direction="row"
|
|
alignItems="center"
|
|
spacing={2}
|
|
justifyContent={'flex-end'}
|
|
flexWrap={{ xs: 'wrap', custom550: 'nowrap' }}
|
|
gap={2}
|
|
>
|
|
{/* Business Location */}
|
|
<Stack sx={{ width: '100%' }}>
|
|
{tenantLocations?.length === 1 ? (
|
|
<TextField
|
|
label="Business Location"
|
|
fullWidth
|
|
focused
|
|
value={tenantLocations[0]?.locationname}
|
|
InputProps={{
|
|
style: { color: theme.palette.primary.main },
|
|
startAdornment: (
|
|
<InputAdornment position="start">
|
|
<MyLocationIcon color="primary" />
|
|
</InputAdornment>
|
|
)
|
|
}}
|
|
/>
|
|
) : (
|
|
<Autocomplete
|
|
fullWidth
|
|
options={tenantLocations || []}
|
|
getOptionLabel={(option) => `${option.locationname} (${option.suburb})`}
|
|
onChange={(event, value, reason) => {
|
|
if (value) {
|
|
setTid(value.tenantid);
|
|
setIsLocation(true);
|
|
setPickCust(value);
|
|
}
|
|
if (reason === 'clear') setIsLocation(false);
|
|
}}
|
|
renderInput={(params) => <TextField {...params} label="Select Business Location" color="primary" fullWidth />}
|
|
/>
|
|
)}
|
|
</Stack>
|
|
|
|
{/* Date Picker */}
|
|
<Stack sx={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
<DatePicker
|
|
format="DD-MM-YYYY"
|
|
disablePast
|
|
value={dayjs(startdate)}
|
|
sx={{ width: 150 }}
|
|
onChange={(e) => {
|
|
let diff = dayjs().diff(dayjs(dayjs(e).format('YYYY-MM-DD')), 'd');
|
|
|
|
if (diff <= 0) {
|
|
setStartdate(e);
|
|
|
|
let arr = [];
|
|
timeslotarr.forEach((val) => {
|
|
if (dayjs().diff(dayjs(`${dayjs(e).format('MM-DD-YYYY')} ${dayjs(val).format('HH:mm:ss')}`), 'm') <= 0) {
|
|
arr.push(val);
|
|
}
|
|
});
|
|
|
|
if (arr[0]) {
|
|
setOrderarr([
|
|
{
|
|
sno: 1,
|
|
address: '',
|
|
customerid: '',
|
|
deliverytime: dayjs(arr[0]),
|
|
deliverylocationid: '',
|
|
clientname: '',
|
|
contactno: '',
|
|
latitude: '',
|
|
longitude: ''
|
|
}
|
|
]);
|
|
} else {
|
|
setOrderarr([]);
|
|
}
|
|
} else {
|
|
opentoast('choose Upcoming Date', 'warning');
|
|
setStartdate(NaN);
|
|
}
|
|
}}
|
|
/>
|
|
</LocalizationProvider>
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
{/* ===================================================== || Pickup || ===================================================== */}
|
|
{pickCust && (
|
|
<TableContainer component={Paper} sx={{ mb: 2 }}>
|
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Pickup Location</TableCell>
|
|
<TableCell>Address</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell>{pickCust?.locationname}</TableCell>
|
|
<TableCell>{pickCust?.address}</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
)}
|
|
|
|
{/* ===================================================== || Drop || ===================================================== */}
|
|
|
|
<MainCard
|
|
sx={{ height: '100%' }}
|
|
title={`Drop (${dropCust?.length || 0})`}
|
|
secondary={
|
|
<Button
|
|
variant="outlined"
|
|
size="small"
|
|
sx={{
|
|
'&:hover': {
|
|
bgcolor: theme.palette.primary.main,
|
|
color: 'white'
|
|
}
|
|
}}
|
|
onClick={() => {
|
|
if (!isLocation) {
|
|
opentoast('Select Business Location', 'warning');
|
|
} else {
|
|
setIsCustomerOpen(true);
|
|
setSearchCustList('');
|
|
}
|
|
}}
|
|
>
|
|
Select Customers
|
|
</Button>
|
|
}
|
|
>
|
|
<TableContainer component={Paper}>
|
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>S.No</TableCell>
|
|
<TableCell>Customer</TableCell>
|
|
<TableCell>Address</TableCell>
|
|
<TableCell>Kms</TableCell>
|
|
<TableCell align="right">Charge</TableCell>
|
|
<TableCell>Action</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{!dropCust && (
|
|
<TableRow>
|
|
<TableCell colSpan={6}>
|
|
<Empty description={' Drop Customers Not Selected'} />
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
{dropCust?.map((customer, index) => (
|
|
<TableRow key={index}>
|
|
<TableCell>{index + 1}</TableCell>
|
|
<TableCell>{customer.firstname}</TableCell>
|
|
<TableCell>{customer.address}</TableCell>
|
|
<TableCell>{customer.distance}</TableCell>
|
|
<TableCell align="right">{`₹${customer.totalcharge}.00`}</TableCell>
|
|
<TableCell align="center">
|
|
{
|
|
<CloseOutlined
|
|
style={{ cursor: 'pointer', color: 'red' }}
|
|
onClick={(event) => handleCheckboxChange(event, customer)}
|
|
/>
|
|
}
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
{dropCust?.length != 0 && (
|
|
<TableRow>
|
|
<TableCell>
|
|
<Typography variant="h5">Total</Typography>
|
|
</TableCell>
|
|
<TableCell></TableCell>
|
|
<TableCell></TableCell>
|
|
<TableCell>
|
|
<Typography variant="h5">{`${totaldist} `}</Typography>
|
|
</TableCell>
|
|
<TableCell align="right">
|
|
<Typography variant="h5"> {`₹${totalAmt}.00`}</Typography>
|
|
</TableCell>
|
|
<TableCell></TableCell>
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
</MainCard>
|
|
|
|
{/* ================================================= || Riders Map || ================================================= */}
|
|
|
|
{/* {showMap && dropCust.length >= 1 && <RidersPinPoint pickCust={pickCust} dropCust={dropCust} />} */}
|
|
|
|
{/* ================================================= || Notes || ================================================= */}
|
|
{dropCust && (
|
|
<MainCard sx={{ mt: 2 }} title={'Notes'}>
|
|
<Grid container>
|
|
<Grid item xs={12}>
|
|
<TextField
|
|
focused
|
|
id="outlined-multiline-static"
|
|
sx={{ width: '100%', height: '100%', mb: 2 }}
|
|
multiline
|
|
rows={1}
|
|
placeholder="Notes"
|
|
value={otherinstructions}
|
|
onChange={(e) => setOtherinstructions(e.target.value)}
|
|
/>
|
|
</Grid>
|
|
<Stack direction="row" justifyContent={'end'} sx={{ mt: 2, width: '100%' }}>
|
|
<Button
|
|
disabled={dropCust?.length == 0}
|
|
size="medium"
|
|
variant="outlined"
|
|
onClick={() => {
|
|
setLoading(true);
|
|
setBtnLoading(true);
|
|
creategrouporders();
|
|
setTimeout(() => {
|
|
setLoading(false);
|
|
setBtnLoading(false);
|
|
}, 2000);
|
|
}}
|
|
sx={{
|
|
'&:hover': {
|
|
transform: 'scale(1.05)',
|
|
transition: 'transform 0.3s ease'
|
|
}
|
|
}}
|
|
>
|
|
{btnLoading ? <CircularProgress color="primary" size={20} thickness={10} /> : 'Create'}
|
|
</Button>
|
|
</Stack>
|
|
</Grid>
|
|
</MainCard>
|
|
)}
|
|
|
|
{/* ============================================= || saved address Dialog || ============================================= */}
|
|
<Dialog
|
|
open={isCustomerOpen}
|
|
onClose={() => {
|
|
setIsCustomerOpen(false);
|
|
}}
|
|
fullWidth
|
|
sx={{ minWidth: 'lg' }}
|
|
>
|
|
{isLoading && <CircularLoader />}
|
|
<DialogTitle sx={{ bgcolor: theme.palette.primary.main, color: 'white' }}>
|
|
<Stack>
|
|
<Typography variant="h4"> {`Select Drop Customers (${dropCust?.length || 0})`}</Typography>
|
|
<FormControl
|
|
sx={{
|
|
width: '100%',
|
|
mt: 1
|
|
}}
|
|
>
|
|
<Stack spacing={2} sx={{ py: 0.2 }}>
|
|
<OutlinedInput
|
|
fullWidth
|
|
id="input-search-header"
|
|
placeholder="Search"
|
|
value={searchCustList}
|
|
onChange={(e) => setSearchCustList(e.target.value)}
|
|
sx={{
|
|
'& .MuiOutlinedInput-input': {
|
|
p: '10.5px 0px 12px'
|
|
},
|
|
bgcolor: 'white'
|
|
}}
|
|
startAdornment={
|
|
<InputAdornment position="start">
|
|
<SearchOutlined style={{ fontSize: 'small' }} />
|
|
</InputAdornment>
|
|
}
|
|
endAdornment={
|
|
<IconButton
|
|
sx={{ visibility: searchCustList ? 'visible' : 'hidden' }}
|
|
onClick={() => {
|
|
setSearchCustList('');
|
|
}}
|
|
>
|
|
<ClearIcon />
|
|
</IconButton>
|
|
}
|
|
autoComplete="off"
|
|
/>
|
|
</Stack>
|
|
</FormControl>
|
|
</Stack>
|
|
</DialogTitle>
|
|
<Divider />
|
|
<DialogContent sx={{ p: 2.5 }}>
|
|
{customerlist.length == 0 ? (
|
|
<Stack spacing={2} direction={'row'} alignItems={'center'} justifyContent={'center'} sx={{ minHeight: 600, maxHeight: 600 }}>
|
|
<Empty />
|
|
</Stack>
|
|
) : (
|
|
<Stack spacing={2} sx={{ minHeight: 600, maxHeight: 600 }}>
|
|
{customerlist &&
|
|
customerlist.map((customer, index) => (
|
|
<FormGroup key={index}>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={dropCust?.some((cust) => cust.customerid === customer.customerid)} // Set the checked state of the checkbox based on whether the customer is in `dropCust`
|
|
onChange={(event) => handleCheckboxChange(event, customer)}
|
|
/>
|
|
}
|
|
label={
|
|
<div style={{ width: '100%' }}>
|
|
<Typography variant="subtitle1" sx={{ textAlign: 'left' }}>
|
|
{`${customer.firstname} (${customer.contactno})`}
|
|
</Typography>
|
|
|
|
<Typography variant="body2" color="secondary" sx={{ textAlign: 'left' }}>
|
|
{customer.address}
|
|
</Typography>
|
|
</div>
|
|
}
|
|
/>
|
|
</FormGroup>
|
|
))}
|
|
</Stack>
|
|
)}
|
|
</DialogContent>
|
|
<Divider />
|
|
<DialogActions sx={{ p: 2.5 }}>
|
|
<Button
|
|
color={dropCust?.length !== 0 ? 'primary' : 'error'}
|
|
variant="outlined"
|
|
sx={{
|
|
'&:hover': {
|
|
bgcolor: dropCust?.length !== 0 ? theme.palette.primary.main : theme.palette.error.main,
|
|
color: 'white'
|
|
}
|
|
}}
|
|
onClick={() => {
|
|
setIsCustomerOpen(false);
|
|
{
|
|
dropCust?.length !== 0 && setShowMap(true);
|
|
}
|
|
}}
|
|
>
|
|
{dropCust?.length !== 0 ? 'Continue' : 'Close'}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default MultipleOrders;
|