sgerp-frontend-lib 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/connection-manager.d.ts +48 -0
- package/dist/connection-manager.d.ts.map +1 -0
- package/dist/connection-manager.js +156 -0
- package/dist/index.js +20 -2
- package/dist/locales/locale-server.d.ts +10 -0
- package/dist/locales/locale-server.d.ts.map +1 -0
- package/dist/locales/locale-server.js +49 -0
- package/dist/locales/locale.d.ts +23 -0
- package/dist/locales/locale.d.ts.map +1 -0
- package/dist/locales/locale.js +145 -0
- package/dist/locales/locale_en.d.ts.map +1 -1
- package/dist/locales/locale_en.js +93 -9
- package/dist/locales/locale_ja.d.ts.map +1 -1
- package/dist/locales/locale_ja.js +93 -9
- package/dist/locales/locale_ms.d.ts.map +1 -1
- package/dist/locales/locale_ms.js +84 -9
- package/dist/locales/useLocalization.d.ts +11 -0
- package/dist/locales/useLocalization.d.ts.map +1 -0
- package/dist/locales/useLocalization.js +64 -0
- package/dist/locales.d.ts +228 -0
- package/dist/locales.d.ts.map +1 -0
- package/dist/locales.js +229 -0
- package/dist/sgerp/api/client.d.ts +45 -0
- package/dist/sgerp/api/client.d.ts.map +1 -0
- package/dist/sgerp/api/client.js +141 -0
- package/dist/sgerp/client.js +341 -0
- package/dist/sgerp/collection.d.ts +391 -0
- package/dist/sgerp/collection.d.ts.map +1 -0
- package/dist/sgerp/collection.js +756 -0
- package/dist/sgerp/collections/account/user.d.ts +8 -0
- package/dist/sgerp/collections/account/user.d.ts.map +1 -0
- package/dist/sgerp/collections/account/user.js +10 -0
- package/dist/sgerp/collections/masstransit/building.d.ts +26 -0
- package/dist/sgerp/collections/masstransit/building.d.ts.map +1 -0
- package/dist/sgerp/collections/masstransit/building.js +53 -0
- package/dist/sgerp/collections/masstransit/transitstop.d.ts +15 -0
- package/dist/sgerp/collections/masstransit/transitstop.d.ts.map +1 -0
- package/dist/sgerp/collections/masstransit/transitstop.js +54 -0
- package/dist/sgerp/collections/masstransit/transitstopset.d.ts +10 -0
- package/dist/sgerp/collections/masstransit/transitstopset.d.ts.map +1 -0
- package/dist/sgerp/collections/masstransit/transitstopset.js +10 -0
- package/dist/sgerp/collections/sharing/organization-project.d.ts +11 -0
- package/dist/sgerp/collections/sharing/organization-project.d.ts.map +1 -0
- package/dist/sgerp/collections/sharing/organization-project.js +13 -0
- package/dist/sgerp/collections/sharing/organization.d.ts +11 -0
- package/dist/sgerp/collections/sharing/organization.d.ts.map +1 -0
- package/dist/sgerp/collections/sharing/organization.js +13 -0
- package/dist/sgerp/collections/sharing/pricing.d.ts +18 -0
- package/dist/sgerp/collections/sharing/pricing.d.ts.map +1 -0
- package/dist/sgerp/collections/sharing/pricing.js +23 -0
- package/dist/sgerp/collections/sharing/project-member.d.ts +8 -0
- package/dist/sgerp/collections/sharing/project-member.d.ts.map +1 -0
- package/dist/sgerp/collections/sharing/project-member.js +10 -0
- package/dist/sgerp/collections/sharing/project.d.ts +8 -0
- package/dist/sgerp/collections/sharing/project.d.ts.map +1 -0
- package/dist/sgerp/collections/sharing/project.js +10 -0
- package/dist/sgerp/collections/simulation/booking.d.ts +11 -0
- package/dist/sgerp/collections/simulation/booking.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/booking.js +13 -0
- package/dist/sgerp/collections/simulation/dataset.d.ts +14 -0
- package/dist/sgerp/collections/simulation/dataset.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/dataset.js +17 -0
- package/dist/sgerp/collections/simulation/driver.d.ts +12 -0
- package/dist/sgerp/collections/simulation/driver.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/driver.js +40 -0
- package/dist/sgerp/collections/simulation/geofence.d.ts +24 -0
- package/dist/sgerp/collections/simulation/geofence.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/geofence.js +66 -0
- package/dist/sgerp/collections/simulation/mapboxtoken.d.ts +18 -0
- package/dist/sgerp/collections/simulation/mapboxtoken.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/mapboxtoken.js +24 -0
- package/dist/sgerp/collections/simulation/node.js +13 -0
- package/dist/sgerp/collections/simulation/operationslocation.d.ts +28 -0
- package/dist/sgerp/collections/simulation/operationslocation.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/operationslocation.js +64 -0
- package/dist/sgerp/collections/simulation/operationslocationgroup.d.ts +12 -0
- package/dist/sgerp/collections/simulation/operationslocationgroup.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/operationslocationgroup.js +24 -0
- package/dist/sgerp/collections/simulation/routingprofile.d.ts +10 -0
- package/dist/sgerp/collections/simulation/routingprofile.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/routingprofile.js +10 -0
- package/dist/sgerp/collections/simulation/simulation.d.ts +12 -0
- package/dist/sgerp/collections/simulation/simulation.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/simulation.js +35 -0
- package/dist/sgerp/collections/simulation/simulationprocessor.d.ts +19 -0
- package/dist/sgerp/collections/simulation/simulationprocessor.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/simulationprocessor.js +27 -0
- package/dist/sgerp/collections/simulation/vehicle.js +13 -0
- package/dist/sgerp/collections/simulation/vehicletype.d.ts +11 -0
- package/dist/sgerp/collections/simulation/vehicletype.d.ts.map +1 -0
- package/dist/sgerp/collections/simulation/vehicletype.js +13 -0
- package/dist/sgerp/collections/sms_notify/smsscheduled.d.ts +11 -0
- package/dist/sgerp/collections/sms_notify/smsscheduled.d.ts.map +1 -0
- package/dist/sgerp/collections/sms_notify/smsscheduled.js +13 -0
- package/dist/sgerp/collections/transportation/passenger.d.ts +8 -0
- package/dist/sgerp/collections/transportation/passenger.d.ts.map +1 -0
- package/dist/sgerp/collections/transportation/passenger.js +10 -0
- package/dist/sgerp/collections/transportation/ticket.d.ts +11 -0
- package/dist/sgerp/collections/transportation/ticket.d.ts.map +1 -0
- package/dist/sgerp/collections/transportation/ticket.js +13 -0
- package/dist/sgerp/collections/transportation/transaction.d.ts +11 -0
- package/dist/sgerp/collections/transportation/transaction.d.ts.map +1 -0
- package/dist/sgerp/collections/transportation/transaction.js +13 -0
- package/dist/sgerp/constants/bulkoperations-enums.d.ts +71 -0
- package/dist/sgerp/constants/bulkoperations-enums.d.ts.map +1 -0
- package/dist/sgerp/constants/bulkoperations-enums.js +99 -0
- package/dist/sgerp/constants/messages-enums.d.ts +47 -0
- package/dist/sgerp/constants/messages-enums.d.ts.map +1 -0
- package/dist/sgerp/constants/messages-enums.js +67 -0
- package/dist/sgerp/constants/scheduling-enums.d.ts +42 -0
- package/dist/sgerp/constants/scheduling-enums.d.ts.map +1 -0
- package/dist/sgerp/constants/scheduling-enums.js +61 -0
- package/dist/sgerp/constants/simulation-enums.d.ts +93 -0
- package/dist/sgerp/constants/simulation-enums.d.ts.map +1 -0
- package/dist/sgerp/constants/simulation-enums.js +147 -0
- package/dist/sgerp/constants/solver-strategies.d.ts +75 -0
- package/dist/sgerp/constants/solver-strategies.d.ts.map +1 -0
- package/dist/sgerp/constants/solver-strategies.js +26 -0
- package/dist/sgerp/context/sgerp-context.js +134 -0
- package/dist/sgerp/domains.d.ts +47 -0
- package/dist/sgerp/domains.d.ts.map +1 -0
- package/dist/sgerp/domains.js +45 -0
- package/dist/sgerp/hooks/use-collection.js +122 -0
- package/dist/sgerp/hooks/use-live-updates.js +16 -13
- package/dist/sgerp/index.js +153 -0
- package/dist/sgerp/map-states/operations-location-state.d.ts +12 -0
- package/dist/sgerp/map-states/operations-location-state.d.ts.map +1 -0
- package/dist/sgerp/map-states/operations-location-state.js +86 -0
- package/dist/sgerp/routing/index.d.ts +51 -0
- package/dist/sgerp/routing/index.d.ts.map +1 -0
- package/dist/sgerp/routing/index.js +373 -0
- package/dist/sgerp/simulation-logic/fetchUtils.js +226 -0
- package/dist/sgerp/simulation-logic/index.js +27 -7
- package/dist/sgerp/simulation-logic/manualEditUtils.js +69 -0
- package/dist/sgerp/simulation-logic/mapUtils.js +58 -0
- package/dist/sgerp/simulation-logic/optimisticUpdateUtils.js +8 -5
- package/dist/sgerp/simulation-logic/referenceUtils.js +110 -0
- package/dist/sgerp/simulation-logic/routeCalculationUtils.js +43 -0
- package/dist/sgerp/simulation-logic/timeShiftUtils.js +63 -0
- package/dist/sgerp/types/account/user.d.ts +38 -0
- package/dist/sgerp/types/account/user.d.ts.map +1 -0
- package/dist/sgerp/types/account/user.js +2 -0
- package/dist/sgerp/types/bulkoperations/index.d.ts +37 -0
- package/dist/sgerp/types/bulkoperations/index.d.ts.map +1 -0
- package/dist/sgerp/types/bulkoperations/index.js +35 -0
- package/dist/sgerp/types/bulkoperations/vehicle-upload.d.ts +335 -0
- package/dist/sgerp/types/bulkoperations/vehicle-upload.d.ts.map +1 -0
- package/dist/sgerp/types/bulkoperations/vehicle-upload.js +49 -0
- package/dist/sgerp/types/config.d.ts +25 -0
- package/dist/sgerp/types/config.d.ts.map +1 -0
- package/dist/sgerp/types/config.js +2 -0
- package/dist/sgerp/types/geojson.d.ts +45 -0
- package/dist/sgerp/types/geojson.d.ts.map +1 -0
- package/dist/sgerp/types/geojson.js +6 -0
- package/dist/sgerp/types/map.d.ts +24 -0
- package/dist/sgerp/types/map.d.ts.map +1 -0
- package/dist/sgerp/types/map.js +2 -0
- package/dist/sgerp/types/masstransit/building.d.ts +24 -0
- package/dist/sgerp/types/masstransit/building.d.ts.map +1 -0
- package/dist/sgerp/types/masstransit/building.js +2 -0
- package/dist/sgerp/types/masstransit/transitstop.d.ts +35 -0
- package/dist/sgerp/types/masstransit/transitstop.d.ts.map +1 -0
- package/dist/sgerp/types/masstransit/transitstop.js +2 -0
- package/dist/sgerp/types/masstransit/transitstopset.d.ts +14 -0
- package/dist/sgerp/types/masstransit/transitstopset.d.ts.map +1 -0
- package/dist/sgerp/types/masstransit/transitstopset.js +2 -0
- package/dist/sgerp/types/sharing/organization-project.d.ts +14 -0
- package/dist/sgerp/types/sharing/organization-project.d.ts.map +1 -0
- package/dist/sgerp/types/sharing/organization-project.js +2 -0
- package/dist/sgerp/types/sharing/organization.d.ts +14 -0
- package/dist/sgerp/types/sharing/organization.d.ts.map +1 -0
- package/dist/sgerp/types/sharing/organization.js +2 -0
- package/dist/sgerp/types/sharing/pricing.d.ts +98 -0
- package/dist/sgerp/types/sharing/pricing.d.ts.map +1 -0
- package/dist/sgerp/types/sharing/pricing.js +2 -0
- package/dist/sgerp/types/sharing/project-member.d.ts +15 -0
- package/dist/sgerp/types/sharing/project-member.d.ts.map +1 -0
- package/dist/sgerp/types/sharing/project-member.js +2 -0
- package/dist/sgerp/types/sharing/project.d.ts +16 -0
- package/dist/sgerp/types/sharing/project.d.ts.map +1 -0
- package/dist/sgerp/types/sharing/project.js +2 -0
- package/dist/sgerp/types/simulation/booking.d.ts +128 -0
- package/dist/sgerp/types/simulation/booking.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/booking.js +24 -0
- package/dist/sgerp/types/simulation/calculation-params.d.ts +20 -0
- package/dist/sgerp/types/simulation/calculation-params.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/calculation-params.js +2 -0
- package/dist/sgerp/types/simulation/dataset.d.ts +16 -0
- package/dist/sgerp/types/simulation/dataset.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/dataset.js +2 -0
- package/dist/sgerp/types/simulation/driver.d.ts +19 -0
- package/dist/sgerp/types/simulation/driver.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/driver.js +2 -0
- package/dist/sgerp/types/simulation/geofence.d.ts +19 -0
- package/dist/sgerp/types/simulation/geofence.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/geofence.js +2 -0
- package/dist/sgerp/types/simulation/logistics-api-settings.d.ts +98 -0
- package/dist/sgerp/types/simulation/logistics-api-settings.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/logistics-api-settings.js +104 -0
- package/dist/sgerp/types/simulation/mapboxtoken.d.ts +13 -0
- package/dist/sgerp/types/simulation/mapboxtoken.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/mapboxtoken.js +2 -0
- package/dist/sgerp/types/simulation/node.js +5 -2
- package/dist/sgerp/types/simulation/operationslocation.d.ts +40 -0
- package/dist/sgerp/types/simulation/operationslocation.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/operationslocation.js +2 -0
- package/dist/sgerp/types/simulation/operationslocationgroup.d.ts +11 -0
- package/dist/sgerp/types/simulation/operationslocationgroup.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/operationslocationgroup.js +2 -0
- package/dist/sgerp/types/simulation/pricing.d.ts +171 -0
- package/dist/sgerp/types/simulation/pricing.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/pricing.js +2 -0
- package/dist/sgerp/types/simulation/route-cost-modification.d.ts +35 -0
- package/dist/sgerp/types/simulation/route-cost-modification.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/route-cost-modification.js +5 -0
- package/dist/sgerp/types/simulation/routing-engine-settings.d.ts +42 -0
- package/dist/sgerp/types/simulation/routing-engine-settings.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/routing-engine-settings.js +35 -0
- package/dist/sgerp/types/simulation/routingprofile.d.ts +32 -0
- package/dist/sgerp/types/simulation/routingprofile.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/routingprofile.js +37 -0
- package/dist/sgerp/types/simulation/simulation.d.ts +120 -0
- package/dist/sgerp/types/simulation/simulation.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/simulation.js +2 -0
- package/dist/sgerp/types/simulation/simulationprocessor.d.ts +31 -0
- package/dist/sgerp/types/simulation/simulationprocessor.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/simulationprocessor.js +2 -0
- package/dist/sgerp/types/simulation/vehicle.js +2 -1
- package/dist/sgerp/types/simulation/vehicletype.d.ts +33 -0
- package/dist/sgerp/types/simulation/vehicletype.d.ts.map +1 -0
- package/dist/sgerp/types/simulation/vehicletype.js +2 -0
- package/dist/sgerp/types/sms_notify/smsscheduled.d.ts +36 -0
- package/dist/sgerp/types/sms_notify/smsscheduled.d.ts.map +1 -0
- package/dist/sgerp/types/sms_notify/smsscheduled.js +6 -0
- package/dist/sgerp/types/transportation/passenger.d.ts +49 -0
- package/dist/sgerp/types/transportation/passenger.d.ts.map +1 -0
- package/dist/sgerp/types/transportation/passenger.js +13 -0
- package/dist/sgerp/types/transportation/ticket.d.ts +31 -0
- package/dist/sgerp/types/transportation/ticket.d.ts.map +1 -0
- package/dist/sgerp/types/transportation/ticket.js +2 -0
- package/dist/sgerp/types/transportation/transaction.d.ts +71 -0
- package/dist/sgerp/types/transportation/transaction.d.ts.map +1 -0
- package/dist/sgerp/types/transportation/transaction.js +54 -0
- package/dist/sgerp/utils/bookingPayload.d.ts +80 -0
- package/dist/sgerp/utils/bookingPayload.d.ts.map +1 -0
- package/dist/sgerp/utils/bookingPayload.js +44 -0
- package/dist/sgerp/utils/color.d.ts +30 -0
- package/dist/sgerp/utils/color.d.ts.map +1 -0
- package/dist/sgerp/utils/color.js +117 -0
- package/dist/sgerp/utils/enum-helpers.d.ts +41 -0
- package/dist/sgerp/utils/enum-helpers.d.ts.map +1 -0
- package/dist/sgerp/utils/enum-helpers.js +54 -0
- package/dist/sgerp/utils/routeUtils.js +171 -0
- package/package.json +1 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchVehicles = fetchVehicles;
|
|
4
|
+
exports.fetchBookings = fetchBookings;
|
|
5
|
+
exports.fetchNodes = fetchNodes;
|
|
6
|
+
exports.fetchDrivers = fetchDrivers;
|
|
7
|
+
exports.fetchDriversByProject = fetchDriversByProject;
|
|
8
|
+
exports.fetchOperationsLocationsByProject = fetchOperationsLocationsByProject;
|
|
9
|
+
exports.fetchGeofences = fetchGeofences;
|
|
10
|
+
exports.fetchSimulationGeofence = fetchSimulationGeofence;
|
|
11
|
+
exports.fetchSimulationData = fetchSimulationData;
|
|
12
|
+
const client_1 = require("@/sgerplib/sgerp/api/client");
|
|
13
|
+
/**
|
|
14
|
+
* Fetch vehicles for a simulation
|
|
15
|
+
* Uses fetchAll() to get all vehicles regardless of count
|
|
16
|
+
*/
|
|
17
|
+
async function fetchVehicles(api, simulationId) {
|
|
18
|
+
await api.collections.vehicle.fetchAll({
|
|
19
|
+
simulation_id__in: simulationId,
|
|
20
|
+
only_fields: 'id,agent_id,driver_id,service_number,registration_number,lat,lon,gps_modified_at,in_use,color,routing_engine_settings,simulation_id,start_time,end_time,modified_at,capacity,bearing,geofence_ids,project_id',
|
|
21
|
+
not__is_invalidated: true,
|
|
22
|
+
order_by: 'id' // Order by ID ascending for consistent ordering
|
|
23
|
+
});
|
|
24
|
+
return api.collections.vehicle.models;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetch bookings for a simulation using the microservices API
|
|
28
|
+
* Based on dashviewer approach: model=booking&booking_type=customer&simulation_id__in=...
|
|
29
|
+
* Uses fetchAll() to get all bookings regardless of count
|
|
30
|
+
*/
|
|
31
|
+
async function fetchBookings(api, simulationId) {
|
|
32
|
+
await api.collections.booking.fetchAll({
|
|
33
|
+
booking_type: 'customer',
|
|
34
|
+
simulation_id__in: simulationId,
|
|
35
|
+
//not__is_invalidated: true,
|
|
36
|
+
only_fields: 'min_pickup_time,max_dropoff_time,created_at,id,uid,simulation_id,state,pickup_location_lat,pickup_location_lon,dropoff_location_lat,dropoff_location_lon,pickup_location_name,dropoff_location_name,pickup_service_time,dropoff_service_time,planned_pickup_time,planned_dropoff_time,customer_id,booking_type,modified_at,demand,actual_dropoff_time,fail_to_board_time,cancellation_time,data',
|
|
37
|
+
not__is_invalidated: true
|
|
38
|
+
});
|
|
39
|
+
return api.collections.booking.models;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fetch nodes for a simulation
|
|
43
|
+
* Uses fetchAll() to get all nodes regardless of count
|
|
44
|
+
*/
|
|
45
|
+
async function fetchNodes(api, simulationId) {
|
|
46
|
+
await api.collections.node.fetchAll({
|
|
47
|
+
simulation_id__in: simulationId,
|
|
48
|
+
only_fields: 'id,uid,booking_id,booking_uid,simulation_id,assigned_vehicle_id,lat,lon,node_type,scheduled_ts,location_name,display_name,demand,status,service_time,open_time_ts,close_time_ts,data,modified_at',
|
|
49
|
+
not__is_invalidated: true
|
|
50
|
+
});
|
|
51
|
+
return api.collections.node.models;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Fetch drivers for vehicles from legacy Tastypie API
|
|
55
|
+
* Extracts driver_id values from vehicles and fetches them using id__in
|
|
56
|
+
* Uses legacy API because it includes username field
|
|
57
|
+
* Uses a separate collection context to avoid interfering with main drivers page
|
|
58
|
+
*/
|
|
59
|
+
async function fetchDrivers(api, vehicles) {
|
|
60
|
+
var _a;
|
|
61
|
+
// Extract unique driver IDs from vehicles
|
|
62
|
+
const driverIds = vehicles
|
|
63
|
+
.map(v => v.driver_id)
|
|
64
|
+
.filter((id) => id != null && id > 0);
|
|
65
|
+
const uniqueDriverIds = [...new Set(driverIds)];
|
|
66
|
+
if (uniqueDriverIds.length === 0) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
// Fetch drivers from legacy Tastypie API (includes username field)
|
|
70
|
+
const response = await client_1.APIClient.get(`/api/v2/driver/?id__in=${uniqueDriverIds.join(',')}&limit=1000`);
|
|
71
|
+
const drivers = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.objects) || [];
|
|
72
|
+
// Use context-specific collection to avoid interfering with main drivers page
|
|
73
|
+
const driverCollection = api.getCollection('driver', 'simulation-detail');
|
|
74
|
+
driverCollection.add(drivers);
|
|
75
|
+
return drivers;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Fetch all drivers for a project from microservices GET API
|
|
79
|
+
* Used for driver assignment page where we need all available drivers
|
|
80
|
+
* Uses first_name and id fields for display
|
|
81
|
+
* Uses a separate collection context to avoid interfering with main drivers page
|
|
82
|
+
*/
|
|
83
|
+
async function fetchDriversByProject(api, projectId) {
|
|
84
|
+
// Use context-specific collection to avoid interfering with main drivers page
|
|
85
|
+
const driverCollection = api.getCollection('driver', 'simulation-detail');
|
|
86
|
+
// Fetch drivers from microservices GET API
|
|
87
|
+
await driverCollection.fetchAll({
|
|
88
|
+
project_id: projectId,
|
|
89
|
+
only_fields: 'id,first_name,last_name,project_id'
|
|
90
|
+
});
|
|
91
|
+
return driverCollection.models;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Fetch operations locations (depots) for a project from microservices GET API
|
|
95
|
+
* Used for driver assignment page to show depot locations where buses can go (e.g., for lunch breaks)
|
|
96
|
+
* Uses a separate collection context to avoid interfering with main operations locations page
|
|
97
|
+
*/
|
|
98
|
+
async function fetchOperationsLocationsByProject(api, projectId) {
|
|
99
|
+
// Use context-specific collection to avoid interfering with main operations locations page
|
|
100
|
+
const operationsLocationCollection = api.getCollection('operationslocation', 'simulation-detail');
|
|
101
|
+
// Fetch operations locations from microservices GET API
|
|
102
|
+
await operationsLocationCollection.fetchAll({
|
|
103
|
+
project_id: projectId,
|
|
104
|
+
only_fields: 'id,name,code,external_id,point,address,postal_code,group_id,project_id,h3,created_at,modified_at'
|
|
105
|
+
});
|
|
106
|
+
return operationsLocationCollection.models;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Fetch geofence IDs from simulation's geofences_zones field
|
|
110
|
+
* Uses Tastypie API to get the geofences_zones array
|
|
111
|
+
*/
|
|
112
|
+
async function fetchSimulationGeofenceZones(simulationId) {
|
|
113
|
+
var _a;
|
|
114
|
+
try {
|
|
115
|
+
const response = await client_1.APIClient.get(`/api/v2/simulation/${simulationId}?only_fields=geofences_zones`);
|
|
116
|
+
const geofencesZones = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.geofences_zones) || [];
|
|
117
|
+
// Extract geofence IDs from "/api/v2/geofence/16" format
|
|
118
|
+
const geofenceIds = geofencesZones
|
|
119
|
+
.map((zone) => {
|
|
120
|
+
const match = zone.match(/\/geofence\/(\d+)/);
|
|
121
|
+
return match ? parseInt(match[1], 10) : null;
|
|
122
|
+
})
|
|
123
|
+
.filter((id) => id !== null);
|
|
124
|
+
return geofenceIds;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error('[fetchSimulationGeofenceZones] Failed to fetch:', error);
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetch geofences for vehicles and simulation
|
|
133
|
+
* Extracts geofence_ids from vehicles and geofences_zones from simulation
|
|
134
|
+
* Merges both sets and fetches all unique geofences
|
|
135
|
+
* Uses a separate collection context to avoid interfering with main geofences page
|
|
136
|
+
*/
|
|
137
|
+
async function fetchGeofences(api, vehicles, simulationId) {
|
|
138
|
+
// Extract unique geofence IDs from vehicles
|
|
139
|
+
// Handle both number format (1840) and string format ("/api/v2/geofence/1840")
|
|
140
|
+
const vehicleGeofenceIds = vehicles
|
|
141
|
+
.flatMap(v => v.geofence_ids || [])
|
|
142
|
+
.map((id) => {
|
|
143
|
+
if (id == null) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
if (typeof id === 'number') {
|
|
147
|
+
return id;
|
|
148
|
+
}
|
|
149
|
+
// Extract number from string like "/api/v2/geofence/1840"
|
|
150
|
+
if (typeof id === 'string') {
|
|
151
|
+
const match = id.match(/\/geofence\/(\d+)/);
|
|
152
|
+
return match ? parseInt(match[1], 10) : null;
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
})
|
|
156
|
+
.filter((id) => id !== null);
|
|
157
|
+
// Fetch geofence IDs from simulation's geofences_zones field
|
|
158
|
+
const simulationGeofenceIds = simulationId
|
|
159
|
+
? await fetchSimulationGeofenceZones(simulationId)
|
|
160
|
+
: [];
|
|
161
|
+
// Merge both sets of geofence IDs
|
|
162
|
+
const allGeofenceIds = [...vehicleGeofenceIds, ...simulationGeofenceIds];
|
|
163
|
+
const uniqueGeofenceIds = [...new Set(allGeofenceIds)];
|
|
164
|
+
if (uniqueGeofenceIds.length === 0) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
// Use context-specific collection to avoid interfering with main geofences page
|
|
168
|
+
const geofenceCollection = api.getCollection('geofence', 'simulation-detail');
|
|
169
|
+
// Fetch geofences using GET API
|
|
170
|
+
await geofenceCollection.fetch({
|
|
171
|
+
key__in: uniqueGeofenceIds.join(','),
|
|
172
|
+
only_fields: 'id,key,name,geometry,project_id'
|
|
173
|
+
});
|
|
174
|
+
return geofenceCollection.models;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Fetch main geofence for simulation
|
|
178
|
+
* Fetches the simulation's main geofence_id (UUID) using id filter
|
|
179
|
+
* Uses a separate collection context to avoid interfering with main geofences page
|
|
180
|
+
*/
|
|
181
|
+
async function fetchSimulationGeofence(api, simulation) {
|
|
182
|
+
var _a, _b;
|
|
183
|
+
console.log('[fetchSimulationGeofence] Simulation:', simulation);
|
|
184
|
+
console.log('[fetchSimulationGeofence] geofence_id:', simulation === null || simulation === void 0 ? void 0 : simulation.geofence_id);
|
|
185
|
+
if (!(simulation === null || simulation === void 0 ? void 0 : simulation.geofence_id)) {
|
|
186
|
+
console.log('[fetchSimulationGeofence] No geofence_id found, returning null');
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
// Fetch the main geofence using id filter (geofence_id is a UUID string)
|
|
190
|
+
console.log('[fetchSimulationGeofence] Fetching geofence by id:', simulation.geofence_id);
|
|
191
|
+
const response = await client_1.APIClient.get(`/api/v2/microservices/get?model=geofence&id=${simulation.geofence_id}&only_fields=id,key,name,geometry,project_id`);
|
|
192
|
+
const geofence = ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.objects) === null || _b === void 0 ? void 0 : _b[0]) || null;
|
|
193
|
+
console.log('[fetchSimulationGeofence] Fetched geofence:', geofence);
|
|
194
|
+
// Use context-specific collection to avoid interfering with main geofences page
|
|
195
|
+
// Add to collection if found
|
|
196
|
+
if (geofence) {
|
|
197
|
+
const geofenceCollection = api.getCollection('geofence', 'simulation-detail');
|
|
198
|
+
geofenceCollection.add([geofence]);
|
|
199
|
+
}
|
|
200
|
+
return geofence;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Fetch all data needed for simulation page
|
|
204
|
+
*/
|
|
205
|
+
async function fetchSimulationData(api, simulationId, simulation = null) {
|
|
206
|
+
// First fetch vehicles, bookings, and nodes in parallel
|
|
207
|
+
const [vehicles, bookings, nodes] = await Promise.all([
|
|
208
|
+
fetchVehicles(api, simulationId),
|
|
209
|
+
fetchBookings(api, simulationId),
|
|
210
|
+
fetchNodes(api, simulationId)
|
|
211
|
+
]);
|
|
212
|
+
// Then fetch drivers, geofences, and main simulation geofence based on the data
|
|
213
|
+
const [drivers, geofences, mainGeofence] = await Promise.all([
|
|
214
|
+
fetchDrivers(api, vehicles),
|
|
215
|
+
fetchGeofences(api, vehicles, simulationId),
|
|
216
|
+
fetchSimulationGeofence(api, simulation)
|
|
217
|
+
]);
|
|
218
|
+
return {
|
|
219
|
+
vehicles,
|
|
220
|
+
bookings,
|
|
221
|
+
nodes,
|
|
222
|
+
drivers,
|
|
223
|
+
geofences,
|
|
224
|
+
mainGeofence
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -1,11 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Simulation page logic utilities
|
|
3
4
|
* Inspired by dashviewer's SimulationPage/logic structure
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.processUnassignResponse = exports.hasRouteChanged = exports.calculateVehicleRoute = exports.shiftWaypointTimestamps = exports.shiftNodeTimestamps = exports.buildVehicleRouteMap = exports.vehicleComplexRearrange = exports.calculateBoundingBoxCenter = exports.attachReferences = exports.createIndexMaps = exports.fetchSimulationData = exports.fetchOperationsLocationsByProject = exports.fetchDriversByProject = exports.fetchDrivers = exports.fetchNodes = exports.fetchBookings = exports.fetchVehicles = void 0;
|
|
8
|
+
var fetchUtils_1 = require("./fetchUtils");
|
|
9
|
+
Object.defineProperty(exports, "fetchVehicles", { enumerable: true, get: function () { return fetchUtils_1.fetchVehicles; } });
|
|
10
|
+
Object.defineProperty(exports, "fetchBookings", { enumerable: true, get: function () { return fetchUtils_1.fetchBookings; } });
|
|
11
|
+
Object.defineProperty(exports, "fetchNodes", { enumerable: true, get: function () { return fetchUtils_1.fetchNodes; } });
|
|
12
|
+
Object.defineProperty(exports, "fetchDrivers", { enumerable: true, get: function () { return fetchUtils_1.fetchDrivers; } });
|
|
13
|
+
Object.defineProperty(exports, "fetchDriversByProject", { enumerable: true, get: function () { return fetchUtils_1.fetchDriversByProject; } });
|
|
14
|
+
Object.defineProperty(exports, "fetchOperationsLocationsByProject", { enumerable: true, get: function () { return fetchUtils_1.fetchOperationsLocationsByProject; } });
|
|
15
|
+
Object.defineProperty(exports, "fetchSimulationData", { enumerable: true, get: function () { return fetchUtils_1.fetchSimulationData; } });
|
|
16
|
+
var referenceUtils_1 = require("./referenceUtils");
|
|
17
|
+
Object.defineProperty(exports, "createIndexMaps", { enumerable: true, get: function () { return referenceUtils_1.createIndexMaps; } });
|
|
18
|
+
Object.defineProperty(exports, "attachReferences", { enumerable: true, get: function () { return referenceUtils_1.attachReferences; } });
|
|
19
|
+
var mapUtils_1 = require("./mapUtils");
|
|
20
|
+
Object.defineProperty(exports, "calculateBoundingBoxCenter", { enumerable: true, get: function () { return mapUtils_1.calculateBoundingBoxCenter; } });
|
|
21
|
+
var manualEditUtils_1 = require("./manualEditUtils");
|
|
22
|
+
Object.defineProperty(exports, "vehicleComplexRearrange", { enumerable: true, get: function () { return manualEditUtils_1.vehicleComplexRearrange; } });
|
|
23
|
+
Object.defineProperty(exports, "buildVehicleRouteMap", { enumerable: true, get: function () { return manualEditUtils_1.buildVehicleRouteMap; } });
|
|
24
|
+
var timeShiftUtils_1 = require("./timeShiftUtils");
|
|
25
|
+
Object.defineProperty(exports, "shiftNodeTimestamps", { enumerable: true, get: function () { return timeShiftUtils_1.shiftNodeTimestamps; } });
|
|
26
|
+
Object.defineProperty(exports, "shiftWaypointTimestamps", { enumerable: true, get: function () { return timeShiftUtils_1.shiftWaypointTimestamps; } });
|
|
27
|
+
var routeCalculationUtils_1 = require("./routeCalculationUtils");
|
|
28
|
+
Object.defineProperty(exports, "calculateVehicleRoute", { enumerable: true, get: function () { return routeCalculationUtils_1.calculateVehicleRoute; } });
|
|
29
|
+
Object.defineProperty(exports, "hasRouteChanged", { enumerable: true, get: function () { return routeCalculationUtils_1.hasRouteChanged; } });
|
|
30
|
+
var optimisticUpdateUtils_1 = require("./optimisticUpdateUtils");
|
|
31
|
+
Object.defineProperty(exports, "processUnassignResponse", { enumerable: true, get: function () { return optimisticUpdateUtils_1.processUnassignResponse; } });
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vehicleComplexRearrange = vehicleComplexRearrange;
|
|
4
|
+
exports.buildVehicleRouteMap = buildVehicleRouteMap;
|
|
5
|
+
const client_1 = require("@/sgerplib/sgerp/api/client");
|
|
6
|
+
/**
|
|
7
|
+
* Call the Manual Edit API to rearrange vehicle routes
|
|
8
|
+
*
|
|
9
|
+
* @param simulationId - The simulation ID
|
|
10
|
+
* @param vehicleRouteMap - Map of vehicle agent_id to array of node UIDs
|
|
11
|
+
* @param options - Optional settings
|
|
12
|
+
* @returns Promise with the API response
|
|
13
|
+
*/
|
|
14
|
+
async function vehicleComplexRearrange(simulationId, vehicleRouteMap, options = {}) {
|
|
15
|
+
var _a;
|
|
16
|
+
const { dryRun = false, notifyAssignment = false, strictTimeWindows = false, currentTime, } = options;
|
|
17
|
+
const requestPayload = {
|
|
18
|
+
simulation_id: simulationId,
|
|
19
|
+
dry_run: dryRun,
|
|
20
|
+
notify_assignment: notifyAssignment,
|
|
21
|
+
action: {
|
|
22
|
+
action_type: 'vehicle_complex_rearrange',
|
|
23
|
+
vehicle_route_map: vehicleRouteMap,
|
|
24
|
+
strict_time_windows: strictTimeWindows,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
// Add current_time if provided
|
|
28
|
+
if (currentTime) {
|
|
29
|
+
requestPayload.current_time = currentTime;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const response = await client_1.APIClient.post('/api/v2/microservices/edit', requestPayload);
|
|
33
|
+
return response.data;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// Check if this is an axios error with response data
|
|
37
|
+
if (error && typeof error === 'object' && 'response' in error) {
|
|
38
|
+
const axiosError = error;
|
|
39
|
+
const errorData = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data;
|
|
40
|
+
// Handle both single error and array of errors
|
|
41
|
+
if (Array.isArray(errorData)) {
|
|
42
|
+
const errorMessages = errorData.map((e) => e.error).join('; ');
|
|
43
|
+
throw new Error(`Manual Edit API errors: ${errorMessages}`);
|
|
44
|
+
}
|
|
45
|
+
else if (errorData && 'error' in errorData) {
|
|
46
|
+
throw new Error(`Manual Edit API error: ${errorData.error} (${errorData.error_code})`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Re-throw the original error if we couldn't parse it
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build a vehicle route map from nodes grouped by vehicle
|
|
55
|
+
*
|
|
56
|
+
* @param nodesByVehicle - Map of vehicle agent_id to array of nodes
|
|
57
|
+
* @returns Vehicle route map for Manual Edit API
|
|
58
|
+
*/
|
|
59
|
+
function buildVehicleRouteMap(nodesByVehicle) {
|
|
60
|
+
const routeMap = {};
|
|
61
|
+
nodesByVehicle.forEach((nodes, vehicleAgentId) => {
|
|
62
|
+
// Extract node UIDs in order
|
|
63
|
+
const route = nodes
|
|
64
|
+
.filter(node => node.uid) // Only include nodes with UIDs
|
|
65
|
+
.map(node => node.uid);
|
|
66
|
+
routeMap[vehicleAgentId] = { route };
|
|
67
|
+
});
|
|
68
|
+
return routeMap;
|
|
69
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateBoundingBoxCenter = calculateBoundingBoxCenter;
|
|
4
|
+
/**
|
|
5
|
+
* Calculate bounding box center from vehicles and bookings
|
|
6
|
+
* Filters out invalid coordinates (0,0) and calculates the average center point
|
|
7
|
+
*/
|
|
8
|
+
function calculateBoundingBoxCenter(vehicles, bookings) {
|
|
9
|
+
const coordinates = [];
|
|
10
|
+
// Add vehicle coordinates (excluding 0,0)
|
|
11
|
+
vehicles.forEach(v => {
|
|
12
|
+
if (v.lat && v.lon && !(v.lat === 0 && v.lon === 0)) {
|
|
13
|
+
coordinates.push([v.lon, v.lat]);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
// Add booking pickup locations
|
|
17
|
+
bookings.forEach(b => {
|
|
18
|
+
if (b.pickup_location_lat && b.pickup_location_lon) {
|
|
19
|
+
coordinates.push([b.pickup_location_lon, b.pickup_location_lat]);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// If no valid coordinates, return null
|
|
23
|
+
if (coordinates.length === 0) {
|
|
24
|
+
return { center: null, zoom: 13 };
|
|
25
|
+
}
|
|
26
|
+
// Calculate center (average of all coordinates)
|
|
27
|
+
const avgLon = coordinates.reduce((sum, c) => sum + c[0], 0) / coordinates.length;
|
|
28
|
+
const avgLat = coordinates.reduce((sum, c) => sum + c[1], 0) / coordinates.length;
|
|
29
|
+
// Calculate zoom level based on coordinate spread
|
|
30
|
+
// Get min/max for longitude and latitude
|
|
31
|
+
const lons = coordinates.map(c => c[0]);
|
|
32
|
+
const lats = coordinates.map(c => c[1]);
|
|
33
|
+
const lonSpread = Math.max(...lons) - Math.min(...lons);
|
|
34
|
+
const latSpread = Math.max(...lats) - Math.min(...lats);
|
|
35
|
+
const maxSpread = Math.max(lonSpread, latSpread);
|
|
36
|
+
// Calculate appropriate zoom level
|
|
37
|
+
// Rough approximation: zoom levels decrease as spread increases
|
|
38
|
+
let zoom = 13; // default
|
|
39
|
+
if (maxSpread > 1) {
|
|
40
|
+
zoom = 10;
|
|
41
|
+
}
|
|
42
|
+
else if (maxSpread > 0.5) {
|
|
43
|
+
zoom = 11;
|
|
44
|
+
}
|
|
45
|
+
else if (maxSpread > 0.2) {
|
|
46
|
+
zoom = 12;
|
|
47
|
+
}
|
|
48
|
+
else if (maxSpread > 0.05) {
|
|
49
|
+
zoom = 13;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
zoom = 14;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
center: [avgLon, avgLat],
|
|
56
|
+
zoom
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Optimistic update utilities for simulation data
|
|
3
4
|
* Apply client-side updates based on API responses before refetching
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.processUnassignResponse = processUnassignResponse;
|
|
8
|
+
const booking_1 = require("../types/simulation/booking");
|
|
9
|
+
const referenceUtils_1 = require("./referenceUtils");
|
|
7
10
|
/**
|
|
8
11
|
* Process unassign response and update nodes/bookings optimistically
|
|
9
12
|
* Applies all necessary transformations in the correct sequence
|
|
@@ -14,7 +17,7 @@ import { attachReferences } from './referenceUtils';
|
|
|
14
17
|
* @param response - API response containing changed UIDs
|
|
15
18
|
* @returns Updated nodes and bookings with references attached
|
|
16
19
|
*/
|
|
17
|
-
|
|
20
|
+
function processUnassignResponse(nodes, bookings, vehicles, response) {
|
|
18
21
|
const changedNodeUids = new Set(response.changed_nodes_uids || []);
|
|
19
22
|
const changedBookingUids = new Set(response.changed_bookings_uids || []);
|
|
20
23
|
// Step 1: Update nodes - set status to 'new', clear assigned_vehicle_id and scheduled_ts
|
|
@@ -27,11 +30,11 @@ export function processUnassignResponse(nodes, bookings, vehicles, response) {
|
|
|
27
30
|
// Step 2: Update bookings - set state to 'prepared'
|
|
28
31
|
const updatedBookings = bookings.map(booking => {
|
|
29
32
|
if (changedBookingUids.has(booking.uid)) {
|
|
30
|
-
return Object.assign(Object.assign({}, booking), { state: BookingState.PREPARED });
|
|
33
|
+
return Object.assign(Object.assign({}, booking), { state: booking_1.BookingState.PREPARED });
|
|
31
34
|
}
|
|
32
35
|
return booking;
|
|
33
36
|
});
|
|
34
37
|
// Step 3: Re-attach references between models
|
|
35
|
-
attachReferences(updatedBookings, vehicles, updatedNodes);
|
|
38
|
+
(0, referenceUtils_1.attachReferences)(updatedBookings, vehicles, updatedNodes);
|
|
36
39
|
return { updatedNodes, updatedBookings };
|
|
37
40
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createIndexMaps = createIndexMaps;
|
|
4
|
+
exports.attachReferences = attachReferences;
|
|
5
|
+
/**
|
|
6
|
+
* Create index maps for fast lookups
|
|
7
|
+
* Similar to dashviewer's stateIndex
|
|
8
|
+
*/
|
|
9
|
+
function createIndexMaps(bookings, vehicles, nodes) {
|
|
10
|
+
const bookingMap = new Map();
|
|
11
|
+
const vehicleMap = new Map();
|
|
12
|
+
const nodeMap = new Map();
|
|
13
|
+
bookings.forEach(booking => {
|
|
14
|
+
bookingMap.set(booking.id, booking);
|
|
15
|
+
});
|
|
16
|
+
vehicles.forEach(vehicle => {
|
|
17
|
+
vehicleMap.set(vehicle.id, vehicle);
|
|
18
|
+
});
|
|
19
|
+
nodes.forEach(node => {
|
|
20
|
+
nodeMap.set(node.id, node);
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
bookingMap,
|
|
24
|
+
vehicleMap,
|
|
25
|
+
nodeMap
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Attach references between models
|
|
30
|
+
* Adapted from dashviewer's attachReferences function
|
|
31
|
+
*/
|
|
32
|
+
function attachReferences(bookings, vehicles, nodes) {
|
|
33
|
+
const { bookingMap, vehicleMap, nodeMap } = createIndexMaps(bookings, vehicles, nodes);
|
|
34
|
+
// Sort nodes by scheduled_ts
|
|
35
|
+
const sortedNodes = [...nodes].sort((a, b) => {
|
|
36
|
+
if (!a.scheduled_ts || !b.scheduled_ts)
|
|
37
|
+
return 0;
|
|
38
|
+
return new Date(a.scheduled_ts).getTime() - new Date(b.scheduled_ts).getTime();
|
|
39
|
+
});
|
|
40
|
+
// Initialize vehicle data structures
|
|
41
|
+
const vehicleData = new Map();
|
|
42
|
+
vehicles.forEach(vehicle => {
|
|
43
|
+
vehicleData.set(vehicle.id, {
|
|
44
|
+
assigned_nodes: [],
|
|
45
|
+
completed_nodes: [],
|
|
46
|
+
assigned_booking_uids: new Set(),
|
|
47
|
+
completed_booking_uids: new Set()
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
// Process each node and build relationships
|
|
51
|
+
sortedNodes.forEach(node => {
|
|
52
|
+
// Attach vehicle reference to node
|
|
53
|
+
if (node.assigned_vehicle_id) {
|
|
54
|
+
const vehicle = vehicleMap.get(node.assigned_vehicle_id);
|
|
55
|
+
if (vehicle) {
|
|
56
|
+
const vData = vehicleData.get(vehicle.id);
|
|
57
|
+
if (vData) {
|
|
58
|
+
if (node.status === 'assigned') {
|
|
59
|
+
vData.assigned_nodes.push(node);
|
|
60
|
+
if (node.booking_uid) {
|
|
61
|
+
vData.assigned_booking_uids.add(node.booking_uid);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (node.status === 'completed') {
|
|
65
|
+
vData.completed_nodes.push(node);
|
|
66
|
+
if (node.booking_uid) {
|
|
67
|
+
vData.completed_booking_uids.add(node.booking_uid);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Attach booking reference to node
|
|
74
|
+
if (node.booking_id) {
|
|
75
|
+
const booking = bookingMap.get(node.booking_id);
|
|
76
|
+
if (booking) {
|
|
77
|
+
// Update booking with node information
|
|
78
|
+
if (node.node_type === 'pickup' && node.scheduled_ts) {
|
|
79
|
+
booking.pickup_scheduled_ts = node.scheduled_ts;
|
|
80
|
+
booking.planned_pickup_time = node.scheduled_ts;
|
|
81
|
+
if (!booking.pickup_location_name) {
|
|
82
|
+
booking.pickup_location_name = node.display_name || node.location_name || '';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (node.node_type === 'dropoff' && node.scheduled_ts) {
|
|
86
|
+
booking.dropoff_scheduled_ts = node.scheduled_ts;
|
|
87
|
+
booking.planned_dropoff_time = node.scheduled_ts;
|
|
88
|
+
if (!booking.dropoff_location_name) {
|
|
89
|
+
booking.dropoff_location_name = node.display_name || node.location_name || '';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Attach vehicle to booking
|
|
93
|
+
if (node.assigned_vehicle_id) {
|
|
94
|
+
const vehicle = vehicleMap.get(node.assigned_vehicle_id);
|
|
95
|
+
if (vehicle) {
|
|
96
|
+
booking.vehicle_id = node.assigned_vehicle_id;
|
|
97
|
+
booking.service_number = vehicle.service_number;
|
|
98
|
+
// Note: Driver names will be attached separately later
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
bookingMap,
|
|
106
|
+
vehicleMap,
|
|
107
|
+
nodeMap,
|
|
108
|
+
vehicleData
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateVehicleRoute = calculateVehicleRoute;
|
|
4
|
+
exports.hasRouteChanged = hasRouteChanged;
|
|
5
|
+
const routing_1 = require("@/sgerplib/sgerp/routing");
|
|
6
|
+
/**
|
|
7
|
+
* Calculate OSRM route for a vehicle based on its assigned nodes
|
|
8
|
+
*/
|
|
9
|
+
async function calculateVehicleRoute(vehicle, sortedNodes, defaultBackend) {
|
|
10
|
+
if (sortedNodes.length < 2) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const coordinates = sortedNodes.map(node => [node.lat, node.lon]);
|
|
14
|
+
// Get routing engine settings from vehicle
|
|
15
|
+
const settings = vehicle.routing_engine_settings || {};
|
|
16
|
+
const routingEngineName = settings.routing_engine_name || 'osrm';
|
|
17
|
+
const url = settings.url || 'http://mapbox-osrm-proxy';
|
|
18
|
+
const roadNetwork = settings.road_network || 'van';
|
|
19
|
+
const key = settings.key || 'dmVyeSBzZWNyZXQga2V5';
|
|
20
|
+
const curb = settings.curb !== undefined ? settings.curb : false;
|
|
21
|
+
// Create routing engine
|
|
22
|
+
const routingEngine = new routing_1.RoutingEngine(routingEngineName, url, roadNetwork, key, defaultBackend);
|
|
23
|
+
// Calculate route
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
routingEngine.route(coordinates, curb, (result, status, message) => {
|
|
26
|
+
if (status === 'ok' && (result === null || result === void 0 ? void 0 : result.osrmRoute)) {
|
|
27
|
+
resolve(result.osrmRoute);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.error(`Failed to calculate route for vehicle ${vehicle.id}:`, message);
|
|
31
|
+
resolve(null);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if a vehicle's route has changed by comparing node IDs
|
|
38
|
+
*/
|
|
39
|
+
function hasRouteChanged(existingNodes, newNodes) {
|
|
40
|
+
const existingNodeIds = (existingNodes === null || existingNodes === void 0 ? void 0 : existingNodes.map(n => n.id).join(',')) || '';
|
|
41
|
+
const newNodeIds = newNodes.map(n => n.id).join(',');
|
|
42
|
+
return existingNodeIds !== newNodeIds;
|
|
43
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shiftNodeTimestamps = shiftNodeTimestamps;
|
|
4
|
+
exports.shiftWaypointTimestamps = shiftWaypointTimestamps;
|
|
5
|
+
/**
|
|
6
|
+
* Calculate time difference in milliseconds between two timestamps
|
|
7
|
+
*/
|
|
8
|
+
function getTimeDiffMs(oldTime, newTime) {
|
|
9
|
+
return new Date(newTime).getTime() - new Date(oldTime).getTime();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Shift a timestamp by a given number of milliseconds
|
|
13
|
+
*/
|
|
14
|
+
function shiftTimestamp(timestamp, diffMs) {
|
|
15
|
+
if (!timestamp)
|
|
16
|
+
return null;
|
|
17
|
+
const date = new Date(timestamp);
|
|
18
|
+
const newDate = new Date(date.getTime() + diffMs);
|
|
19
|
+
return newDate.toISOString();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Shift all node scheduled timestamps by a time difference
|
|
23
|
+
* Note: open_time_ts and close_time_ts are NOT shifted as they represent
|
|
24
|
+
* fixed booking time window constraints, not planned arrival times
|
|
25
|
+
*
|
|
26
|
+
* @param nodes - Array of nodes to shift
|
|
27
|
+
* @param oldStartTime - Original start time (ISO string)
|
|
28
|
+
* @param newStartTime - New start time (ISO string)
|
|
29
|
+
* @returns New array of nodes with shifted scheduled_ts only
|
|
30
|
+
*/
|
|
31
|
+
function shiftNodeTimestamps(nodes, oldStartTime, newStartTime) {
|
|
32
|
+
const diffMs = getTimeDiffMs(oldStartTime, newStartTime);
|
|
33
|
+
if (diffMs === 0) {
|
|
34
|
+
// No change needed
|
|
35
|
+
return nodes;
|
|
36
|
+
}
|
|
37
|
+
return nodes.map(node => {
|
|
38
|
+
var _a;
|
|
39
|
+
return (Object.assign(Object.assign({}, node), { scheduled_ts: (_a = shiftTimestamp(node.scheduled_ts, diffMs)) !== null && _a !== void 0 ? _a : node.scheduled_ts }));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Shift waypoint node timestamps
|
|
44
|
+
* This is a helper for RouteDetailsTable waypoints structure
|
|
45
|
+
* Note: open_time_ts and close_time_ts are NOT shifted as they represent
|
|
46
|
+
* fixed booking time window constraints, not planned arrival times
|
|
47
|
+
*
|
|
48
|
+
* @param waypoints - Array of waypoints with nested nodes
|
|
49
|
+
* @param oldStartTime - Original start time (ISO string)
|
|
50
|
+
* @param newStartTime - New start time (ISO string)
|
|
51
|
+
* @returns New array of waypoints with shifted scheduled_ts only
|
|
52
|
+
*/
|
|
53
|
+
function shiftWaypointTimestamps(waypoints, oldStartTime, newStartTime) {
|
|
54
|
+
const diffMs = getTimeDiffMs(oldStartTime, newStartTime);
|
|
55
|
+
if (diffMs === 0) {
|
|
56
|
+
// No change needed
|
|
57
|
+
return waypoints;
|
|
58
|
+
}
|
|
59
|
+
return waypoints.map(waypoint => (Object.assign(Object.assign({}, waypoint), { nodes: waypoint.nodes.map(node => {
|
|
60
|
+
var _a;
|
|
61
|
+
return (Object.assign(Object.assign({}, node), { scheduled_ts: (_a = shiftTimestamp(node.scheduled_ts, diffMs)) !== null && _a !== void 0 ? _a : node.scheduled_ts }));
|
|
62
|
+
}) })));
|
|
63
|
+
}
|