fleetmap-reports 1.0.248 → 1.0.252
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 +64 -5
- package/lang/enGB.js +8 -0
- package/lang/esCL.js +8 -0
- package/lang/ptBR.js +8 -0
- package/lang/ptPT.js +8 -0
- package/package.json +1 -1
- package/src/activity-report.js +362 -191
- package/src/index.js +2 -2
- package/src/kms-report.js +150 -95
- package/src/speeding-report.js +110 -45
- package/src/trip-report.js +58 -34
- package/src/util/traccar.js +14 -0
- package/src/util/utils.js +16 -0
package/src/index.js
CHANGED
|
@@ -19,8 +19,8 @@ function Reports(config, axios) {
|
|
|
19
19
|
byGroup: false
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
this.speedingReport = (from, to, userData
|
|
23
|
-
return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar
|
|
22
|
+
this.speedingReport = (from, to, userData) => {
|
|
23
|
+
return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
this.speedingReportToPDF = (userData, reportData) => {
|
package/src/kms-report.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const {createActivityReport} = require("./activity-report");
|
|
2
1
|
const messages = require('../lang')
|
|
3
2
|
const jsPDF = require('jspdf')
|
|
4
3
|
require('jspdf-autotable')
|
|
@@ -6,6 +5,7 @@ const {getStyle} = require("./reportStyle");
|
|
|
6
5
|
const {headerFromUser,addTable} = require("./util/pdfDocument");
|
|
7
6
|
const {getUserPartner} = require("fleetmap-partners");
|
|
8
7
|
const traccar = require("./util/traccar");
|
|
8
|
+
const {getDates} = require("./util/utils");
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
let traccarInstance
|
|
@@ -51,73 +51,102 @@ function processDevices(from, to, devices, route, trips) {
|
|
|
51
51
|
const deviceTrips = trips.filter(t => t.deviceId === d.id)
|
|
52
52
|
|
|
53
53
|
if (deviceTrips.length > 0) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const days = []
|
|
61
|
-
const keys = Array.from(groupedTrips.keys())
|
|
62
|
-
keys.forEach(key => {
|
|
63
|
-
const currentDate = new Date(key)
|
|
64
|
-
let dayTrips = groupedTrips.get(key)
|
|
65
|
-
const day = {
|
|
66
|
-
date: currentDate,
|
|
67
|
-
kms: 0
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if(userData.allWeek){
|
|
71
|
-
day.kms = dayTrips.reduce((a, b) => a + b.distance, 0) || 0
|
|
72
|
-
} else {
|
|
73
|
-
if((currentDate.getDay() === 0 && userData.weekDays.sunday) ||
|
|
74
|
-
(currentDate.getDay() === 1 && userData.weekDays.monday) ||
|
|
75
|
-
(currentDate.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
76
|
-
(currentDate.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
77
|
-
(currentDate.getDay() === 4 && userData.weekDays.thursday) ||
|
|
78
|
-
(currentDate.getDay() === 5 && userData.weekDays.friday) ||
|
|
79
|
-
(currentDate.getDay() === 6 && userData.weekDays.saturday)) {
|
|
80
|
-
|
|
81
|
-
const startDate = new Date(new Date(key).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
|
|
82
|
-
const endDate = new Date(new Date(key).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
|
|
83
|
-
|
|
84
|
-
console.log(key, startDate, endDate)
|
|
85
|
-
|
|
86
|
-
//Trips inside time period
|
|
87
|
-
const filteredTrips = dayTrips.filter(t => new Date(t.startTime).getTime() > startDate.getTime()
|
|
88
|
-
&& new Date(t.endTime).getTime() < endDate.getTime())
|
|
54
|
+
if(userData.groupByDay) {
|
|
55
|
+
deviceTrips.forEach(t => t.tripDay = new Date(t.startTime).toISOString().split('T')[0] + ' 12:00 PM')
|
|
56
|
+
const groupedTrips = deviceTrips.reduce(
|
|
57
|
+
(entryMap, e) => entryMap.set(e.tripDay, [...entryMap.get(e.tripDay)||[], e]),
|
|
58
|
+
new Map()
|
|
59
|
+
)
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
61
|
+
const allDates = getDates(from, to)
|
|
62
|
+
|
|
63
|
+
const days = []
|
|
64
|
+
let keys = Array.from(groupedTrips.keys())
|
|
65
|
+
allDates.forEach(d => {
|
|
66
|
+
const day = d.toISOString().split('T')[0] + ' 12:00 PM'
|
|
67
|
+
if(!keys.includes(day)){
|
|
68
|
+
groupedTrips.set(day, [])
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
keys = Array.from(groupedTrips.keys())
|
|
73
|
+
keys.sort((a,b)=>new Date(a).getTime()-new Date(b).getTime());
|
|
74
|
+
keys.forEach(key => {
|
|
75
|
+
const currentDate = new Date(key)
|
|
76
|
+
let dayTrips = groupedTrips.get(key)
|
|
77
|
+
const day = {
|
|
78
|
+
date: currentDate,
|
|
79
|
+
kms: 0
|
|
80
|
+
}
|
|
93
81
|
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
if(userData.allWeek){
|
|
83
|
+
day.kms = dayTrips.reduce((a, b) => a + b.distance, 0) || 0
|
|
84
|
+
} else {
|
|
85
|
+
if((currentDate.getDay() === 0 && userData.weekDays.sunday) ||
|
|
86
|
+
(currentDate.getDay() === 1 && userData.weekDays.monday) ||
|
|
87
|
+
(currentDate.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
88
|
+
(currentDate.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
89
|
+
(currentDate.getDay() === 4 && userData.weekDays.thursday) ||
|
|
90
|
+
(currentDate.getDay() === 5 && userData.weekDays.friday) ||
|
|
91
|
+
(currentDate.getDay() === 6 && userData.weekDays.saturday)) {
|
|
92
|
+
|
|
93
|
+
const startDate = new Date(new Date(key).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
|
|
94
|
+
const endDate = new Date(new Date(key).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
|
|
95
|
+
|
|
96
|
+
console.log(key, startDate, endDate)
|
|
97
|
+
|
|
98
|
+
if(startDate.getTime() < endDate.getTime()) {
|
|
99
|
+
//Trips inside time period
|
|
100
|
+
const filteredTrips = dayTrips.filter(t => new Date(t.startTime).getTime() > startDate.getTime()
|
|
101
|
+
&& new Date(t.endTime).getTime() < endDate.getTime())
|
|
102
|
+
|
|
103
|
+
day.kms = filteredTrips.reduce((a, b) => a + b.distance, 0) || 0
|
|
104
|
+
console.log('Inside trips:' + day.kms)
|
|
105
|
+
} else {
|
|
106
|
+
//Trips inside time period
|
|
107
|
+
const filteredTrips = dayTrips.filter(t => new Date(t.startTime).getTime() > startDate.getTime()
|
|
108
|
+
|| new Date(t.endTime).getTime() < endDate.getTime())
|
|
109
|
+
|
|
110
|
+
day.kms = filteredTrips.reduce((a, b) => a + b.distance, 0) || 0
|
|
111
|
+
console.log('Inside trips:' + day.kms)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//Trip starts outside time period and ends inside time period
|
|
115
|
+
const startIncompleteTrip = dayTrips.filter(t => new Date(t.startTime).getTime() < startDate.getTime()
|
|
116
|
+
&& new Date(t.endTime).getTime() > startDate.getTime())
|
|
117
|
+
|
|
118
|
+
//Trip starts inside time period and ends outside time period
|
|
119
|
+
const endIncompleteTrip = dayTrips.filter(t => new Date(t.startTime).getTime() < endDate.getTime()
|
|
96
120
|
&& new Date(t.endTime).getTime() > endDate.getTime())
|
|
97
121
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
day.kms = day.kms + (routeInside.reduce((a, b) => a + b.distance, 0) || 0)
|
|
110
|
-
console.log('endIncompleteTrip:'+day.kms)
|
|
122
|
+
if (startIncompleteTrip.length) {
|
|
123
|
+
const routeInside = route.filter(p => new Date(p.fixTime).getTime() > startDate.getTime() && new Date(p.fixTime).getTime() < new Date(startIncompleteTrip[0].endTime).getTime())
|
|
124
|
+
day.kms = day.kms + (routeInside.reduce((a, b) => a + b.distance, 0) || 0)
|
|
125
|
+
console.log('startIncompleteTrip:' + day.kms)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (endIncompleteTrip.length) {
|
|
129
|
+
const routeInside = route.filter(p => new Date(p.fixTime).getTime() < endDate.getTime() && new Date(p.fixTime).getTime() > new Date(endIncompleteTrip[0].startTime).getTime())
|
|
130
|
+
day.kms = day.kms + (routeInside.reduce((a, b) => a + b.distance, 0) || 0)
|
|
131
|
+
console.log('endIncompleteTrip:' + day.kms)
|
|
132
|
+
}
|
|
111
133
|
}
|
|
112
134
|
}
|
|
113
|
-
}
|
|
114
135
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
days.push(day)
|
|
137
|
+
})
|
|
138
|
+
devicesResult.push({
|
|
139
|
+
device: d,
|
|
140
|
+
days: days
|
|
141
|
+
})
|
|
142
|
+
} else {
|
|
143
|
+
devicesResult.push({
|
|
144
|
+
device: d,
|
|
145
|
+
summary: {
|
|
146
|
+
distance: deviceTrips.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0),
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
}
|
|
121
150
|
}
|
|
122
151
|
}
|
|
123
152
|
|
|
@@ -130,27 +159,22 @@ async function createKmsReport(from, to, reportUserData, traccar) {
|
|
|
130
159
|
console.log(from, to)
|
|
131
160
|
traccarInstance = traccar
|
|
132
161
|
userData = reportUserData
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const withoutGroupDevices = await createKmsReportByDevice(from, to)
|
|
144
|
-
reportData.push(withoutGroupDevices)
|
|
145
|
-
} else {
|
|
146
|
-
const allData = await createKmsReportByDevice(from, to)
|
|
147
|
-
reportData.push(allData)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return reportData
|
|
162
|
+
const reportData = []
|
|
163
|
+
if(userData.byDriver){
|
|
164
|
+
const allData = await createKmsReportByDriver(from, to)
|
|
165
|
+
reportData.push(allData)
|
|
166
|
+
}
|
|
167
|
+
else if(userData.byGroup){
|
|
168
|
+
const allGroupsData = await createKmsReportByGroup(from, to)
|
|
169
|
+
allGroupsData.forEach(data => reportData.push(data))
|
|
170
|
+
const withoutGroupDevices = await createKmsReportByDevice(from, to)
|
|
171
|
+
reportData.push(withoutGroupDevices)
|
|
151
172
|
} else {
|
|
152
|
-
|
|
173
|
+
const allData = await createKmsReportByDevice(from, to)
|
|
174
|
+
reportData.push(allData)
|
|
153
175
|
}
|
|
176
|
+
|
|
177
|
+
return reportData
|
|
154
178
|
}
|
|
155
179
|
|
|
156
180
|
async function exportKmsReportToPDF(userData, reportData) {
|
|
@@ -158,6 +182,16 @@ async function exportKmsReportToPDF(userData, reportData) {
|
|
|
158
182
|
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
159
183
|
const kmsData = userData.byDriver ? reportData.drivers : reportData.devices
|
|
160
184
|
|
|
185
|
+
const weekDays = [
|
|
186
|
+
translations.report.sunday,
|
|
187
|
+
translations.report.monday,
|
|
188
|
+
translations.report.tuesday,
|
|
189
|
+
translations.report.wednesday,
|
|
190
|
+
translations.report.thursday,
|
|
191
|
+
translations.report.friday,
|
|
192
|
+
translations.report.saturday
|
|
193
|
+
]
|
|
194
|
+
|
|
161
195
|
const headers = []
|
|
162
196
|
if(userData.groupByDay) {
|
|
163
197
|
headers.push(translations.report.date,
|
|
@@ -174,32 +208,42 @@ async function exportKmsReportToPDF(userData, reportData) {
|
|
|
174
208
|
translations.report.distance)
|
|
175
209
|
}
|
|
176
210
|
if (kmsData) {
|
|
177
|
-
|
|
178
|
-
const doc =
|
|
179
|
-
await headerFromUser(doc, translations.report.titleKmsReport, userData.user,
|
|
211
|
+
const orientation = userData.groupByDay ? 'p' : 'l'
|
|
212
|
+
const doc = new jsPDF.jsPDF(orientation)
|
|
213
|
+
await headerFromUser(doc, translations.report.titleKmsReport, userData.user, orientation)
|
|
180
214
|
|
|
181
215
|
if (userData.groupByDay) {
|
|
182
|
-
|
|
216
|
+
kmsData.forEach(function (d, index) {
|
|
183
217
|
const name = userData.byDriver ? d.driver.name : d.device.name
|
|
184
218
|
const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
|
|
185
219
|
|
|
186
|
-
let space = 0
|
|
187
|
-
if
|
|
220
|
+
let space = index === 0 ? 8 : 0
|
|
221
|
+
if(index){
|
|
188
222
|
doc.addPage()
|
|
189
|
-
} else {
|
|
190
|
-
first = false
|
|
191
|
-
space = 8
|
|
192
223
|
}
|
|
224
|
+
|
|
193
225
|
doc.setFontSize(13)
|
|
194
226
|
doc.text(name, 20, space + 20)
|
|
195
227
|
doc.setFontSize(11)
|
|
196
228
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
|
|
197
229
|
doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
|
|
198
230
|
|
|
231
|
+
if(!userData.allWeek) {
|
|
232
|
+
doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
|
|
233
|
+
+ (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
|
|
234
|
+
+ (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
|
|
235
|
+
+ (userData.weekDays.thursday ? ' ' + translations.report.thursday + ',' : '')
|
|
236
|
+
+ (userData.weekDays.friday ? ' ' + translations.report.friday + ',' : '')
|
|
237
|
+
+ (userData.weekDays.saturday ? ' ' + translations.report.saturday + ',' : '')
|
|
238
|
+
+ (userData.weekDays.sunday ? ' ' + translations.report.sunday + ',' : '')
|
|
239
|
+
+ ' das '
|
|
240
|
+
+ userData.dayHours.startTime + ' - ' + userData.dayHours.endTime, 20, space + 30)
|
|
241
|
+
}
|
|
242
|
+
|
|
199
243
|
const data = []
|
|
200
244
|
d.days.forEach(day => {
|
|
201
245
|
const temp = [
|
|
202
|
-
new Date(day.date).toLocaleDateString(),
|
|
246
|
+
new Date(day.date).toLocaleDateString() + ' - ' + weekDays[day.date.getDay()],
|
|
203
247
|
(day.kms/1000).toFixed(0)
|
|
204
248
|
]
|
|
205
249
|
|
|
@@ -213,9 +257,8 @@ async function exportKmsReportToPDF(userData, reportData) {
|
|
|
213
257
|
)
|
|
214
258
|
|
|
215
259
|
const style = getStyle(getUserPartner(userData.user))
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
260
|
+
addTable(doc, headers, data, footValues, style, 40)
|
|
261
|
+
})
|
|
219
262
|
} else {
|
|
220
263
|
const data = []
|
|
221
264
|
if (userData.byDriver) {
|
|
@@ -234,7 +277,7 @@ async function exportKmsReportToPDF(userData, reportData) {
|
|
|
234
277
|
const group = userData.groups.find(g => d.device.groupId === g.id)
|
|
235
278
|
|
|
236
279
|
const temp = [
|
|
237
|
-
d.
|
|
280
|
+
d.device.name,
|
|
238
281
|
d.device.model,
|
|
239
282
|
group ? group.name : '',
|
|
240
283
|
Number((d.summary.distance / 1000).toFixed(0))
|
|
@@ -273,6 +316,16 @@ function exportKmsReportToExcel(userData, reportData) {
|
|
|
273
316
|
const lang = userData.user.attributes.lang || (navigator && navigator.language)
|
|
274
317
|
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
275
318
|
|
|
319
|
+
const weekDays = [
|
|
320
|
+
translations.report.sunday,
|
|
321
|
+
translations.report.monday,
|
|
322
|
+
translations.report.tuesday,
|
|
323
|
+
translations.report.wednesday,
|
|
324
|
+
translations.report.thursday,
|
|
325
|
+
translations.report.friday,
|
|
326
|
+
translations.report.saturday
|
|
327
|
+
]
|
|
328
|
+
|
|
276
329
|
const settings = {
|
|
277
330
|
sheetName: translations.report.titleKmsReport, // The name of the sheet
|
|
278
331
|
fileName: fileName // The name of the spreadsheet
|
|
@@ -286,6 +339,7 @@ function exportKmsReportToExcel(userData, reportData) {
|
|
|
286
339
|
{label: translations.report.licensePlate, value: 'licenseplate'},
|
|
287
340
|
{label: translations.report.group, value: 'group'},
|
|
288
341
|
{label: translations.report.date, value: 'date'},
|
|
342
|
+
{label: translations.report.weekDay, value: 'weekday'},
|
|
289
343
|
{label: translations.report.distance, value: 'distance'})
|
|
290
344
|
} else if(userData.byDriver) {
|
|
291
345
|
headers.push(
|
|
@@ -314,12 +368,13 @@ function exportKmsReportToExcel(userData, reportData) {
|
|
|
314
368
|
group: group ? group.name : '',
|
|
315
369
|
licenseplate: d.device.attributes.license_plate,
|
|
316
370
|
date: a.date,
|
|
371
|
+
weekday: weekDays[a.date.getDay()],
|
|
317
372
|
distance: Number((a.kms / 1000).toFixed(0))
|
|
318
373
|
}
|
|
319
374
|
}))
|
|
320
375
|
} else {
|
|
321
376
|
data = data.concat([{
|
|
322
|
-
name: userData.byDriver ? d.driver.name : d.
|
|
377
|
+
name: userData.byDriver ? d.driver.name : d.device.name,
|
|
323
378
|
group: group ? group.name : '',
|
|
324
379
|
licenseplate: userData.byDriver ? '' : d.device.attributes.license_plate,
|
|
325
380
|
distance: Number((d.summary.distance / 1000).toFixed(0))
|
package/src/speeding-report.js
CHANGED
|
@@ -13,16 +13,18 @@ const {getUserPartner} = require("fleetmap-partners");
|
|
|
13
13
|
const traccar = require("./util/traccar");
|
|
14
14
|
|
|
15
15
|
let traccarInstance
|
|
16
|
+
let userData
|
|
16
17
|
|
|
17
18
|
const fileName = 'SpeedingReport'
|
|
18
19
|
|
|
19
|
-
async function createSpeedingReport(from, to,
|
|
20
|
+
async function createSpeedingReport(from, to, reportUserData, traccar) {
|
|
20
21
|
traccarInstance = traccar
|
|
21
|
-
|
|
22
|
+
userData = reportUserData
|
|
23
|
+
console.log('createSpeedingReport', from, to, userData, traccar)
|
|
22
24
|
const reportData = []
|
|
23
25
|
|
|
24
26
|
if(userData.byDriver){
|
|
25
|
-
const allData = await createSpeedingReportByDriver(from, to
|
|
27
|
+
const allData = await createSpeedingReportByDriver(from, to)
|
|
26
28
|
reportData.push(allData)
|
|
27
29
|
}
|
|
28
30
|
else if(userData.byGroup){
|
|
@@ -37,48 +39,50 @@ async function createSpeedingReport(from, to, userData, traccar, roadSpeedLimits
|
|
|
37
39
|
xpert: devices.filter(d => d.attributes.xpert).length > 0
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
+
const eventTypes = ['deviceOverspeed']
|
|
43
|
+
const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
|
|
44
|
+
const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, devices)
|
|
42
45
|
|
|
43
46
|
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
44
47
|
|
|
45
|
-
if (
|
|
46
|
-
groupData.devices = await processDevices(from, to, devices,
|
|
48
|
+
if (events.length > 0) {
|
|
49
|
+
groupData.devices = await processDevices(from, to, devices, events, routes)
|
|
47
50
|
reportData.push(groupData)
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
const withoutGroupData = await createSpeedingReportByDevice(from, to
|
|
55
|
+
const withoutGroupData = await createSpeedingReportByDevice(from, to)
|
|
53
56
|
reportData.push(withoutGroupData)
|
|
54
57
|
} else {
|
|
55
|
-
const allData = await createSpeedingReportByDevice(from, to
|
|
58
|
+
const allData = await createSpeedingReportByDevice(from, to)
|
|
56
59
|
reportData.push(allData)
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
return reportData
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
async function createSpeedingReportByDevice(from, to
|
|
65
|
+
async function createSpeedingReportByDevice(from, to) {
|
|
63
66
|
const groupIds = userData.groups.map(g => g.id)
|
|
64
67
|
const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
|
|
65
68
|
|
|
66
69
|
withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
67
70
|
|
|
68
|
-
const
|
|
69
|
-
const
|
|
71
|
+
const eventTypes = ['deviceOverspeed']
|
|
72
|
+
const events = await traccar.getEvents(traccarInstance, from, to, withoutGroupDevices, eventTypes)
|
|
73
|
+
const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, withoutGroupDevices)
|
|
70
74
|
|
|
71
75
|
const allData = { devices: [] }
|
|
72
76
|
|
|
73
|
-
if(
|
|
74
|
-
allData.devices = await processDevices(from, to, withoutGroupDevices,
|
|
77
|
+
if(events.length > 0 || userData.roadSpeedLimits) {
|
|
78
|
+
allData.devices = await processDevices(from, to, withoutGroupDevices, events, routes)
|
|
75
79
|
allData.xpert = withoutGroupDevices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
return allData
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
async function createSpeedingReportByDriver(from, to
|
|
85
|
+
async function createSpeedingReportByDriver(from, to) {
|
|
82
86
|
const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
83
87
|
console.log('Devices with driver',deviceIds.length)
|
|
84
88
|
|
|
@@ -93,18 +97,18 @@ async function createSpeedingReportByDriver(from, to, userData) {
|
|
|
93
97
|
}
|
|
94
98
|
console.log(eventsData.length)
|
|
95
99
|
|
|
96
|
-
await getEventsPosition(from , to, userData.devices,
|
|
97
|
-
allData.drivers = await processDrivers(from, to,
|
|
100
|
+
await getEventsPosition(from , to, userData.devices, eventsData)
|
|
101
|
+
allData.drivers = await processDrivers(from, to, eventsData)
|
|
98
102
|
console.log(allData.drivers.length)
|
|
99
103
|
return allData
|
|
100
104
|
}
|
|
101
105
|
|
|
102
|
-
async function processDrivers(from, to,
|
|
106
|
+
async function processDrivers(from, to, data) {
|
|
103
107
|
console.log(data)
|
|
104
108
|
const driversResult = []
|
|
105
109
|
const alertsWithPosition = data.filter(a => a.position)
|
|
106
110
|
|
|
107
|
-
drivers.forEach(d => {
|
|
111
|
+
userData.drivers.forEach(d => {
|
|
108
112
|
const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
|
|
109
113
|
|
|
110
114
|
if (alerts.length > 0) {
|
|
@@ -124,34 +128,70 @@ async function processDrivers(from, to, drivers, data) {
|
|
|
124
128
|
return driversResult
|
|
125
129
|
}
|
|
126
130
|
|
|
127
|
-
async function processDevices(from, to, devices,
|
|
131
|
+
async function processDevices(from, to, devices, events, routes) {
|
|
128
132
|
const devicesResult = []
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
if(userData.useVehicleSpeedLimit) {
|
|
135
|
+
await getEventsPosition(from, to, devices, events)
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
console.log(events)
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
for (const d of devices) {
|
|
140
|
+
const deviceEvents = events.filter(t => t.deviceId === d.id)
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
if (deviceEvents.length > 0) {
|
|
143
|
+
const alertsWithPosition = deviceEvents.filter(a => a.position).sort((a, b) => a.positionId - b.positionId)
|
|
144
|
+
devicesResult.push({
|
|
145
|
+
device: d,
|
|
146
|
+
from: from,
|
|
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
|
+
}
|
|
148
188
|
}
|
|
149
189
|
}
|
|
150
190
|
|
|
151
191
|
return devicesResult
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
async function getEventsPosition(from, to, devices,
|
|
194
|
+
async function getEventsPosition(from, to, devices, events){
|
|
155
195
|
|
|
156
196
|
const deviceIds = [...new Set(events.map(e => e.deviceId))]
|
|
157
197
|
const routeData = await traccar.getRoute(traccarInstance, from, to, deviceIds.map(id => { return { id: id } } ))
|
|
@@ -161,10 +201,10 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
161
201
|
for (const d of devices) {
|
|
162
202
|
let alerts = events.filter(t => t.deviceId === d.id)
|
|
163
203
|
|
|
164
|
-
if (alerts.length > 0 || roadSpeedLimits) {
|
|
204
|
+
if (alerts.length > 0 || userData.roadSpeedLimits) {
|
|
165
205
|
const positions = routeData.filter(p => p.deviceId === d.id)
|
|
166
206
|
|
|
167
|
-
if (roadSpeedLimits && positions.length) {
|
|
207
|
+
if (userData.roadSpeedLimits && positions.length) {
|
|
168
208
|
try {
|
|
169
209
|
const results = await here.routeMatch(positions)
|
|
170
210
|
const hereAlerts = results.map(r => {
|
|
@@ -202,7 +242,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
202
242
|
let geofence = null
|
|
203
243
|
|
|
204
244
|
if (a.geofenceId) {
|
|
205
|
-
geofence = geofences.find(g => g.id === a.geofenceId)
|
|
245
|
+
geofence = userData.geofences.find(g => g.id === a.geofenceId)
|
|
206
246
|
if (geofence) {
|
|
207
247
|
a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
|
|
208
248
|
}
|
|
@@ -230,7 +270,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
if (a.position.attributes.driverUniqueId) {
|
|
233
|
-
const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
|
|
273
|
+
const driver = userData.drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
|
|
234
274
|
a.driver = driver && driver.name
|
|
235
275
|
}
|
|
236
276
|
|
|
@@ -243,6 +283,31 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
243
283
|
}
|
|
244
284
|
}
|
|
245
285
|
|
|
286
|
+
function calculateEventData(positions, pIndex, a, geofence){
|
|
287
|
+
let endEventPosition = a.position
|
|
288
|
+
let maxSpeed = a.position.speed
|
|
289
|
+
let dist = 0
|
|
290
|
+
while (pIndex + 1 < positions.length) {
|
|
291
|
+
pIndex++
|
|
292
|
+
|
|
293
|
+
dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
|
|
294
|
+
point([positions[pIndex].longitude, positions[pIndex].latitude]))
|
|
295
|
+
endEventPosition = positions[pIndex]
|
|
296
|
+
if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
|
|
297
|
+
a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
|
|
298
|
+
a.attributes.maxSpeed = maxSpeed
|
|
299
|
+
a.distance = dist
|
|
300
|
+
break
|
|
301
|
+
} else {
|
|
302
|
+
if (maxSpeed < endEventPosition.speed) {
|
|
303
|
+
maxSpeed = endEventPosition.speed
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return pIndex
|
|
309
|
+
}
|
|
310
|
+
|
|
246
311
|
function isOutsideGeofence(geofence, endEventPosition) {
|
|
247
312
|
const v = turf.feature(turf.flip(parse(geofence.area)))
|
|
248
313
|
const point = turf.point([endEventPosition.longitude, endEventPosition.latitude])
|
|
@@ -266,7 +331,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
266
331
|
translations.report.duration,
|
|
267
332
|
]
|
|
268
333
|
|
|
269
|
-
if(userData.
|
|
334
|
+
if(userData.roadSpeedLimits) {
|
|
270
335
|
headers.splice(2, 0, translations.report.roadSpeedLimit)
|
|
271
336
|
}
|
|
272
337
|
|
|
@@ -301,7 +366,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
301
366
|
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
|
|
302
367
|
doc.text(new Date(d.from).toLocaleString() + ' - ' + new Date(d.to).toLocaleString(), 20, space+25 )
|
|
303
368
|
if (d.alerts[0] && !userData.byDriver) {
|
|
304
|
-
doc.text(translations.report.speedLimit + ": " + Math.round(d.alerts[0].attributes.speedLimit * 1.85200) + ' Km/h', 20, space + 30)
|
|
369
|
+
doc.text(translations.report.speedLimit + ": " + (userData.useVehicleSpeedLimit ? Math.round(d.alerts[0].attributes.speedLimit * 1.85200) : userData.customSpeed) + ' Km/h', 20, space + 30)
|
|
305
370
|
}
|
|
306
371
|
d.alerts.map(a => {
|
|
307
372
|
const temp = [
|
|
@@ -314,7 +379,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
314
379
|
userData.byDriver ? a.deviceName : a.driver
|
|
315
380
|
]
|
|
316
381
|
|
|
317
|
-
if(userData.
|
|
382
|
+
if(userData.roadSpeedLimits){
|
|
318
383
|
temp.splice(2, 0, a.roadSpeedLimit)
|
|
319
384
|
}
|
|
320
385
|
|
|
@@ -330,7 +395,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
330
395
|
convertMS(d.alerts.reduce((a, b) => a + b.eventTime, 0), true)
|
|
331
396
|
]
|
|
332
397
|
|
|
333
|
-
if(userData.
|
|
398
|
+
if(userData.roadSpeedLimits){
|
|
334
399
|
footValues.splice(2, 0, '')
|
|
335
400
|
}
|
|
336
401
|
|
|
@@ -389,7 +454,7 @@ function exportSpeedingReportToExcel(userData, reportData) {
|
|
|
389
454
|
userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
|
|
390
455
|
]
|
|
391
456
|
|
|
392
|
-
if (userData.
|
|
457
|
+
if (userData.roadSpeedLimits){
|
|
393
458
|
headers.splice(3, 0, {label: translations.report.roadSpeedLimit, value:'roadSpeedLimit'})
|
|
394
459
|
}
|
|
395
460
|
|