fleetmap-reports 1.0.247 → 1.0.251

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.
@@ -1,4 +1,3 @@
1
- const automaticReports = require("./automaticReports")
2
1
  const messages = require('../lang')
3
2
  const jsPDF = require('jspdf')
4
3
  const {convertMS} = require("./util/utils")
@@ -14,16 +13,18 @@ const {getUserPartner} = require("fleetmap-partners");
14
13
  const traccar = require("./util/traccar");
15
14
 
16
15
  let traccarInstance
16
+ let userData
17
17
 
18
18
  const fileName = 'SpeedingReport'
19
19
 
20
- async function createSpeedingReport(from, to, userData, traccar, roadSpeedLimits) {
20
+ async function createSpeedingReport(from, to, reportUserData, traccar) {
21
21
  traccarInstance = traccar
22
- console.log('createSpeedingReport', from, to, userData, traccar, roadSpeedLimits)
22
+ userData = reportUserData
23
+ console.log('createSpeedingReport', from, to, userData, traccar)
23
24
  const reportData = []
24
25
 
25
26
  if(userData.byDriver){
26
- const allData = await createSpeedingReportByDriver(from, to, userData, roadSpeedLimits)
27
+ const allData = await createSpeedingReportByDriver(from, to)
27
28
  reportData.push(allData)
28
29
  }
29
30
  else if(userData.byGroup){
@@ -38,76 +39,76 @@ async function createSpeedingReport(from, to, userData, traccar, roadSpeedLimits
38
39
  xpert: devices.filter(d => d.attributes.xpert).length > 0
39
40
  }
40
41
 
41
- const data = await getReportData(from, to, devices)
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 (data.length > 0) {
46
- groupData.devices = await processDevices(from, to, devices, userData.geofences, userData.drivers, data, roadSpeedLimits)
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, userData)
55
+ const withoutGroupData = await createSpeedingReportByDevice(from, to)
53
56
  reportData.push(withoutGroupData)
54
57
  } else {
55
- const allData = await createSpeedingReportByDevice(from, to, userData, roadSpeedLimits)
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, userData, roadSpeedLimits) {
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 events = ['deviceOverspeed']
69
- const data = await traccar.getEvents(traccarInstance, from, to, withoutGroupDevices, events)
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(data.length > 0 || roadSpeedLimits) {
74
- allData.devices = await processDevices(from, to, withoutGroupDevices, userData.geofences, userData.drivers, data, roadSpeedLimits)
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, userData) {
85
+ async function createSpeedingReportByDriver(from, to) {
82
86
  const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
83
- console.log(deviceIds.length)
87
+ console.log('Devices with driver',deviceIds.length)
84
88
 
85
89
  let eventsData = []
86
90
  if(deviceIds.length > 0) {
87
- console.log('getReportData', deviceIds.length)
88
91
  const devices = userData.devices.filter(d => deviceIds.includes(d.id))
89
- eventsData = await getReportData(from, to, devices)
92
+ eventsData = await traccar.getEvents(traccarInstance, from, to, devices,['deviceOverspeed'])
90
93
  }
91
94
 
92
95
  const allData = {
93
96
  drivers: []
94
97
  }
95
-
96
98
  console.log(eventsData.length)
97
99
 
98
- await getEventsPosition(from , to, userData.devices, userData.geofences, userData.drivers, eventsData)
99
-
100
- allData.drivers = await processDrivers(from, to, userData.drivers, eventsData)
100
+ await getEventsPosition(from , to, userData.devices, eventsData)
101
+ allData.drivers = await processDrivers(from, to, eventsData)
101
102
  console.log(allData.drivers.length)
102
103
  return allData
103
104
  }
104
105
 
105
- async function processDrivers(from, to, drivers, data) {
106
+ async function processDrivers(from, to, data) {
106
107
  console.log(data)
107
108
  const driversResult = []
108
109
  const alertsWithPosition = data.filter(a => a.position)
109
110
 
110
- drivers.forEach(d => {
111
+ userData.drivers.forEach(d => {
111
112
  const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
112
113
 
113
114
  if (alerts.length > 0) {
@@ -127,52 +128,70 @@ async function processDrivers(from, to, drivers, data) {
127
128
  return driversResult
128
129
  }
129
130
 
130
- async function getReportData(from, to, devices) {
131
- const types = ['deviceOverspeed']
132
- let data = []
133
- const arrayOfArrays = automaticReports.sliceArray(devices)
134
- for (const a of arrayOfArrays) {
135
- try {
136
- const devices = a.map(d => d.id)
137
- console.log('reportsEventsGet', from, to, devices, null, types)
138
- const response = await traccarInstance.reports.reportsEventsGet(from, to, devices, null, types)
139
- data = data.concat(response.data)
140
- } catch (e) {
141
- console.error(e)
142
- }
143
- }
144
- console.log('Alerts:', data.length)
145
- return data
146
- }
147
-
148
- async function processDevices(from, to, devices, geofences, drivers, data, roadSpeedLimits) {
131
+ async function processDevices(from, to, devices, events, routes) {
149
132
  const devicesResult = []
150
133
 
151
- await getEventsPosition(from , to, devices, geofences, drivers, data, roadSpeedLimits)
134
+ if(userData.useVehicleSpeedLimit) {
135
+ await getEventsPosition(from, to, devices, events)
152
136
 
153
- console.log(data)
137
+ console.log(events)
154
138
 
155
- for (const d of devices) {
156
- const alerts = data.filter(t => t.deviceId === d.id)
139
+ for (const d of devices) {
140
+ const deviceEvents = events.filter(t => t.deviceId === d.id)
157
141
 
158
- if (alerts.length > 0) {
159
- const alertsWithPosition = alerts.filter(a => a.position).sort((a,b) => a.positionId - b.positionId)
160
- devicesResult.push({
161
- device: d,
162
- from: from,
163
- to: to,
164
- alerts: alertsWithPosition,
165
- maxSpeed: alertsWithPosition.reduce((a, b) => {
166
- return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
167
- }, 0),
168
- })
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
+ }
169
188
  }
170
189
  }
171
190
 
172
191
  return devicesResult
173
192
  }
174
193
 
175
- async function getEventsPosition(from, to, devices, geofences, drivers, events, roadSpeedLimits){
194
+ async function getEventsPosition(from, to, devices, events){
176
195
 
177
196
  const deviceIds = [...new Set(events.map(e => e.deviceId))]
178
197
  const routeData = await traccar.getRoute(traccarInstance, from, to, deviceIds.map(id => { return { id: id } } ))
@@ -182,10 +201,10 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
182
201
  for (const d of devices) {
183
202
  let alerts = events.filter(t => t.deviceId === d.id)
184
203
 
185
- if (alerts.length > 0 || roadSpeedLimits) {
204
+ if (alerts.length > 0 || userData.roadSpeedLimits) {
186
205
  const positions = routeData.filter(p => p.deviceId === d.id)
187
206
 
188
- if (roadSpeedLimits && positions.length) {
207
+ if (userData.roadSpeedLimits && positions.length) {
189
208
  try {
190
209
  const results = await here.routeMatch(positions)
191
210
  const hereAlerts = results.map(r => {
@@ -223,7 +242,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
223
242
  let geofence = null
224
243
 
225
244
  if (a.geofenceId) {
226
- geofence = geofences.find(g => g.id === a.geofenceId)
245
+ geofence = userData.geofences.find(g => g.id === a.geofenceId)
227
246
  if (geofence) {
228
247
  a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
229
248
  }
@@ -251,7 +270,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
251
270
  }
252
271
 
253
272
  if (a.position.attributes.driverUniqueId) {
254
- const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
273
+ const driver = userData.drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
255
274
  a.driver = driver && driver.name
256
275
  }
257
276
 
@@ -264,6 +283,31 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
264
283
  }
265
284
  }
266
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
+
267
311
  function isOutsideGeofence(geofence, endEventPosition) {
268
312
  const v = turf.feature(turf.flip(parse(geofence.area)))
269
313
  const point = turf.point([endEventPosition.longitude, endEventPosition.latitude])
@@ -287,7 +331,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
287
331
  translations.report.duration,
288
332
  ]
289
333
 
290
- if(userData.useRoadSpeedLimits) {
334
+ if(userData.roadSpeedLimits) {
291
335
  headers.splice(2, 0, translations.report.roadSpeedLimit)
292
336
  }
293
337
 
@@ -335,7 +379,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
335
379
  userData.byDriver ? a.deviceName : a.driver
336
380
  ]
337
381
 
338
- if(userData.useRoadSpeedLimits){
382
+ if(userData.roadSpeedLimits){
339
383
  temp.splice(2, 0, a.roadSpeedLimit)
340
384
  }
341
385
 
@@ -351,7 +395,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
351
395
  convertMS(d.alerts.reduce((a, b) => a + b.eventTime, 0), true)
352
396
  ]
353
397
 
354
- if(userData.useRoadSpeedLimits){
398
+ if(userData.roadSpeedLimits){
355
399
  footValues.splice(2, 0, '')
356
400
  }
357
401
 
@@ -410,7 +454,7 @@ function exportSpeedingReportToExcel(userData, reportData) {
410
454
  userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
411
455
  ]
412
456
 
413
- if (userData.useRoadSpeedLimits){
457
+ if (userData.roadSpeedLimits){
414
458
  headers.splice(3, 0, {label: translations.report.roadSpeedLimit, value:'roadSpeedLimit'})
415
459
  }
416
460
 
@@ -5,9 +5,10 @@ const {convertMS} = require("./util/utils")
5
5
  require('jspdf-autotable')
6
6
  const {coordsDistance} = require("./util/utils")
7
7
  const drivers = require("./util/driver")
8
- const {getUserPartner} = require("fleetmap-partners");
8
+ const {getUserPartner} = require("fleetmap-partners")
9
9
  const {headerFromUser} = require("./util/pdfDocument")
10
10
  const {getStyle} = require("./reportStyle")
11
+ const traccar = require("./util/traccar")
11
12
 
12
13
 
13
14
  let traccarInstance
@@ -16,7 +17,6 @@ const fileName = 'TripReport'
16
17
 
17
18
  async function createTripReport(from, to, userData, traccar) {
18
19
  console.log('Create TripReport')
19
-
20
20
  traccarInstance = traccar
21
21
  const reportData = []
22
22
 
@@ -26,72 +26,74 @@ async function createTripReport(from, to, userData, traccar) {
26
26
  }
27
27
  else if(userData.byGroup){
28
28
  console.log("ByGroup")
29
- for (const g of userData.groups) {
30
- const devices = userData.devices.filter(d => d.groupId === g.id)
31
- console.log(g.name + ' devices:' + devices.length)
32
- if(devices.length > 0) {
33
- const groupData = {
34
- devices: [],
35
- group: g,
36
- xpert: devices.filter(d => d.attributes.xpert).length > 0
37
- }
38
-
39
- const response = await traccarInstance.reports.reportsTripsGet(from, to, null, [g.id])
40
- const data = response.data
41
-
42
- const stopsResponse = await traccarInstance.reports.reportsStopsGet(from, to, null, [g.id])
43
- const stopsData = stopsResponse.data
44
-
45
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
46
-
47
- if (data.length > 0) {
48
-
49
- console.log('Trips:' + data.length)
50
- groupData.devices = processDevices(from, to, devices, data, stopsData)
51
-
52
- reportData.push(groupData)
53
- }
54
- }
55
- }
29
+ const allData = await createTripReportByGroup(from, to, userData)
30
+ reportData.push(...allData)
56
31
  }
57
32
 
58
33
  const groupIds = userData.groups.map(g => g.id)
59
34
  const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
60
35
 
36
+ const allData = await createTripReportByDevice(from, to, userData, withoutGroupDevices)
37
+ reportData.push(allData)
38
+
39
+ return reportData
40
+ }
41
+
42
+ async function createTripReportByDevice(from, to, userData, devices) {
61
43
  const allData = {
62
44
  devices: [],
63
- xpert: withoutGroupDevices.filter(d => d.attributes.xpert).length > 0
45
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
64
46
  }
65
47
 
66
- withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
67
- const devicesToSlice = withoutGroupDevices.slice()
68
-
69
- const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
70
- let data = []
71
- let stopsData = []
72
- for (const a of arrayOfArrays) {
73
- const response = await traccarInstance.reports.reportsTripsGet(from, to, a.map(d => d.id))
74
- data = data.concat(response.data)
48
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
75
49
 
76
- const stopsResponse = await traccarInstance.reports.reportsStopsGet(from, to, a.map(d => d.id))
77
- stopsData = stopsResponse.data
78
- }
50
+ const devicesToSlice = devices.slice()
51
+ const data = await traccar.getTrips(traccarInstance, from, to, devicesToSlice)
52
+ const stopsData = await traccar.getStops(traccarInstance, from, to, devicesToSlice)
79
53
 
80
54
  console.log('Trips:' + data.length)
81
55
 
82
- if (data.length === 0) {
83
- return reportData
56
+ if (data.length > 0) {
57
+ allData.devices = processDevices(from, to, devices, data, stopsData, userData)
58
+
84
59
  }
85
60
 
86
- allData.devices = processDevices(from, to, withoutGroupDevices, data, stopsData, userData)
61
+ return allData
62
+ }
87
63
 
88
- reportData.push(allData)
64
+ async function createTripReportByGroup(from, to, userData) {
65
+ const reportData = []
66
+ for (const g of userData.groups) {
67
+ const devices = userData.devices.filter(d => d.groupId === g.id)
68
+ console.log(g.name + ' devices:' + devices.length)
69
+ if(devices.length > 0) {
70
+ const groupData = {
71
+ devices: [],
72
+ group: g,
73
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
74
+ }
75
+
76
+ const response = await traccarInstance.reports.reportsTripsGet(from, to, null, [g.id])
77
+ const data = response.data
89
78
 
79
+ const stopsResponse = await traccarInstance.reports.reportsStopsGet(from, to, null, [g.id])
80
+ const stopsData = stopsResponse.data
81
+
82
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
83
+
84
+ if (data.length > 0) {
85
+
86
+ console.log('Trips:' + data.length)
87
+ groupData.devices = processDevices(from, to, devices, data, stopsData, userData)
88
+
89
+ reportData.push(groupData)
90
+ }
91
+ }
92
+ }
90
93
  return reportData
91
94
  }
92
95
 
93
96
  async function createTripReportByDriver(from, to, userData){
94
-
95
97
  const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
96
98
  console.log(deviceIds.length)
97
99
 
@@ -1,14 +1,8 @@
1
- const automaticReports = require("../automaticReports")
1
+ const traccar = require("./traccar");
2
2
 
3
3
  //get devices used by each driver between two dates
4
- async function devicesByDriver(traccar, from, to, drivers, devices){
5
- let eventsData = []
6
- let tripsData = []
7
- const arrayOfArrays = automaticReports.sliceArray(devices)
8
- for (const a of arrayOfArrays) {
9
- const response = await traccar.reports.reportsEventsGet(from, to, a.map(d => d.id), null, ['driverChanged'])
10
- eventsData = eventsData.concat(response.data)
11
- }
4
+ async function devicesByDriver(traccarInstance, from, to, drivers, devices){
5
+ const eventsData = traccar.getEvents(traccarInstance, from, to , devices, ['driverChanged'])
12
6
 
13
7
  const deviceIds = []
14
8
  for(const d of drivers) {
@@ -27,6 +27,19 @@ async function getTrips(traccar, from, to, devices){
27
27
  return result.map(r => r.data).flat()
28
28
  }
29
29
 
30
+ async function getStops(traccar, from, to, devices){
31
+ const devicesToSlice = devices.slice()
32
+ const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
33
+ let requests = []
34
+ for (const a of arrayOfArrays) {
35
+ const promise = traccar.reports.reportsStopsGet(from, to, a.map(d => d.id))
36
+ requests = requests.concat(promise)
37
+ }
38
+
39
+ const result = await Promise.all(requests)
40
+ return result.map(r => r.data).flat()
41
+ }
42
+
30
43
  async function getEvents(traccar, from, to, devices, events){
31
44
  const devicesToSlice = devices.slice()
32
45
  const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
@@ -41,4 +54,5 @@ async function getEvents(traccar, from, to, devices, events){
41
54
 
42
55
  exports.getRoute = getRoute
43
56
  exports.getTrips = getTrips
57
+ exports.getStops = getStops
44
58
  exports.getEvents = getEvents
package/src/util/utils.js CHANGED
@@ -29,6 +29,21 @@ function coordsDistance(lon1, lat1, lon2, lat2) {
29
29
  return (turf.distance(from, to, 'meters'))
30
30
  }
31
31
 
32
+ function getDates(startDate, endDate) {
33
+ const dates = []
34
+ let currentDate = startDate
35
+ const addDays = function (days) {
36
+ const date = new Date(this.valueOf())
37
+ date.setDate(date.getDate() + days)
38
+ return date
39
+ }
40
+ while (currentDate <= endDate) {
41
+ dates.push(currentDate)
42
+ currentDate = addDays.call(currentDate, 1)
43
+ }
44
+ return dates
45
+ }
46
+
32
47
  async function getImgFromUrl(hostname) {
33
48
  try {
34
49
  const img = new Image()
@@ -43,4 +58,5 @@ async function getImgFromUrl(hostname) {
43
58
  exports.getImgFromUrl = getImgFromUrl
44
59
  exports.convertMS = convertMS
45
60
  exports.coordsDistance = coordsDistance
61
+ exports.getDates = getDates
46
62