434 lines
18 KiB
JavaScript
434 lines
18 KiB
JavaScript
import axios from 'axios';
|
|
import { OpenToast } from 'components/nearle_components/OpenToast';
|
|
const tenid = localStorage.getItem('tenantid');
|
|
|
|
export const fetchOrders = async ({ pageParam = 1, queryKey }) => {
|
|
const [, { tenantId, locationId, status, startdate, enddate, searchword, rowsPerPage }] = queryKey;
|
|
|
|
const url =
|
|
`${process.env.REACT_APP_URL}/orders/tenant/getorders/` +
|
|
`?tenantid=${tenantId}` +
|
|
`&locationid=${locationId}` +
|
|
`&status=${status}` +
|
|
`&fromdate=${startdate}` +
|
|
`&todate=${enddate}` +
|
|
`&pageno=${pageParam}` + // 👈 pageParam comes from TanStack
|
|
`&pagesize=${rowsPerPage}` +
|
|
`&keyword=${searchword}`;
|
|
|
|
const res = await axios.get(url);
|
|
return {
|
|
details: res.data.details,
|
|
nextPage: res.data.details.length === rowsPerPage ? pageParam + 1 : undefined
|
|
// 👈 API must return this flag
|
|
};
|
|
};
|
|
|
|
// ==============================|| fetchOrderSummary (orders)||============================== //
|
|
export const fetchOrderSummary = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getordersummary`);
|
|
console.log('fetchOrderSummary', response.data.details);
|
|
return response.data.details;
|
|
};
|
|
|
|
// ==============================|| fetchLocationSummary (orders)||============================== //
|
|
export const fetchLocationSummary = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getlocationsummary`);
|
|
console.log('fetchLocationSummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
|
|
// ==============================|| fetchOrderInsight (orders)||============================== //
|
|
export const fetchOrderInsight = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getorderinsight`);
|
|
console.log('fetchOrderInsight', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
|
|
// ==============================|| fetchDeliveryInsight (delivery)||============================== //
|
|
export const fetchDeliveryInsight = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/deliveries/getdeliveryinsight`);
|
|
console.log('fetchDeliveryInsight', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| fetchDeliveryLocationSummary (delivery)||============================== //
|
|
export const fetchDeliveryLocationSummary = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/deliveries/getlocationsummary`);
|
|
console.log('fetchDeliveryLocationSummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| getorders (Locations)||============================== //
|
|
// fetchOrders.js
|
|
|
|
export const fetchOrders1 = async ({ pageParam = 1, queryKey }) => {
|
|
const [_key, tenantid, locationid, status, startdate, enddate, searchword, rowsPerPage] = queryKey;
|
|
|
|
const res = await axios.get(
|
|
`${process.env.REACT_APP_URL}/orders/tenant/getorders/?tenantid=${tenantid}&locationid=${locationid}&status=${status}&fromdate=${startdate}&todate=${enddate}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${searchword}`
|
|
);
|
|
|
|
return {
|
|
details: res.data.details,
|
|
nextPage: res.data.details.length === rowsPerPage ? pageParam + 1 : undefined
|
|
};
|
|
};
|
|
|
|
// ==============================|| fetchAllTenants (clients)||============================== //
|
|
|
|
export const fetchAllTenants = async ({ queryKey }) => {
|
|
const [size, pageno, search] = queryKey;
|
|
|
|
let url = '';
|
|
if (search) {
|
|
// url = `${process.env.REACT_APP_URL}/tenants/search/?keyword=${search}`;
|
|
url = `${process.env.REACT_APP_URL}/tenants/search/?keyword=${search}`;
|
|
} else {
|
|
// url = `${process.env.REACT_APP_URL}/tenants/getalltenants?pageno=${pageno}&pagesize=${size}`;
|
|
url = `${process.env.REACT_APP_URL}/tenants/getalltenants?pageno=${pageno}&pagesize=${size}`;
|
|
}
|
|
const response = await axios.get(url);
|
|
|
|
// tenants/search/?keyword=${search}
|
|
console.log('fetchAllTenants', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| fetchCustomersList (customers)||============================== //
|
|
export const fetchCustomersList = async ({ queryKey }) => {
|
|
const [pages] = queryKey;
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/customers/getallcustomers/?pageno=${pages}&pagesize=10`);
|
|
console.log('fetchCustomersList', response.data.details);
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| gettenantcustomers (customers)||============================== //
|
|
|
|
export const gettenantcustomers = async ({ pageParam = 1, queryKey }) => {
|
|
const [, rowsPerPage, customerSearch] = queryKey;
|
|
|
|
try {
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/customers/gettenantcustomers/?tenantid=${tenid}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${customerSearch}`
|
|
);
|
|
|
|
const details = response.data.details ?? [];
|
|
|
|
return {
|
|
details,
|
|
nextPage: details.length === rowsPerPage ? pageParam + 1 : undefined
|
|
};
|
|
} catch (err) {
|
|
OpenToast(err.message, 'error', 1000);
|
|
return { details: [], nextPage: undefined };
|
|
}
|
|
};
|
|
|
|
// ==============================|| fetchCustomersListBySearch (customers)||============================== //
|
|
export const fetchCustomersListBySearch = async ({ queryKey }) => {
|
|
const [search] = queryKey;
|
|
const response = await axios.get(search.lenght > 3 && `${process.env.REACT_APP_URL}/customers/search/?keyword=${search}`);
|
|
console.log('fetchCustomersListBySearch', response.data.details);
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| fetchOrdersSummary (rider summary)||============================== //
|
|
export const fetchOrdersSummary = async ({ queryKey }) => {
|
|
console.log('queryKey for fetchOrdersSummary', queryKey);
|
|
const [startdate, enddate] = queryKey;
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/deliveries/getreportsummary/?tenantid=${tenid}&fromdate=${startdate}&todate=${enddate}`
|
|
);
|
|
console.log('fetchOrdersSummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| getreportlocationsummary (orders summary)||============================== //
|
|
export const getreportlocationsummary = async ({ queryKey }) => {
|
|
console.log('queryKey for getreportlocationsummary', queryKey);
|
|
const [startdate, enddate, locationId, debouncedSearch] = queryKey;
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/deliveries/getreportlocationsummary/?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}&keyword=${debouncedSearch}`
|
|
);
|
|
console.log('getreportlocationsummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| getriderlocationreportsummary (orders summary)||============================== //
|
|
export const getriderlocationreportsummary = async ({ queryKey }) => {
|
|
console.log('queryKey for getriderlocationreportsummary', queryKey);
|
|
const [startdate, enddate, locationId] = queryKey;
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/deliveries/getriderlocationreportsummary/?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}`
|
|
);
|
|
console.log('getriderlocationreportsummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| fetchLocations (orders summary))||============================== //
|
|
|
|
export const fetchLocations = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/partners/getpartners`);
|
|
const updatedLocations = [
|
|
...response.data.details,
|
|
{ partnername: 'All', partnerid: -1 } // Add your new object here
|
|
];
|
|
console.log('fetchLocations', updatedLocations);
|
|
|
|
return updatedLocations;
|
|
};
|
|
// ==============================|| gettenantlocations (orders summary))||============================== //
|
|
|
|
export const gettenantlocations = async ({ queryKey }) => {
|
|
const [, searchLocation] = queryKey;
|
|
try {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantlocations?tenantid=${tenid}&keyword=${searchLocation}`);
|
|
return response.data?.details || [];
|
|
} catch (error) {
|
|
// Must return an array — downstream consumers do `.map`/`.length` and a
|
|
// string here crashes the entire Locations page.
|
|
console.error('Error fetching tenant locations:', error);
|
|
return [];
|
|
}
|
|
};
|
|
|
|
// ==============================|| fetchDeliverySummary (orders summary)||============================== //
|
|
export const fetchDeliverySummary = async ({ queryKey }) => {
|
|
const [, startdate, enddate, currentStatus, locationId] = queryKey;
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/deliveries/deliverysummary?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}`
|
|
);
|
|
console.log('fetchDeliverySummary', response.data.details);
|
|
return response.data.details;
|
|
};
|
|
// ==============================|| fetchAppLocations (report summary))||============================== //
|
|
|
|
export const fetchAppLocations = async () => {
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/partners/getpartners`);
|
|
const updatedLocations = [
|
|
...response.data.details,
|
|
{ partnername: 'All', applocationid: -1 } // Add your new object here
|
|
];
|
|
console.log('fetchAppLocations', updatedLocations);
|
|
|
|
return updatedLocations;
|
|
};
|
|
|
|
// ==============================|| fetchRidersSummary (riders summary)||============================== //
|
|
|
|
export const fetchRidersSummary = async ({ queryKey }) => {
|
|
console.log('queryKey for fetchRidersSummary', queryKey);
|
|
const [tenantid, startdate, enddate] = queryKey;
|
|
const response = await axios.get(
|
|
`${process.env.REACT_APP_URL}/deliveries/getridersummary/?tenantid=${tenantid}&fromdate=${startdate}&todate=${enddate}`
|
|
);
|
|
console.log('fetchRidersSummary', response.data.details);
|
|
|
|
return response.data.details;
|
|
};
|
|
|
|
// ==============================|| fetchorderdetails (orders detail)||============================== //
|
|
export const fetchorderdetails = async ({ pageParam = 0, queryKey }) => {
|
|
const [startdate, enddate, currentStatus, locationId, searchword] = queryKey;
|
|
|
|
const limit = 10;
|
|
const pageno = pageParam + 1; // ✅ increment page by 1 each time
|
|
|
|
const response = await axios.get(
|
|
`${
|
|
process.env.REACT_APP_URL
|
|
}/deliveries/getdeliveries/?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}&status=${
|
|
currentStatus === 'All' ? '' : currentStatus
|
|
}&pageno=${pageno}&pagesize=${limit}&keyword=${searchword}`
|
|
);
|
|
|
|
const details = response.data.details || [];
|
|
const hasMore = details.length === limit; // ✅ only if you got full data
|
|
|
|
return {
|
|
details,
|
|
nextPage: hasMore ? pageParam + 1 : undefined // nextPage increments correctly
|
|
};
|
|
};
|
|
|
|
// export const fetchorderdetails = async ({ queryKey }) => {
|
|
// console.log('queryKey of fetchorderdetails', queryKey);
|
|
// const [startdate, enddate, currentStatus] = queryKey;
|
|
// const response = await axios.get(
|
|
// `${process.env.REACT_APP_URL}/deliveries/getdeliveries/?tenantid=${tenid}&fromdate=${startdate}&todate=${enddate}&status=${
|
|
// currentStatus == 'All' ? '' : currentStatus
|
|
// }`
|
|
// );
|
|
// console.log('fetchorderdetails', response.data.details);
|
|
// return response.data.details;
|
|
// };
|
|
// ==============================|| fetchCount (orders detail)||============================== //
|
|
export const fetchCount = async ({ queryKey }) => {
|
|
console.log('queryKey of fetchCount', queryKey);
|
|
const [startdate, enddate] = queryKey;
|
|
const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getorders/?fromdate=${startdate}&todate=${enddate}`);
|
|
const calculateOrderCounts = () => {
|
|
let deliveredCount = 0;
|
|
let pendingCount = 0;
|
|
let cancelledCount = 0;
|
|
|
|
response.data.details.forEach((order) => {
|
|
const status = order.orderstatus;
|
|
if (status === 'delivered') {
|
|
deliveredCount++;
|
|
} else if (status === 'pending') {
|
|
pendingCount++;
|
|
} else if (status === 'cancelled') {
|
|
cancelledCount++;
|
|
}
|
|
});
|
|
|
|
return { deliveredCount, pendingCount, cancelledCount };
|
|
};
|
|
console.log('fetchCount', calculateOrderCounts());
|
|
|
|
return calculateOrderCounts();
|
|
};
|
|
|
|
// ==============================|| fetchRidersLogs (RiderLogs)||============================== //
|
|
|
|
export const fetchRidersLogs = async ({ queryKey }) => {
|
|
const [appId, startdate, riderSearch = ''] = queryKey;
|
|
// const riderLogsResponse = await axios.get(
|
|
// `${process.env.REACT_APP_URL}/partners/getriderlogs/?applocationid=${appId}&fromdate=${startdate || ''}&todate=${startdate}&keyword=${
|
|
// riderSearch || ''
|
|
// }`
|
|
// );
|
|
const riderLogsResponse = await axios.get(
|
|
`https://jupiter.nearle.app/live/api/v2/partners/getriderlogs/?applocationid=${appId}&fromdate=${startdate || ''}&todate=${
|
|
startdate || ''
|
|
}&keyword=${riderSearch || ''}`
|
|
);
|
|
console.log('fetchRidersLogs', riderLogsResponse.data.details);
|
|
return riderLogsResponse.data.details;
|
|
};
|
|
|
|
// ==============================|| Dispatch / Preview APIs (ported from xpressconsole) ||============================== //
|
|
|
|
// Returns the rider's latest periodic log entry — battery, GPS, status,
|
|
// current order. Used by the Rider Info modal on the Dispatch page.
|
|
export const getRiderPeriodicLogs = async (userid) => {
|
|
const url = `${process.env.REACT_APP_URL}/utils/getriderperiodiclogs${userid ? `?userid=${userid}` : ''}`;
|
|
const response = await axios.get(url);
|
|
if (response.data && response.data.status) return response.data.data;
|
|
return null;
|
|
};
|
|
|
|
// Fetches the riders dropdown list for an app location.
|
|
export const fetchRidersList = async ({ queryKey }) => {
|
|
try {
|
|
const [, appId] = queryKey;
|
|
const { data } = await axios.get(`${process.env.REACT_APP_URL}/partners/getriders/?applocationid=${appId}`);
|
|
const response = data?.details
|
|
? data.details.map((val) => ({
|
|
...val,
|
|
label: `${val.firstname} ${val.lastname} | ${val.contactno}`
|
|
}))
|
|
: [];
|
|
return response;
|
|
} catch (err) {
|
|
OpenToast(err.message, 'error', 2000);
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
// Optimise the orders (bike solver).
|
|
export const createOptimisationDeliveries = async (deliveryData) => {
|
|
const response = await axios.post(`https://routes.workolik.com/api/v1/optimization/createdeliveries`, deliveryData.deliveries);
|
|
return response.data;
|
|
};
|
|
|
|
// Server-side step reconciliation after manual edits in Preview.
|
|
export const reconcileSteps = async ({ riders }) => {
|
|
const response = await axios.post(`https://routes.workolik.com/api/v1/optimization/reconcile-steps`, { riders });
|
|
return response.data;
|
|
};
|
|
|
|
// Batch efficiency analysis — batch ∈ 'morning' | 'afternoon' | 'evening'.
|
|
export const fetchBatchEfficiency = async ({ batch, tenantId }) => {
|
|
const response = await axios.post(
|
|
`https://routes.workolik.com/api/v1/batch/efficiency`,
|
|
{ batch, tenant_id: tenantId },
|
|
{
|
|
headers: { 'Content-Type': 'application/json' },
|
|
validateStatus: () => true
|
|
}
|
|
);
|
|
return response.data;
|
|
};
|
|
|
|
// Final commit of dispatched deliveries — coerces userid/rider_id to int at
|
|
// the boundary so a string upstream can't cause a 500 unmarshal error.
|
|
export const finalCreatedeliveries = async (deliveryData) => {
|
|
const toInt = (v) => {
|
|
const n = Number(v);
|
|
return Number.isFinite(n) ? n : v;
|
|
};
|
|
const deliveries = (deliveryData.deliveries || []).map((d) => ({
|
|
...d,
|
|
userid: toInt(d.userid),
|
|
rider_id: toInt(d.rider_id)
|
|
}));
|
|
const response = await axios.post(`https://jupiter.nearle.app/live/api/v1/deliveries/createdeliveries`, deliveries);
|
|
return response.data;
|
|
};
|
|
|
|
// Auto rider assignment via either the bike solver or the auto/multi-trip
|
|
// solver. Body shape differs per mode; absent_riders is merged through.
|
|
export const createAutomationDeliveries = async (variables) => {
|
|
const absentRiders = Array.isArray(variables.absent_riders) ? variables.absent_riders : [];
|
|
|
|
const url =
|
|
variables.selectedMode.value == 1
|
|
? `https://routes.workolik.com/api/v1/optimization/riderassign?hypertuning_params=${variables.hypertuning_params}`
|
|
: `https://routemate.workolik.com/api/v1/optimization/riderassign?strategy=multi_trip`;
|
|
|
|
const body =
|
|
variables.selectedMode.value == 1
|
|
? { deliveries: variables.deliveries, absent_riders: absentRiders }
|
|
: { ...(variables.data || {}), absent_riders: absentRiders };
|
|
|
|
const response = await axios.post(url, body);
|
|
return response.data;
|
|
};
|
|
|
|
// Push a notification to a rider after assignment.
|
|
export const notifyRider = async (riderToken) => {
|
|
if (!riderToken) {
|
|
throw new Error('Invalid rider token');
|
|
}
|
|
const response = await axios.post(`${process.env.REACT_APP_URL}/utils/notifyuser`, {
|
|
token: riderToken,
|
|
notification: {
|
|
title: 'NearleXpress',
|
|
body: 'Orders have been placed for delivery. Kindly accept and process deliveries',
|
|
sound: 'ring',
|
|
image: ''
|
|
}
|
|
});
|
|
return response.data;
|
|
};
|
|
|
|
// Paginated deliveries fetch — supports both "All zones" (appId === 0) and
|
|
// per-zone scoping. Returns { rows, nextPage } for useInfiniteQuery.
|
|
export const fetchDeliveries = async ({ pageParam = 1, queryKey }) => {
|
|
let [, appId, userid, currentStatus, startdate, enddate, rowsPerPage, searchword, tenantid, locationid, riderid] = queryKey;
|
|
currentStatus = currentStatus == 'All' ? 'all' : currentStatus;
|
|
const url =
|
|
appId === 0
|
|
? `${process.env.REACT_APP_URL}/deliveries/getdeliveries/?appuserid=${userid}&status=${currentStatus}&fromdate=${startdate}&todate=${enddate}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${searchword}&tenantid=${tenantid}&locationid=${locationid}&userid=${riderid}`
|
|
: `${process.env.REACT_APP_URL}/deliveries/getdeliveries/?applocationid=${appId}&status=${currentStatus}&fromdate=${startdate}&todate=${enddate}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${searchword}&tenantid=${tenantid}&locationid=${locationid}&userid=${riderid}`;
|
|
const response = await axios.get(url);
|
|
|
|
return {
|
|
rows: response.data.details,
|
|
nextPage: response.data.details.length === Number(rowsPerPage) ? pageParam + 1 : undefined
|
|
};
|
|
};
|