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 && } {/* */} Multiple Orders {/* Business Location */} {tenantLocations?.length === 1 ? ( ) }} /> ) : ( `${option.locationname} (${option.suburb})`} onChange={(event, value, reason) => { if (value) { setTid(value.tenantid); setIsLocation(true); setPickCust(value); } if (reason === 'clear') setIsLocation(false); }} renderInput={(params) => } /> )} {/* Date Picker */} { 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); } }} /> {/* ===================================================== || Pickup || ===================================================== */} {pickCust && ( Pickup Location Address {pickCust?.locationname} {pickCust?.address}
)} {/* ===================================================== || Drop || ===================================================== */} { if (!isLocation) { opentoast('Select Business Location', 'warning'); } else { setIsCustomerOpen(true); setSearchCustList(''); } }} > Select Customers } > S.No Customer Address Kms Charge Action {!dropCust && ( )} {dropCust?.map((customer, index) => ( {index + 1} {customer.firstname} {customer.address} {customer.distance} {`₹${customer.totalcharge}.00`} { handleCheckboxChange(event, customer)} /> } ))} {dropCust?.length != 0 && ( Total {`${totaldist} `} {`₹${totalAmt}.00`} )}
{/* ================================================= || Riders Map || ================================================= */} {/* {showMap && dropCust.length >= 1 && } */} {/* ================================================= || Notes || ================================================= */} {dropCust && ( setOtherinstructions(e.target.value)} /> )} {/* ============================================= || saved address Dialog || ============================================= */} { setIsCustomerOpen(false); }} fullWidth sx={{ minWidth: 'lg' }} > {isLoading && } {`Select Drop Customers (${dropCust?.length || 0})`} setSearchCustList(e.target.value)} sx={{ '& .MuiOutlinedInput-input': { p: '10.5px 0px 12px' }, bgcolor: 'white' }} startAdornment={ } endAdornment={ { setSearchCustList(''); }} > } autoComplete="off" /> {customerlist.length == 0 ? ( ) : ( {customerlist && customerlist.map((customer, index) => ( 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={
{`${customer.firstname} (${customer.contactno})`} {customer.address}
} />
))}
)}
); }; export default MultipleOrders;