fleetmap-reports 1.0.264 → 1.0.268
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/.idea/workspace.xml +54 -7
- package/package.json +1 -1
- package/src/activity-report.js +8 -11
- package/src/kms-report.js +11 -17
- package/src/speeding-report.js +190 -194
- package/src/trip-report.js +55 -99
- package/src/util/driver.js +2 -3
- package/src/util/traccar.js +3 -3
- package/src/util/trips.js +53 -0
package/.idea/workspace.xml
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<project version="4">
|
|
3
3
|
<component name="ChangeListManager">
|
|
4
|
-
<list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="
|
|
4
|
+
<list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="fix trip report">
|
|
5
5
|
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
|
|
6
6
|
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
7
|
-
<change beforePath="$PROJECT_DIR$/src/activity-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/activity-report.js" afterDir="false" />
|
|
8
7
|
<change beforePath="$PROJECT_DIR$/src/index.test.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.test.js" afterDir="false" />
|
|
9
|
-
<change beforePath="$PROJECT_DIR$/src/
|
|
10
|
-
<change beforePath="$PROJECT_DIR$/src/trip-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/trip-report.js" afterDir="false" />
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/src/speeding-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/speeding-report.js" afterDir="false" />
|
|
11
9
|
</list>
|
|
12
10
|
<option name="SHOW_DIALOG" value="false" />
|
|
13
11
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -222,7 +220,13 @@
|
|
|
222
220
|
<workItem from="1640866782794" duration="123000" />
|
|
223
221
|
<workItem from="1640866964393" duration="1022000" />
|
|
224
222
|
<workItem from="1640870147277" duration="8236000" />
|
|
225
|
-
<workItem from="1641321068227" duration="
|
|
223
|
+
<workItem from="1641321068227" duration="14805000" />
|
|
224
|
+
<workItem from="1641387675790" duration="32947000" />
|
|
225
|
+
<workItem from="1641509412324" duration="41000" />
|
|
226
|
+
<workItem from="1641510744190" duration="1404000" />
|
|
227
|
+
<workItem from="1641526151665" duration="1679000" />
|
|
228
|
+
<workItem from="1641640203903" duration="5320000" />
|
|
229
|
+
<workItem from="1641740608739" duration="552000" />
|
|
226
230
|
</task>
|
|
227
231
|
<task id="LOCAL-00001" summary="Fix getStyle">
|
|
228
232
|
<created>1636983717385</created>
|
|
@@ -371,12 +375,51 @@
|
|
|
371
375
|
<option name="project" value="LOCAL" />
|
|
372
376
|
<updated>1640878664617</updated>
|
|
373
377
|
</task>
|
|
374
|
-
<
|
|
378
|
+
<task id="LOCAL-00022" summary="fix kms-report by driver and fix activity report with time period">
|
|
379
|
+
<created>1641348028566</created>
|
|
380
|
+
<option name="number" value="00022" />
|
|
381
|
+
<option name="presentableId" value="LOCAL-00022" />
|
|
382
|
+
<option name="project" value="LOCAL" />
|
|
383
|
+
<updated>1641348028566</updated>
|
|
384
|
+
</task>
|
|
385
|
+
<task id="LOCAL-00023" summary="Refactor trip and speeding reports">
|
|
386
|
+
<created>1641511586537</created>
|
|
387
|
+
<option name="number" value="00023" />
|
|
388
|
+
<option name="presentableId" value="LOCAL-00023" />
|
|
389
|
+
<option name="project" value="LOCAL" />
|
|
390
|
+
<updated>1641511586537</updated>
|
|
391
|
+
</task>
|
|
392
|
+
<task id="LOCAL-00024" summary="check if weekDays parameter is set">
|
|
393
|
+
<created>1641527800168</created>
|
|
394
|
+
<option name="number" value="00024" />
|
|
395
|
+
<option name="presentableId" value="LOCAL-00024" />
|
|
396
|
+
<option name="project" value="LOCAL" />
|
|
397
|
+
<updated>1641527800170</updated>
|
|
398
|
+
</task>
|
|
399
|
+
<task id="LOCAL-00025" summary="fix trip report">
|
|
400
|
+
<created>1641664506677</created>
|
|
401
|
+
<option name="number" value="00025" />
|
|
402
|
+
<option name="presentableId" value="LOCAL-00025" />
|
|
403
|
+
<option name="project" value="LOCAL" />
|
|
404
|
+
<updated>1641664506679</updated>
|
|
405
|
+
</task>
|
|
406
|
+
<option name="localTasksCounter" value="26" />
|
|
375
407
|
<servers />
|
|
376
408
|
</component>
|
|
377
409
|
<component name="TypeScriptGeneratedFilesManager">
|
|
378
410
|
<option name="version" value="3" />
|
|
379
411
|
</component>
|
|
412
|
+
<component name="Vcs.Log.History.Properties">
|
|
413
|
+
<option name="COLUMN_ID_ORDER">
|
|
414
|
+
<list>
|
|
415
|
+
<option value="Default.Root" />
|
|
416
|
+
<option value="Default.Author" />
|
|
417
|
+
<option value="Default.Date" />
|
|
418
|
+
<option value="Default.Subject" />
|
|
419
|
+
<option value="Space.CommitStatus" />
|
|
420
|
+
</list>
|
|
421
|
+
</option>
|
|
422
|
+
</component>
|
|
380
423
|
<component name="Vcs.Log.Tabs.Properties">
|
|
381
424
|
<option name="TAB_STATES">
|
|
382
425
|
<map>
|
|
@@ -410,6 +453,10 @@
|
|
|
410
453
|
<MESSAGE value="calculate avg speed" />
|
|
411
454
|
<MESSAGE value="fix activity report by driver" />
|
|
412
455
|
<MESSAGE value="activity report by driver grouped by day" />
|
|
413
|
-
<
|
|
456
|
+
<MESSAGE value="fix kms-report by driver and fix activity report with time period" />
|
|
457
|
+
<MESSAGE value="Refactor trip and speeding reports" />
|
|
458
|
+
<MESSAGE value="check if weekDays parameter is set" />
|
|
459
|
+
<MESSAGE value="fix trip report" />
|
|
460
|
+
<option name="LAST_COMMIT_MESSAGE" value="fix trip report" />
|
|
414
461
|
</component>
|
|
415
462
|
</project>
|
package/package.json
CHANGED
package/src/activity-report.js
CHANGED
|
@@ -94,7 +94,7 @@ async function createActivityReportByDevice(from, to){
|
|
|
94
94
|
if(userData.groupByDay) {
|
|
95
95
|
const dates = getDates(from, to)
|
|
96
96
|
for(const date of dates){
|
|
97
|
-
if(userData.allWeek){
|
|
97
|
+
if(userData.allWeek || !userData.weekDays){
|
|
98
98
|
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
99
99
|
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
100
100
|
|
|
@@ -160,11 +160,11 @@ async function createActivityReportByDevice(from, to){
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
async function createActivityReportByDriver(from, to){
|
|
163
|
-
const
|
|
164
|
-
|
|
163
|
+
const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
164
|
+
|
|
165
165
|
let tripsData = []
|
|
166
|
-
if(
|
|
167
|
-
tripsData = await traccar.getTrips(traccarInstance, from, to,
|
|
166
|
+
if(devices.length > 0) {
|
|
167
|
+
tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
const allData = {
|
|
@@ -187,9 +187,6 @@ function processDevices(devices, data, kmsReport) {
|
|
|
187
187
|
if (summary) {
|
|
188
188
|
summary.forEach(s => {
|
|
189
189
|
const deviceKms = kmsReport[0].devices.filter(r => r.device.id === d.id)
|
|
190
|
-
|
|
191
|
-
console.log(deviceKms)
|
|
192
|
-
|
|
193
190
|
s.convertedSpentFuel = automaticReports.calculateSpentFuel(s.spentFuel, d)
|
|
194
191
|
s.distance = deviceKms.length ? (userData.groupByDay ? deviceKms[0].days.find(d => d.date.getTime() === s.date.getTime()).kms : deviceKms[0].summary.distance) : 0
|
|
195
192
|
})
|
|
@@ -217,7 +214,7 @@ function processDrivers(from, to, drivers, data) {
|
|
|
217
214
|
if(userData.groupByDay) {
|
|
218
215
|
const dates = getDates(from, to)
|
|
219
216
|
for(const date of dates){
|
|
220
|
-
if(userData.allWeek){
|
|
217
|
+
if(userData.allWeek || !userData.weekDays){
|
|
221
218
|
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
222
219
|
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
223
220
|
|
|
@@ -412,7 +409,7 @@ function exportActivityReportToPDF_Vehicle_GroupByDay(doc, translations, reportD
|
|
|
412
409
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
|
|
413
410
|
doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
|
|
414
411
|
|
|
415
|
-
if (!userData.allWeek) {
|
|
412
|
+
if (!userData.allWeek && userData.weekDays) {
|
|
416
413
|
doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
|
|
417
414
|
+ (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
|
|
418
415
|
+ (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
|
|
@@ -539,7 +536,7 @@ function exportActivityReportToPDF_Driver_GroupByDay(doc, translations, reportDa
|
|
|
539
536
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
|
|
540
537
|
doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
|
|
541
538
|
|
|
542
|
-
if (!userData.allWeek) {
|
|
539
|
+
if (!userData.allWeek && userData.weekDays) {
|
|
543
540
|
doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
|
|
544
541
|
+ (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
|
|
545
542
|
+ (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
|
package/src/kms-report.js
CHANGED
|
@@ -27,7 +27,7 @@ async function createKmsReportByDevice(from, to) {
|
|
|
27
27
|
|
|
28
28
|
devicesToProcess.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
29
29
|
const route = userData.allWeek ? [] : await traccar.getRoute(traccarInstance, from, to, devicesToProcess)
|
|
30
|
-
const tripsData = await traccar.getTrips(traccarInstance, from, to, devicesToProcess
|
|
30
|
+
const tripsData = await traccar.getTrips(traccarInstance, from, to, devicesToProcess)
|
|
31
31
|
|
|
32
32
|
console.log('trips:' + tripsData.length)
|
|
33
33
|
|
|
@@ -40,22 +40,16 @@ async function createKmsReportByDevice(from, to) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
async function createKmsReportByDriver(from, to) {
|
|
43
|
-
const
|
|
44
|
-
console.log(
|
|
43
|
+
const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
44
|
+
console.log(devices.length)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
tripsData = response.data
|
|
46
|
+
if(!devices.length) {
|
|
47
|
+
//empty report
|
|
48
|
+
return { drivers: [] }
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
allData.drivers = processDrivers(from, to, userData.drivers, tripsData)
|
|
57
|
-
|
|
58
|
-
return allData
|
|
51
|
+
const tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
|
|
52
|
+
return { drivers: processDrivers(from, to, userData.drivers, tripsData) }
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
async function createKmsReportByGroup(from, to) {
|
|
@@ -75,7 +69,7 @@ function processDrivers(from, to, drivers, data) {
|
|
|
75
69
|
driverData.days = []
|
|
76
70
|
const dates = getDates(from, to)
|
|
77
71
|
for(const date of dates){
|
|
78
|
-
if(userData.allWeek){
|
|
72
|
+
if(userData.allWeek || !userData.weekDays){
|
|
79
73
|
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
80
74
|
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
81
75
|
|
|
@@ -159,7 +153,7 @@ function processDevices(from, to, devices, route, trips) {
|
|
|
159
153
|
kms: 0
|
|
160
154
|
}
|
|
161
155
|
|
|
162
|
-
if(userData.allWeek){
|
|
156
|
+
if(userData.allWeek || !userData.weekDays){
|
|
163
157
|
day.kms = dayTrips.reduce((a, b) => a + b.distance, 0) || 0
|
|
164
158
|
} else {
|
|
165
159
|
if((currentDate.getDay() === 0 && userData.weekDays.sunday) ||
|
|
@@ -308,7 +302,7 @@ async function exportKmsReportToPDF(userData, reportData) {
|
|
|
308
302
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
|
|
309
303
|
doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
|
|
310
304
|
|
|
311
|
-
if(!userData.allWeek) {
|
|
305
|
+
if(!userData.allWeek && userData.weekDays) {
|
|
312
306
|
doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
|
|
313
307
|
+ (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
|
|
314
308
|
+ (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
|
package/src/speeding-report.js
CHANGED
|
@@ -16,109 +16,135 @@ let traccarInstance
|
|
|
16
16
|
let userData
|
|
17
17
|
|
|
18
18
|
const fileName = 'SpeedingReport'
|
|
19
|
+
const eventTypes = ['deviceOverspeed']
|
|
19
20
|
|
|
20
21
|
async function createSpeedingReport(from, to, reportUserData, traccar) {
|
|
22
|
+
console.log('Create SpeedingReport')
|
|
21
23
|
traccarInstance = traccar
|
|
22
24
|
userData = reportUserData
|
|
23
|
-
console.log('createSpeedingReport', from, to, userData, traccar)
|
|
24
25
|
const reportData = []
|
|
25
26
|
|
|
26
|
-
if(userData.byDriver){
|
|
27
|
+
if (userData.byDriver) {
|
|
28
|
+
console.log("ByDriver")
|
|
27
29
|
const allData = await createSpeedingReportByDriver(from, to)
|
|
28
30
|
reportData.push(allData)
|
|
29
31
|
}
|
|
30
|
-
else if(userData.byGroup){
|
|
32
|
+
else if (userData.byGroup) {
|
|
31
33
|
console.log("ByGroup")
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
const allData = await createSpeedingReportByGroup(from, to)
|
|
35
|
+
reportData.push(...allData)
|
|
36
|
+
} else {
|
|
37
|
+
console.log("ByDevice")
|
|
38
|
+
const allData = await createSpeedingReportByDevice(from, to, userData.devices)
|
|
39
|
+
reportData.push(allData)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return reportData
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function createSpeedingReportByGroup(from, to){
|
|
46
|
+
const reportData = []
|
|
47
|
+
for (const g of userData.groups) {
|
|
48
|
+
const devices = userData.devices.filter(d => d.groupId === g.id)
|
|
49
|
+
console.log(g.name + ' devices:' + devices.length)
|
|
50
|
+
if(devices.length > 0) {
|
|
51
|
+
const groupData = {
|
|
52
|
+
devices: [],
|
|
53
|
+
group: g,
|
|
54
|
+
xpert: devices.filter(d => d.attributes.xpert).length > 0
|
|
55
|
+
}
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, devices)
|
|
57
|
+
const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
|
|
58
|
+
const routes = await traccar.getRoute(traccarInstance, from, to, devices)
|
|
45
59
|
|
|
46
|
-
|
|
60
|
+
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
62
|
+
if (events.length > 0) {
|
|
63
|
+
groupData.devices = await processDevices(from, to, devices, events, routes)
|
|
64
|
+
reportData.push(groupData)
|
|
52
65
|
}
|
|
53
66
|
}
|
|
54
|
-
|
|
55
|
-
const withoutGroupData = await createSpeedingReportByDevice(from, to)
|
|
56
|
-
reportData.push(withoutGroupData)
|
|
57
|
-
} else {
|
|
58
|
-
const allData = await createSpeedingReportByDevice(from, to)
|
|
59
|
-
reportData.push(allData)
|
|
60
67
|
}
|
|
61
68
|
|
|
69
|
+
const groupIds = userData.groups.map(g => g.id)
|
|
70
|
+
const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
|
|
71
|
+
|
|
72
|
+
const withoutGroupData = await createSpeedingReportByDevice(from, to, withoutGroupDevices)
|
|
73
|
+
reportData.push(withoutGroupData)
|
|
74
|
+
|
|
62
75
|
return reportData
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
async function createSpeedingReportByDevice(from, to) {
|
|
66
|
-
|
|
67
|
-
const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
|
|
68
|
-
|
|
69
|
-
withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
78
|
+
async function createSpeedingReportByDevice(from, to, devices) {
|
|
79
|
+
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
70
80
|
|
|
71
|
-
const
|
|
72
|
-
const events =
|
|
73
|
-
|
|
81
|
+
const routes = await traccar.getRoute(traccarInstance, from, to, devices)
|
|
82
|
+
const events = []
|
|
83
|
+
if(!userData.useVehicleSpeedLimit && userData.customSpeed){
|
|
84
|
+
events.push(...await getCustomSpeedLimitEvents(devices, routes))
|
|
85
|
+
} else {
|
|
86
|
+
events.push(...await traccar.getEvents(traccarInstance, from, to, devices, eventTypes))
|
|
87
|
+
}
|
|
74
88
|
|
|
75
|
-
|
|
89
|
+
if(userData.roadSpeedLimits){
|
|
90
|
+
events.push(...await getHereEvents(devices, routes))
|
|
91
|
+
}
|
|
76
92
|
|
|
77
|
-
if(events.length
|
|
78
|
-
|
|
79
|
-
|
|
93
|
+
if(!events.length) {
|
|
94
|
+
//empty report
|
|
95
|
+
return { devices: [] }
|
|
80
96
|
}
|
|
81
97
|
|
|
82
|
-
return
|
|
98
|
+
return {
|
|
99
|
+
devices: await processDevices(from, to, devices, events, routes),
|
|
100
|
+
xpert: devices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
|
|
101
|
+
}
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
async function createSpeedingReportByDriver(from, to) {
|
|
86
|
-
const
|
|
87
|
-
console.log('Devices with driver',
|
|
105
|
+
const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
106
|
+
console.log('Devices with driver',devices.length)
|
|
107
|
+
|
|
108
|
+
if(!devices.length) {
|
|
109
|
+
//empty report
|
|
110
|
+
return { drivers: [] }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const routes = await traccar.getRoute(traccarInstance, from, to, devices)
|
|
114
|
+
const events = []
|
|
115
|
+
if(!userData.useVehicleSpeedLimit && userData.customSpeed){
|
|
116
|
+
events.push(...await getCustomSpeedLimitEvents(devices, routes))
|
|
117
|
+
} else {
|
|
118
|
+
events.push(...await traccar.getEvents(traccarInstance, from, to, devices, eventTypes))
|
|
119
|
+
}
|
|
88
120
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const devices = userData.devices.filter(d => deviceIds.includes(d.id))
|
|
92
|
-
eventsData = await traccar.getEvents(traccarInstance, from, to, devices,['deviceOverspeed'])
|
|
121
|
+
if(userData.roadSpeedLimits){
|
|
122
|
+
events.push(...await getHereEvents(devices, routes))
|
|
93
123
|
}
|
|
94
124
|
|
|
95
|
-
|
|
96
|
-
|
|
125
|
+
if(!events.length) {
|
|
126
|
+
//empty report
|
|
127
|
+
return { drivers: [] }
|
|
97
128
|
}
|
|
98
|
-
console.log(eventsData.length)
|
|
99
129
|
|
|
100
|
-
await
|
|
101
|
-
allData.drivers = await processDrivers(from, to, eventsData)
|
|
102
|
-
console.log(allData.drivers.length)
|
|
103
|
-
return allData
|
|
130
|
+
return {drivers: await processDrivers(from, to, events, routes)}
|
|
104
131
|
}
|
|
105
132
|
|
|
106
|
-
async function processDrivers(from, to,
|
|
107
|
-
console.log(data)
|
|
133
|
+
async function processDrivers(from, to, events, routes) {
|
|
108
134
|
const driversResult = []
|
|
109
|
-
const alertsWithPosition = data.filter(a => a.position)
|
|
110
135
|
|
|
111
|
-
userData.
|
|
112
|
-
const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
|
|
113
|
-
|
|
114
|
-
if (alerts.length > 0) {
|
|
136
|
+
await findEventsPosition(from, to, userData.devices, events, routes)
|
|
115
137
|
|
|
138
|
+
userData.drivers.forEach(d => {
|
|
139
|
+
const driverEvents = events.filter(e => e.position && e.position.attributes.driverUniqueId === d.uniqueId)
|
|
140
|
+
if (driverEvents.length > 0) {
|
|
141
|
+
driverEvents.sort((a, b) => a.positionId - b.positionId)
|
|
116
142
|
driversResult.push({
|
|
117
143
|
driver: d,
|
|
118
144
|
from: from,
|
|
119
145
|
to: to,
|
|
120
|
-
alerts:
|
|
121
|
-
maxSpeed:
|
|
146
|
+
alerts: driverEvents,
|
|
147
|
+
maxSpeed: driverEvents.reduce((a, b) => {
|
|
122
148
|
return a > b.attributes.maxSpeed ? a : b.attributes.maxSpeed
|
|
123
149
|
}, 0),
|
|
124
150
|
})
|
|
@@ -130,117 +156,38 @@ async function processDrivers(from, to, data) {
|
|
|
130
156
|
|
|
131
157
|
async function processDevices(from, to, devices, events, routes) {
|
|
132
158
|
const devicesResult = []
|
|
159
|
+
await findEventsPosition(from, to, devices, events, routes)
|
|
133
160
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
to: to,
|
|
148
|
-
alerts: alertsWithPosition,
|
|
149
|
-
maxSpeed: alertsWithPosition.reduce((a, b) => {
|
|
150
|
-
return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
|
|
151
|
-
}, 0),
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
for (const d of devices) {
|
|
157
|
-
const positions = routes.filter(t => t.deviceId === d.id)
|
|
158
|
-
const maxSpeed = userData.customSpeed / 1.85200
|
|
159
|
-
|
|
160
|
-
const alerts = []
|
|
161
|
-
for(let pIndex = 0; pIndex < positions.length ; pIndex++){
|
|
162
|
-
const position = positions[pIndex]
|
|
163
|
-
if(position.speed > maxSpeed){
|
|
164
|
-
const alert = {
|
|
165
|
-
position: position,
|
|
166
|
-
attributes: {
|
|
167
|
-
speedLimit: maxSpeed,
|
|
168
|
-
speed: position.speed
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
pIndex = calculateEventData(positions, pIndex, alert)
|
|
173
|
-
|
|
174
|
-
alerts.push(alert)
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if(alerts.length > 0){
|
|
178
|
-
devicesResult.push({
|
|
179
|
-
device: d,
|
|
180
|
-
from: from,
|
|
181
|
-
to: to,
|
|
182
|
-
alerts: alerts,
|
|
183
|
-
maxSpeed: alerts.reduce((a, b) => {
|
|
184
|
-
return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
|
|
185
|
-
}, 0),
|
|
186
|
-
})
|
|
187
|
-
}
|
|
161
|
+
for (const d of devices) {
|
|
162
|
+
const deviceEvents = events.filter(e => e.deviceId === d.id && e.position)
|
|
163
|
+
if (deviceEvents.length > 0) {
|
|
164
|
+
deviceEvents.sort((a, b) => a.positionId - b.positionId)
|
|
165
|
+
devicesResult.push({
|
|
166
|
+
device: d,
|
|
167
|
+
from: from,
|
|
168
|
+
to: to,
|
|
169
|
+
alerts: deviceEvents,
|
|
170
|
+
maxSpeed: deviceEvents.reduce((a, b) => {
|
|
171
|
+
return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
|
|
172
|
+
}, 0),
|
|
173
|
+
})
|
|
188
174
|
}
|
|
189
175
|
}
|
|
190
176
|
|
|
191
177
|
return devicesResult
|
|
192
178
|
}
|
|
193
179
|
|
|
194
|
-
async function
|
|
195
|
-
|
|
196
|
-
const deviceIds = [...new Set(events.map(e => e.deviceId))]
|
|
197
|
-
const routeData = await traccar.getRoute(traccarInstance, from, to, deviceIds.map(id => { return { id: id } } ))
|
|
198
|
-
|
|
199
|
-
console.log(events)
|
|
200
|
-
|
|
180
|
+
async function findEventsPosition(from, to, devices, events, routes){
|
|
201
181
|
for (const d of devices) {
|
|
202
|
-
let
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const positions =
|
|
206
|
-
|
|
207
|
-
if (userData.roadSpeedLimits && positions.length) {
|
|
208
|
-
try {
|
|
209
|
-
const results = await here.routeMatch(positions)
|
|
210
|
-
const hereAlerts = results.map(r => {
|
|
211
|
-
const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
|
|
212
|
-
return {
|
|
213
|
-
...r,
|
|
214
|
-
roadSpeedLimit: r.speedLimit,
|
|
215
|
-
deviceId: d.id,
|
|
216
|
-
position,
|
|
217
|
-
positionId: position && position.id,
|
|
218
|
-
attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
|
|
219
|
-
}
|
|
220
|
-
})
|
|
221
|
-
console.log('hereAlerts', hereAlerts)
|
|
222
|
-
const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
|
|
223
|
-
if (idx === 1) {
|
|
224
|
-
return [cur]
|
|
225
|
-
}
|
|
226
|
-
if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
|
|
227
|
-
return acc.concat(cur)
|
|
228
|
-
}
|
|
229
|
-
return acc
|
|
230
|
-
})
|
|
231
|
-
events.push(...reduced)
|
|
232
|
-
alerts = events.filter(t => t.deviceId === d.id)
|
|
233
|
-
} catch (e) {
|
|
234
|
-
console.error(e)
|
|
235
|
-
}
|
|
236
|
-
}
|
|
182
|
+
let deviceEvents = events.filter(e => e.deviceId === d.id && e.positionId)
|
|
183
|
+
if (deviceEvents.length > 0) {
|
|
184
|
+
deviceEvents.sort((a,b) => a.positionId-b.positionId )
|
|
185
|
+
const positions = routes.filter(p => p.deviceId === d.id)
|
|
237
186
|
|
|
238
|
-
for (const a of
|
|
187
|
+
for (const a of deviceEvents) {
|
|
239
188
|
let pIndex = positions.findIndex(p => p.id === a.positionId)
|
|
240
189
|
if (pIndex > 0) {
|
|
241
|
-
a.position = positions[pIndex]
|
|
242
190
|
let geofence = null
|
|
243
|
-
|
|
244
191
|
if (a.geofenceId) {
|
|
245
192
|
geofence = userData.geofences.find(g => g.id === a.geofenceId)
|
|
246
193
|
if (geofence) {
|
|
@@ -248,44 +195,85 @@ async function getEventsPosition(from, to, devices, events){
|
|
|
248
195
|
}
|
|
249
196
|
}
|
|
250
197
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
let dist = 0
|
|
254
|
-
while (pIndex + 1 < positions.length) {
|
|
255
|
-
pIndex++
|
|
256
|
-
|
|
257
|
-
dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
|
|
258
|
-
point([positions[pIndex].longitude, positions[pIndex].latitude]))
|
|
259
|
-
endEventPosition = positions[pIndex]
|
|
260
|
-
if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
|
|
261
|
-
a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
|
|
262
|
-
a.attributes.maxSpeed = maxSpeed
|
|
263
|
-
a.distance = dist
|
|
264
|
-
break
|
|
265
|
-
} else {
|
|
266
|
-
if (maxSpeed < endEventPosition.speed) {
|
|
267
|
-
maxSpeed = endEventPosition.speed
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
198
|
+
a.position = positions[pIndex]
|
|
199
|
+
pIndex = calculateEventData(positions, pIndex, a, d, geofence)
|
|
271
200
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
201
|
+
positions.slice(pIndex)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
276
207
|
|
|
277
|
-
|
|
208
|
+
async function getCustomSpeedLimitEvents(devices, routes){
|
|
209
|
+
console.log('calculate custom speed limit events')
|
|
210
|
+
const events = []
|
|
211
|
+
const maxSpeed = userData.customSpeed / 1.85200
|
|
278
212
|
|
|
279
|
-
|
|
213
|
+
for (const d of devices) {
|
|
214
|
+
const positions = routes.filter(p => p.deviceId === d.id)
|
|
215
|
+
let eventIsActive = false
|
|
216
|
+
|
|
217
|
+
for (const position of positions) {
|
|
218
|
+
if(position.speed > maxSpeed && !eventIsActive){
|
|
219
|
+
const event = {
|
|
220
|
+
positionId: position && position.id,
|
|
221
|
+
deviceId: d.id,
|
|
222
|
+
attributes: {
|
|
223
|
+
speedLimit: maxSpeed,
|
|
224
|
+
speed: position.speed
|
|
225
|
+
}
|
|
280
226
|
}
|
|
227
|
+
events.push(event)
|
|
228
|
+
eventIsActive = true
|
|
229
|
+
} else if (position.speed <= maxSpeed) {
|
|
230
|
+
eventIsActive = false
|
|
281
231
|
}
|
|
282
232
|
}
|
|
283
233
|
}
|
|
234
|
+
|
|
235
|
+
return events
|
|
284
236
|
}
|
|
285
237
|
|
|
286
|
-
function
|
|
287
|
-
|
|
288
|
-
|
|
238
|
+
async function getHereEvents(devices, routes){
|
|
239
|
+
console.log('calculate here speed limit events')
|
|
240
|
+
const events = []
|
|
241
|
+
for (const d of devices) {
|
|
242
|
+
const positions = routes.filter(p => p.deviceId === d.id)
|
|
243
|
+
try {
|
|
244
|
+
const results = await here.routeMatch(positions)
|
|
245
|
+
const hereAlerts = results.map(r => {
|
|
246
|
+
const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
|
|
247
|
+
return {
|
|
248
|
+
...r,
|
|
249
|
+
roadSpeedLimit: r.speedLimit,
|
|
250
|
+
deviceId: d.id,
|
|
251
|
+
position,
|
|
252
|
+
positionId: position && position.id,
|
|
253
|
+
attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
console.log('hereAlerts', hereAlerts)
|
|
257
|
+
const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
|
|
258
|
+
if (idx === 1) {
|
|
259
|
+
return [cur]
|
|
260
|
+
}
|
|
261
|
+
if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
|
|
262
|
+
return acc.concat(cur)
|
|
263
|
+
}
|
|
264
|
+
return acc
|
|
265
|
+
})
|
|
266
|
+
events.push(...reduced)
|
|
267
|
+
} catch (e) {
|
|
268
|
+
//console.error(e)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return events
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function calculateEventData(positions, pIndex, alert, device, geofence){
|
|
275
|
+
let endEventPosition = alert.position
|
|
276
|
+
let maxSpeed = alert.position.speed
|
|
289
277
|
let dist = 0
|
|
290
278
|
while (pIndex + 1 < positions.length) {
|
|
291
279
|
pIndex++
|
|
@@ -293,10 +281,10 @@ function calculateEventData(positions, pIndex, a, geofence){
|
|
|
293
281
|
dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
|
|
294
282
|
point([positions[pIndex].longitude, positions[pIndex].latitude]))
|
|
295
283
|
endEventPosition = positions[pIndex]
|
|
296
|
-
if (endEventPosition.speed <=
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
284
|
+
if (endEventPosition.speed <= alert.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
|
|
285
|
+
alert.eventTime = new Date(endEventPosition.fixTime) - new Date(alert.position.fixTime)
|
|
286
|
+
alert.attributes.maxSpeed = maxSpeed
|
|
287
|
+
alert.distance = dist
|
|
300
288
|
break
|
|
301
289
|
} else {
|
|
302
290
|
if (maxSpeed < endEventPosition.speed) {
|
|
@@ -305,6 +293,14 @@ function calculateEventData(positions, pIndex, a, geofence){
|
|
|
305
293
|
}
|
|
306
294
|
}
|
|
307
295
|
|
|
296
|
+
|
|
297
|
+
if (alert.position.attributes.driverUniqueId) {
|
|
298
|
+
const driver = userData.drivers.find(d => d.uniqueId === alert.position.attributes.driverUniqueId)
|
|
299
|
+
alert.driver = driver && driver.name
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
alert.deviceName = device.name
|
|
303
|
+
|
|
308
304
|
return pIndex
|
|
309
305
|
}
|
|
310
306
|
|
|
@@ -367,7 +363,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
367
363
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
|
|
368
364
|
doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
|
|
369
365
|
if (d.alerts[0] && !userData.byDriver) {
|
|
370
|
-
doc.text(translations.report.speedLimit + ": " + (userData.useVehicleSpeedLimit ? Math.round(d.alerts[0].attributes.speedLimit * 1.85200) : userData.customSpeed) + ' Km/h', 20, space + 30)
|
|
366
|
+
doc.text(translations.report.speedLimit + ": " + ((userData.useVehicleSpeedLimit || !userData.customSpeed) ? Math.round(d.alerts[0].attributes.speedLimit * 1.85200) : userData.customSpeed) + ' Km/h', 20, space + 30)
|
|
371
367
|
}
|
|
372
368
|
d.alerts.map(a => {
|
|
373
369
|
const temp = [
|
package/src/trip-report.js
CHANGED
|
@@ -3,13 +3,13 @@ const messages = require('../lang')
|
|
|
3
3
|
const jsPDF = require('jspdf')
|
|
4
4
|
const {convertMS, convertToLocaleString, convertToLocaleDateString, convertToLocaleTimeString} = require("./util/utils")
|
|
5
5
|
require('jspdf-autotable')
|
|
6
|
-
const {coordsDistance} = require("./util/utils")
|
|
7
6
|
const drivers = require("./util/driver")
|
|
8
7
|
const {getUserPartner} = require("fleetmap-partners")
|
|
9
8
|
const {headerFromUser, addTable} = require("./util/pdfDocument")
|
|
10
9
|
const {getStyle} = require("./reportStyle")
|
|
11
10
|
const traccar = require("./util/traccar")
|
|
12
11
|
const trips = require("./util/trips");
|
|
12
|
+
const {isInsideTimetable, addNearestPOIs} = require("./util/trips");
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
let traccarInstance
|
|
@@ -23,26 +23,26 @@ async function createTripReport(from, to, reportUserData, traccar) {
|
|
|
23
23
|
traccarInstance = traccar
|
|
24
24
|
const reportData = []
|
|
25
25
|
|
|
26
|
-
if(userData.byDriver){
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (userData.byDriver) {
|
|
27
|
+
console.log("ByDriver")
|
|
28
|
+
const report = await createTripReportByDriver(from, to)
|
|
29
|
+
reportData.push(report)
|
|
29
30
|
}
|
|
30
|
-
else if(userData.byGroup){
|
|
31
|
+
else if (userData.byGroup) {
|
|
31
32
|
console.log("ByGroup")
|
|
32
33
|
const allData = await createTripReportByGroup(from, to)
|
|
33
34
|
reportData.push(...allData)
|
|
35
|
+
} else {
|
|
36
|
+
console.log("ByDevice")
|
|
37
|
+
const report = await createTripReportByDevice(from, to)
|
|
38
|
+
reportData.push(report)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
const groupIds = userData.groups.map(g => g.id)
|
|
37
|
-
const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
|
|
38
|
-
|
|
39
|
-
const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
|
|
40
|
-
reportData.push(allData)
|
|
41
|
-
|
|
42
41
|
return reportData
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
async function createTripReportByDevice(from, to
|
|
44
|
+
async function createTripReportByDevice(from, to) {
|
|
45
|
+
const devices = userData.devices
|
|
46
46
|
const allData = {
|
|
47
47
|
devices: [],
|
|
48
48
|
xpert: devices.filter(d => d.attributes.xpert).length > 0
|
|
@@ -51,7 +51,7 @@ async function createTripReportByDevice(from, to, devices) {
|
|
|
51
51
|
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
52
52
|
|
|
53
53
|
const devicesToSlice = devices.slice()
|
|
54
|
-
const data = await traccar.getTrips(traccarInstance, from, to, devicesToSlice
|
|
54
|
+
const data = await traccar.getTrips(traccarInstance, from, to, devicesToSlice)
|
|
55
55
|
const stopsData = await traccar.getStops(traccarInstance, from, to, devicesToSlice)
|
|
56
56
|
|
|
57
57
|
console.log('Trips:' + data.length)
|
|
@@ -77,90 +77,75 @@ async function createTripReportByGroup(from, to) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
const response = await traccarInstance.reports.reportsTripsGet(from, to, null, [g.id])
|
|
80
|
-
const
|
|
80
|
+
const tripsData = response.data
|
|
81
81
|
|
|
82
82
|
const stopsResponse = await traccarInstance.reports.reportsStopsGet(from, to, null, [g.id])
|
|
83
83
|
const stopsData = stopsResponse.data
|
|
84
84
|
|
|
85
85
|
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
86
86
|
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
groupData.devices = processDevices(from, to, devices, data, stopsData, userData)
|
|
87
|
+
if (tripsData.length > 0) {
|
|
88
|
+
console.log('Trips:' + tripsData.length)
|
|
89
|
+
groupData.devices = processDevices(from, to, devices, tripsData, stopsData, userData)
|
|
91
90
|
|
|
92
91
|
reportData.push(groupData)
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
}
|
|
95
|
+
|
|
96
|
+
const groupIds = userData.groups.map(g => g.id)
|
|
97
|
+
const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
|
|
98
|
+
|
|
99
|
+
const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
|
|
100
|
+
reportData.push(allData)
|
|
101
|
+
|
|
96
102
|
return reportData
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
async function createTripReportByDriver(from, to){
|
|
100
|
-
const
|
|
101
|
-
console.log(
|
|
106
|
+
const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
107
|
+
console.log(devices.length)
|
|
102
108
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
tripsData = response.data
|
|
109
|
+
if(!devices.length){
|
|
110
|
+
//Empty report
|
|
111
|
+
return { drivers:[] }
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
const
|
|
110
|
-
drivers: []
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
allData.drivers = processDrivers(from, to, userData.drivers, tripsData)
|
|
114
|
+
const tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
|
|
114
115
|
|
|
115
|
-
return
|
|
116
|
+
return { drivers: processDrivers(from, to, userData.drivers, tripsData)}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
function processDevices(from, to, devices, data, stopsData) {
|
|
119
120
|
const devicesResult = []
|
|
120
121
|
|
|
121
122
|
devices.forEach(d => {
|
|
122
|
-
const trips = data.filter(t => t.deviceId === d.id
|
|
123
|
+
const trips = data.filter(t => t.deviceId === d.id
|
|
124
|
+
&& (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
|
|
123
125
|
const stops = stopsData.filter(s => s.deviceId === d.id)
|
|
124
126
|
|
|
125
|
-
trips
|
|
126
|
-
|
|
127
|
+
addNearestPOIs(trips, userData)
|
|
128
|
+
|
|
129
|
+
trips.forEach(trip => {
|
|
127
130
|
if (automaticReports.deviceWithFuelInfo(d)) {
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
trip.fuelConsumption = Math.round((trip.spentFuel * d.attributes.fuel_tank_capacity) / 100)
|
|
132
|
+
trip.avgFuelConsumption = trip.totalKms > 0 ? Math.round(trip.fuelConsumption * 100 / trip.totalKms) : 0
|
|
130
133
|
} else {
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
trip.fuelConsumption = '-'
|
|
135
|
+
trip.avgFuelConsumption = '-'
|
|
133
136
|
}
|
|
134
137
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
|
|
146
|
-
if (nearestPOIs.length > 0) {
|
|
147
|
-
t.endPOIName = nearestPOIs[0].p.name
|
|
138
|
+
const stop = getStop(new Date(trip.startTime), stops)
|
|
139
|
+
if (stop) {
|
|
140
|
+
trip.stopDuration = (new Date(stop.endTime) - new Date(stop.startTime))
|
|
141
|
+
trip.stopEngineHours = stop.engineHours
|
|
142
|
+
} else {
|
|
143
|
+
trip.stopDuration = 0
|
|
144
|
+
trip.stopEngineHours = 0
|
|
148
145
|
}
|
|
149
146
|
})
|
|
150
147
|
|
|
151
148
|
if (trips.length > 0) {
|
|
152
|
-
trips.forEach(trip => {
|
|
153
|
-
const stop = getStop(new Date(trip.startTime), stops)
|
|
154
|
-
|
|
155
|
-
if (stop) {
|
|
156
|
-
trip.stopDuration = (new Date(stop.endTime) - new Date(stop.startTime))
|
|
157
|
-
trip.stopEngineHours = stop.engineHours
|
|
158
|
-
} else {
|
|
159
|
-
trip.stopDuration = 0
|
|
160
|
-
trip.stopEngineHours = 0
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
|
|
164
149
|
const deviceData = {
|
|
165
150
|
device: d,
|
|
166
151
|
from: from,
|
|
@@ -188,11 +173,12 @@ function processDrivers(from, to, drivers, data) {
|
|
|
188
173
|
console.log(data)
|
|
189
174
|
const driversResult = []
|
|
190
175
|
drivers.forEach(d => {
|
|
191
|
-
const trips = data.filter(t => t.driverUniqueId === d.uniqueId
|
|
176
|
+
const trips = data.filter(t => t.driverUniqueId === d.uniqueId
|
|
177
|
+
&& (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
|
|
192
178
|
|
|
193
|
-
trips.
|
|
194
|
-
|
|
195
|
-
|
|
179
|
+
trips.sort((a,b)=>new Date(a.startTime).getTime()-new Date(b.startTime).getTime())
|
|
180
|
+
|
|
181
|
+
addNearestPOIs(trips, userData)
|
|
196
182
|
|
|
197
183
|
if (trips.length > 0) {
|
|
198
184
|
const driverData = {
|
|
@@ -201,14 +187,13 @@ function processDrivers(from, to, drivers, data) {
|
|
|
201
187
|
to: to,
|
|
202
188
|
totalDuration: trips.reduce((a, b) => a + b.duration, 0),
|
|
203
189
|
totalDistance: trips.reduce((a, b) => a + b.distance, 0),
|
|
204
|
-
maxSpeed: trips.reduce((a, b) => {
|
|
205
|
-
return a > b.maxSpeed ? a : b.maxSpeed
|
|
206
|
-
}, 0),
|
|
190
|
+
maxSpeed: trips.reduce((a, b) => { return a > b.maxSpeed ? a : b.maxSpeed }, 0),
|
|
207
191
|
trips: trips,
|
|
208
192
|
}
|
|
209
193
|
driversResult.push(driverData)
|
|
210
194
|
}
|
|
211
195
|
})
|
|
196
|
+
console.log(driversResult)
|
|
212
197
|
|
|
213
198
|
return driversResult
|
|
214
199
|
}
|
|
@@ -262,7 +247,7 @@ async function exportTripReportToPDF(userData, reportData) {
|
|
|
262
247
|
doc.setFontSize(11)
|
|
263
248
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space+20 )
|
|
264
249
|
doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
|
|
265
|
-
if(!userData.allWeek) {
|
|
250
|
+
if(!userData.allWeek && userData.weekDays) {
|
|
266
251
|
doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
|
|
267
252
|
+ (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
|
|
268
253
|
+ (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
|
|
@@ -453,35 +438,6 @@ function getStop(tripEndDate, stops){
|
|
|
453
438
|
return null
|
|
454
439
|
}
|
|
455
440
|
|
|
456
|
-
function isInsideTimetable(t, userData){
|
|
457
|
-
const tripStart = new Date(t.startTime)
|
|
458
|
-
const tripEnd = new Date(t.endTime)
|
|
459
|
-
|
|
460
|
-
if((tripStart.getDay() === 0 && userData.weekDays.sunday) ||
|
|
461
|
-
(tripStart.getDay() === 1 && userData.weekDays.monday) ||
|
|
462
|
-
(tripStart.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
463
|
-
(tripStart.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
464
|
-
(tripStart.getDay() === 4 && userData.weekDays.thursday) ||
|
|
465
|
-
(tripStart.getDay() === 5 && userData.weekDays.friday) ||
|
|
466
|
-
(tripStart.getDay() === 6 && userData.weekDays.saturday)) {
|
|
467
|
-
|
|
468
|
-
const startDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
|
|
469
|
-
const endDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
|
|
470
|
-
|
|
471
|
-
console.log(tripStart, startDate, endDate)
|
|
472
|
-
|
|
473
|
-
//Trips inside time period
|
|
474
|
-
if(startDate.getTime() < endDate.getTime()) {
|
|
475
|
-
return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
|
|
476
|
-
} else {
|
|
477
|
-
return (tripStart.getTime() < endDate.getTime() && tripEnd.getTime() < endDate.getTime()) ||
|
|
478
|
-
(tripStart.getTime() > startDate.getTime())
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
return false
|
|
483
|
-
}
|
|
484
|
-
|
|
485
441
|
exports.createTripReport = createTripReport;
|
|
486
442
|
exports.exportTripReportToPDF = exportTripReportToPDF;
|
|
487
443
|
exports.exportTripReportToExcel = exportTripReportToExcel;
|
package/src/util/driver.js
CHANGED
|
@@ -9,10 +9,9 @@ async function devicesByDriver(traccarInstance, from, to, drivers, devices){
|
|
|
9
9
|
return e.attributes.driverUniqueId === d.uniqueId
|
|
10
10
|
})
|
|
11
11
|
|
|
12
|
-
deviceIds.push(events.map(e => e.deviceId))
|
|
12
|
+
deviceIds.push(...events.map(e => e.deviceId))
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
return [...new Set(deviceIds.flat())]
|
|
14
|
+
return devices.filter(d => deviceIds.includes(d.id))
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
exports.devicesByDriver = devicesByDriver
|
package/src/util/traccar.js
CHANGED
|
@@ -14,12 +14,12 @@ async function getRoute(traccar, from, to, devices){
|
|
|
14
14
|
return result.map(r => r.data).flat()
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async function getTrips(traccar, from, to,
|
|
18
|
-
const devicesToSlice =
|
|
17
|
+
async function getTrips(traccar, from, to, devices){
|
|
18
|
+
const devicesToSlice = devices.slice()
|
|
19
19
|
const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
|
|
20
20
|
let requests = []
|
|
21
21
|
for (const a of arrayOfArrays) {
|
|
22
|
-
const promise = traccar.reports.reportsTripsGet(from, to, a)
|
|
22
|
+
const promise = traccar.reports.reportsTripsGet(from, to, a.map(d => d.id))
|
|
23
23
|
requests = requests.concat(promise)
|
|
24
24
|
}
|
|
25
25
|
|
package/src/util/trips.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
const traccar = require("./traccar");
|
|
2
|
+
const {coordsDistance} = require("./utils");
|
|
2
3
|
|
|
3
4
|
const minDistance = 0
|
|
4
5
|
const minAvgSpeed = 0
|
|
5
6
|
|
|
7
|
+
function addNearestPOIs(trips, userData){
|
|
8
|
+
trips.forEach(t => {
|
|
9
|
+
t.totalKms = t.distance / 1000
|
|
10
|
+
|
|
11
|
+
const distance = userData.geofences
|
|
12
|
+
.filter(g => g && g.area.startsWith('CIRCLE'))
|
|
13
|
+
.map(g => {
|
|
14
|
+
const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
|
|
15
|
+
const coord = str.trim().split(' ')
|
|
16
|
+
return {
|
|
17
|
+
p: g,
|
|
18
|
+
distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
|
|
22
|
+
if (nearestPOIs.length > 0) {
|
|
23
|
+
t.endPOIName = nearestPOIs[0].p.name
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
6
28
|
async function checkTripsKms(traccarInstance, from, to, routeData, tripsData, devices) {
|
|
7
29
|
console.log('checkTripsKms')
|
|
8
30
|
const trips = tripsData.filter(t => t.distance === minDistance && t.averageSpeed > minAvgSpeed)
|
|
@@ -20,4 +42,35 @@ async function checkTripsKms(traccarInstance, from, to, routeData, tripsData, de
|
|
|
20
42
|
}
|
|
21
43
|
}
|
|
22
44
|
|
|
45
|
+
function isInsideTimetable(t, userData){
|
|
46
|
+
const tripStart = new Date(t.startTime)
|
|
47
|
+
const tripEnd = new Date(t.endTime)
|
|
48
|
+
|
|
49
|
+
if((tripStart.getDay() === 0 && userData.weekDays.sunday) ||
|
|
50
|
+
(tripStart.getDay() === 1 && userData.weekDays.monday) ||
|
|
51
|
+
(tripStart.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
52
|
+
(tripStart.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
53
|
+
(tripStart.getDay() === 4 && userData.weekDays.thursday) ||
|
|
54
|
+
(tripStart.getDay() === 5 && userData.weekDays.friday) ||
|
|
55
|
+
(tripStart.getDay() === 6 && userData.weekDays.saturday)) {
|
|
56
|
+
|
|
57
|
+
const startDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
|
|
58
|
+
const endDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
|
|
59
|
+
|
|
60
|
+
console.log(tripStart, startDate, endDate)
|
|
61
|
+
|
|
62
|
+
//Trips inside time period
|
|
63
|
+
if(startDate.getTime() < endDate.getTime()) {
|
|
64
|
+
return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
|
|
65
|
+
} else {
|
|
66
|
+
return (tripStart.getTime() < endDate.getTime() && tripEnd.getTime() < endDate.getTime()) ||
|
|
67
|
+
(tripStart.getTime() > startDate.getTime())
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return false
|
|
72
|
+
}
|
|
73
|
+
|
|
23
74
|
exports.checkTripsKms = checkTripsKms
|
|
75
|
+
exports.isInsideTimetable = isInsideTimetable
|
|
76
|
+
exports.addNearestPOIs = addNearestPOIs
|