@vulog/aima-booking 1.1.89 → 1.1.91
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 +294 -12
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
- package/src/getStation.test.ts +4 -4
- package/src/getStation.ts +1 -1
package/README.md
CHANGED
|
@@ -1,26 +1,308 @@
|
|
|
1
1
|
# @vulog/aima-booking
|
|
2
2
|
|
|
3
|
+
Booking management module for the AIMA platform. This module provides functionality to manage booking requests, stations, and subscription bookings.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
3
7
|
```bash
|
|
4
|
-
npm
|
|
8
|
+
npm install @vulog/aima-client @vulog/aima-core @vulog/aima-booking
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Initialize Client
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { getClient } from '@vulog/aima-client';
|
|
17
|
+
import {
|
|
18
|
+
getBookingRequests,
|
|
19
|
+
getScheduleBookingRequests,
|
|
20
|
+
getSubscriptionBookingRequests,
|
|
21
|
+
getSATBookingRequests,
|
|
22
|
+
getBookingRequestById,
|
|
23
|
+
getBookingRequestByTrip,
|
|
24
|
+
getSubscriptionBookingRequestById,
|
|
25
|
+
getStations,
|
|
26
|
+
getStationById
|
|
27
|
+
} from '@vulog/aima-booking';
|
|
28
|
+
|
|
29
|
+
const client = getClient({
|
|
30
|
+
apiKey: 'your-api-key',
|
|
31
|
+
baseUrl: 'https://your-api-base-url',
|
|
32
|
+
clientId: 'your-client-id',
|
|
33
|
+
clientSecret: 'your-client-secret',
|
|
34
|
+
fleetId: 'your-fleet-id',
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API Reference
|
|
39
|
+
|
|
40
|
+
### Booking Requests
|
|
41
|
+
|
|
42
|
+
#### getBookingRequests
|
|
43
|
+
|
|
44
|
+
Retrieve booking requests with optional filtering.
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
const bookingRequests = await getBookingRequests(client, 'ONGOING', {
|
|
48
|
+
limit: 50,
|
|
49
|
+
offset: 0,
|
|
50
|
+
userId: 'user-uuid-here'
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Parameters:**
|
|
55
|
+
- `client`: AIMA client instance
|
|
56
|
+
- `status`: Booking request status ('ONGOING', 'COMPLETED', 'CANCELLED', 'EXPIRED')
|
|
57
|
+
- `filters`: Optional filter object
|
|
58
|
+
- `limit`: Maximum number of results
|
|
59
|
+
- `offset`: Number of results to skip
|
|
60
|
+
- `userId`: Filter by user ID
|
|
61
|
+
- `vehicleId`: Filter by vehicle ID
|
|
62
|
+
- `stationId`: Filter by station ID
|
|
63
|
+
|
|
64
|
+
#### getScheduleBookingRequests
|
|
65
|
+
|
|
66
|
+
Get scheduled booking requests.
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
const scheduledRequests = await getScheduleBookingRequests(client, {
|
|
70
|
+
startDate: '2024-01-01T00:00:00Z',
|
|
71
|
+
endDate: '2024-01-31T23:59:59Z'
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### getSubscriptionBookingRequests
|
|
76
|
+
|
|
77
|
+
Get subscription-based booking requests.
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
const subscriptionRequests = await getSubscriptionBookingRequests(client, {
|
|
81
|
+
status: 'ACTIVE',
|
|
82
|
+
userId: 'user-uuid-here'
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### getSATBookingRequests
|
|
87
|
+
|
|
88
|
+
Get SAT (Scheduled Access Time) booking requests.
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
const satRequests = await getSATBookingRequests(client, 'PENDING');
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Individual Booking Requests
|
|
95
|
+
|
|
96
|
+
#### getBookingRequestById
|
|
97
|
+
|
|
98
|
+
Retrieve a specific booking request by ID.
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
const bookingRequest = await getBookingRequestById(client, 'bb493049-5b4f-43ea-8a65-964a13aec549');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### getBookingRequestByTrip
|
|
105
|
+
|
|
106
|
+
Get booking request associated with a trip.
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const bookingRequest = await getBookingRequestByTrip(client, '33E8E42710144E15A5CC447E4D3524F4');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### getSubscriptionBookingRequestById
|
|
113
|
+
|
|
114
|
+
Get subscription booking request by ID.
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const subscriptionRequest = await getSubscriptionBookingRequestById(client, 'b7faa2a2-e8fc-4a29-8de7-09ce783b9797');
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Stations
|
|
121
|
+
|
|
122
|
+
#### getStations
|
|
123
|
+
|
|
124
|
+
Retrieve stations with optional includes.
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
const stations = await getStations(client, ['OPEN_HOUR', 'INFO']);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Parameters:**
|
|
131
|
+
- `client`: AIMA client instance
|
|
132
|
+
- `includes`: Array of data to include ('OPEN_HOUR', 'INFO', 'VEHICLES', 'ZONES')
|
|
133
|
+
|
|
134
|
+
#### getStationById
|
|
135
|
+
|
|
136
|
+
Get a specific station by ID.
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
const station = await getStationById(client, 'station-id-here', ['OPEN_HOUR', 'INFO']);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Types
|
|
143
|
+
|
|
144
|
+
### BookingRequest
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
interface BookingRequest {
|
|
148
|
+
id: string;
|
|
149
|
+
userId: string;
|
|
150
|
+
vehicleId: string;
|
|
151
|
+
stationId: string;
|
|
152
|
+
status: 'PENDING' | 'ONGOING' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED';
|
|
153
|
+
startTime: string;
|
|
154
|
+
endTime: string;
|
|
155
|
+
createdAt: string;
|
|
156
|
+
updatedAt: string;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Station
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
interface Station {
|
|
164
|
+
id: string;
|
|
165
|
+
name: string;
|
|
166
|
+
address: string;
|
|
167
|
+
coordinates: {
|
|
168
|
+
latitude: number;
|
|
169
|
+
longitude: number;
|
|
170
|
+
};
|
|
171
|
+
isActive: boolean;
|
|
172
|
+
openHours: OpenHours[];
|
|
173
|
+
info: StationInfo;
|
|
174
|
+
vehicles: Vehicle[];
|
|
175
|
+
zones: Zone[];
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### BookingRequestStatus
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
type BookingRequestStatus = 'PENDING' | 'ONGOING' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED';
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### ServiceType
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
type ServiceType = 'CAR_SHARING' | 'BIKE_SHARING' | 'SCOOTER_SHARING' | 'MULTIMODAL';
|
|
5
189
|
```
|
|
6
190
|
|
|
191
|
+
## Error Handling
|
|
192
|
+
|
|
193
|
+
All functions include validation and will throw appropriate errors if:
|
|
194
|
+
- Required parameters are missing
|
|
195
|
+
- Invalid booking request or station IDs are provided
|
|
196
|
+
- Invalid status values are used
|
|
197
|
+
- Network errors occur
|
|
198
|
+
|
|
199
|
+
## Examples
|
|
200
|
+
|
|
201
|
+
### Complete Booking Management Workflow
|
|
202
|
+
|
|
7
203
|
```javascript
|
|
8
204
|
import { getClient } from '@vulog/aima-client';
|
|
9
|
-
import {
|
|
205
|
+
import {
|
|
206
|
+
getBookingRequests,
|
|
207
|
+
getStations,
|
|
208
|
+
getBookingRequestById
|
|
209
|
+
} from '@vulog/aima-booking';
|
|
10
210
|
|
|
11
211
|
const client = getClient({
|
|
12
|
-
apiKey: '
|
|
13
|
-
baseUrl: '
|
|
14
|
-
clientId: '
|
|
15
|
-
clientSecret: '
|
|
16
|
-
fleetId: '
|
|
212
|
+
apiKey: 'your-api-key',
|
|
213
|
+
baseUrl: 'https://your-api-base-url',
|
|
214
|
+
clientId: 'your-client-id',
|
|
215
|
+
clientSecret: 'your-client-secret',
|
|
216
|
+
fleetId: 'your-fleet-id',
|
|
17
217
|
});
|
|
18
218
|
|
|
19
|
-
|
|
219
|
+
async function bookingWorkflow() {
|
|
220
|
+
try {
|
|
221
|
+
// Get all ongoing booking requests
|
|
222
|
+
const ongoingRequests = await getBookingRequests(client, 'ONGOING');
|
|
223
|
+
console.log(`Found ${ongoingRequests.length} ongoing booking requests`);
|
|
224
|
+
|
|
225
|
+
// Get stations with full information
|
|
226
|
+
const stations = await getStations(client, ['OPEN_HOUR', 'INFO', 'VEHICLES']);
|
|
227
|
+
console.log(`Found ${stations.length} stations`);
|
|
228
|
+
|
|
229
|
+
// Get specific booking request
|
|
230
|
+
const bookingRequest = await getBookingRequestById(client, 'bb493049-5b4f-43ea-8a65-964a13aec549');
|
|
231
|
+
console.log('Booking request details:', bookingRequest);
|
|
232
|
+
|
|
233
|
+
return { ongoingRequests, stations, bookingRequest };
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error('Booking workflow error:', error);
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
20
240
|
|
|
21
|
-
|
|
241
|
+
### Station Analysis
|
|
22
242
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
243
|
+
```javascript
|
|
244
|
+
async function analyzeStations(client) {
|
|
245
|
+
try {
|
|
246
|
+
const stations = await getStations(client, ['OPEN_HOUR', 'INFO', 'VEHICLES']);
|
|
247
|
+
|
|
248
|
+
const analysis = {
|
|
249
|
+
totalStations: stations.length,
|
|
250
|
+
activeStations: stations.filter(s => s.isActive).length,
|
|
251
|
+
stationsWithVehicles: stations.filter(s => s.vehicles && s.vehicles.length > 0).length,
|
|
252
|
+
averageVehiclesPerStation: stations.reduce((sum, s) => sum + (s.vehicles?.length || 0), 0) / stations.length,
|
|
253
|
+
stationsByZone: stations.reduce((acc, station) => {
|
|
254
|
+
station.zones?.forEach(zone => {
|
|
255
|
+
acc[zone.name] = (acc[zone.name] || 0) + 1;
|
|
256
|
+
});
|
|
257
|
+
return acc;
|
|
258
|
+
}, {})
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
console.log('Station Analysis:');
|
|
262
|
+
console.log(`Total Stations: ${analysis.totalStations}`);
|
|
263
|
+
console.log(`Active Stations: ${analysis.activeStations}`);
|
|
264
|
+
console.log(`Stations with Vehicles: ${analysis.stationsWithVehicles}`);
|
|
265
|
+
console.log(`Average Vehicles per Station: ${analysis.averageVehiclesPerStation.toFixed(2)}`);
|
|
266
|
+
console.log('Stations by Zone:', analysis.stationsByZone);
|
|
267
|
+
|
|
268
|
+
return analysis;
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error('Station analysis error:', error);
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Booking Request Monitoring
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
async function monitorBookingRequests(client) {
|
|
280
|
+
try {
|
|
281
|
+
const [ongoing, completed, cancelled] = await Promise.all([
|
|
282
|
+
getBookingRequests(client, 'ONGOING'),
|
|
283
|
+
getBookingRequests(client, 'COMPLETED'),
|
|
284
|
+
getBookingRequests(client, 'CANCELLED')
|
|
285
|
+
]);
|
|
286
|
+
|
|
287
|
+
const monitoring = {
|
|
288
|
+
ongoing: ongoing.length,
|
|
289
|
+
completed: completed.length,
|
|
290
|
+
cancelled: cancelled.length,
|
|
291
|
+
total: ongoing.length + completed.length + cancelled.length,
|
|
292
|
+
completionRate: completed.length / (completed.length + cancelled.length) * 100
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
console.log('Booking Request Monitoring:');
|
|
296
|
+
console.log(`Ongoing: ${monitoring.ongoing}`);
|
|
297
|
+
console.log(`Completed: ${monitoring.completed}`);
|
|
298
|
+
console.log(`Cancelled: ${monitoring.cancelled}`);
|
|
299
|
+
console.log(`Total: ${monitoring.total}`);
|
|
300
|
+
console.log(`Completion Rate: ${monitoring.completionRate.toFixed(2)}%`);
|
|
301
|
+
|
|
302
|
+
return monitoring;
|
|
303
|
+
} catch (error) {
|
|
304
|
+
console.error('Booking monitoring error:', error);
|
|
305
|
+
throw error;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
26
308
|
```
|
package/dist/index.js
CHANGED
|
@@ -358,7 +358,7 @@ var getStationById = async (client, id, includes = []) => {
|
|
|
358
358
|
});
|
|
359
359
|
if (station && includes.includes("INFO")) {
|
|
360
360
|
const poi = await client.get(
|
|
361
|
-
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/
|
|
361
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
|
|
362
362
|
{
|
|
363
363
|
headers: { accept: "application/vnd.geo+json" }
|
|
364
364
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -324,7 +324,7 @@ var getStationById = async (client, id, includes = []) => {
|
|
|
324
324
|
});
|
|
325
325
|
if (station && includes.includes("INFO")) {
|
|
326
326
|
const poi = await client.get(
|
|
327
|
-
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/
|
|
327
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
|
|
328
328
|
{
|
|
329
329
|
headers: { accept: "application/vnd.geo+json" }
|
|
330
330
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vulog/aima-booking",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.91",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"author": "Vulog",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@vulog/aima-client": "1.1.
|
|
23
|
-
"@vulog/aima-core": "1.1.
|
|
22
|
+
"@vulog/aima-client": "1.1.91",
|
|
23
|
+
"@vulog/aima-core": "1.1.91"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"es-toolkit": "^1.39.9",
|
package/src/getStation.test.ts
CHANGED
|
@@ -227,7 +227,7 @@ describe('getStationById', () => {
|
|
|
227
227
|
config: {}
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
-
if (url === `/boapi/proxy/geoloc/fleets/${FLEET_ID}/
|
|
230
|
+
if (url === `/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}` ) {
|
|
231
231
|
return Promise.resolve({
|
|
232
232
|
data: {
|
|
233
233
|
type: 'FeatureCollection',
|
|
@@ -262,7 +262,7 @@ describe('getStationById', () => {
|
|
|
262
262
|
config: {}
|
|
263
263
|
});
|
|
264
264
|
}
|
|
265
|
-
if (url.startsWith(`/boapi/proxy/geoloc/fleets/${FLEET_ID}/
|
|
265
|
+
if (url.startsWith(`/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/`)) {
|
|
266
266
|
return Promise.resolve({
|
|
267
267
|
data: {
|
|
268
268
|
type: 'FeatureCollection',
|
|
@@ -369,7 +369,7 @@ describe('getStationById', () => {
|
|
|
369
369
|
expect(getMock).toBeCalledTimes(2);
|
|
370
370
|
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
|
|
371
371
|
expect(getMock).toBeCalledWith(
|
|
372
|
-
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/
|
|
372
|
+
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}`,
|
|
373
373
|
{ headers: { accept: 'application/vnd.geo+json' } }
|
|
374
374
|
);
|
|
375
375
|
expectStation(station, STATION);
|
|
@@ -400,7 +400,7 @@ describe('getStationById', () => {
|
|
|
400
400
|
expect(getMock).toBeCalledTimes(3);
|
|
401
401
|
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
|
|
402
402
|
expect(getMock).toBeCalledWith(
|
|
403
|
-
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/
|
|
403
|
+
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}`,
|
|
404
404
|
{ headers: { accept: 'application/vnd.geo+json' } }
|
|
405
405
|
);
|
|
406
406
|
expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/stations/details?showTimetable=false`);
|
package/src/getStation.ts
CHANGED
|
@@ -66,7 +66,7 @@ export const getStationById = async (
|
|
|
66
66
|
if (station && includes.includes('INFO')) {
|
|
67
67
|
const poi = await client
|
|
68
68
|
.get<{ features: any[] }>(
|
|
69
|
-
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/
|
|
69
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
|
|
70
70
|
{
|
|
71
71
|
headers: { accept: 'application/vnd.geo+json' },
|
|
72
72
|
}
|