fleetmap-reports 1.0.284 → 1.0.288

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.
@@ -109,31 +109,21 @@ function calculateRefuelingPositions(d, positions) {
109
109
  let refuelingActivated = false
110
110
  let currentValue = null
111
111
  let positionsChecked = 0
112
- let lastRefuelingIndex = 0
113
112
  positions.forEach(function(element, index, array){
114
113
  if(!element.attributes.ignition && refuelingActivated && !currentValue){
115
- //Ignition is off and Refueling is Active and there is no current value
116
-
117
- //Get 5 position before the ignition off to calculate the current value of the fuel tank level
118
- //lastRefuelingIndex is used to avoid re-analyzing positions prior to a refueling
119
- const before = (index > 5 ? array.slice((index-6 < lastRefuelingIndex ? lastRefuelingIndex : index-6), index-1) : array.slice(0, index-1)).filter(b => b.attributes.ignition && b.attributes.fuel)
114
+ const before = (index > 5 ? array.slice(index-6, index-1) : array.slice(0, index-1)).filter(b => b.attributes.ignition && b.attributes.fuel)
120
115
  currentValue = Math.round(before.reduce((a, b) => a + b.attributes.fuel, 0) / before.length )
121
-
122
116
  positionsChecked = 0
123
117
  }
124
118
 
125
119
  if(element.attributes.ignition && refuelingActivated && currentValue) {
126
- //Ignition is on and Refueling is Active and there is a current value
127
- //Calculate the value of the fuel tank level after turning the ignition back on
128
120
  const after = (array.length > index + 5 ? array.slice(index, index+1) : array.slice(index)).filter(b => b.attributes.ignition && b.attributes.fuel)
129
121
  const newValue = Math.round(after.reduce((a, b) => a + b.attributes.fuel, 0) / after.length )
130
122
 
131
123
  const diff = automaticReports.calculateFuelDiff(currentValue, newValue, d)
132
124
  if (diff > 20) {
133
- //New refueling detected
134
125
  const value = Math.round(diff * d.attributes.fuel_tank_capacity / 100)
135
126
  refuelingPositions.push({position: element, diff: value})
136
- lastRefuelingIndex = index
137
127
  positionsChecked = 6 // to reset values
138
128
  }
139
129
 
@@ -1,27 +1,3 @@
1
- function getStyle(partnerData) {
2
- const reportStyleData = {
3
- pdfHeaderColor: [105, 105, 105],
4
- pdfHeaderTextColor: [256, 256, 256],
5
- pdfBodyColor: [256, 256, 256],
6
- pdfBodyTextColor: [30, 30, 30],
7
- pdfFooterColor: [210, 210, 210],
8
- pdfFooterTextColor: [30, 30, 30],
9
- imgHeight: 0,
10
- imgWidth: 0,
11
- }
12
-
13
- if(partnerData && partnerData.reports){
14
- reportStyleData.pdfHeaderColor = partnerData.reports.mainColor || [105, 105, 105]
15
- reportStyleData.pdfFooterColor = partnerData.reports.mainColor || [210, 210, 210]
16
- reportStyleData.pdfFooterTextColor = partnerData.reports.mainColor ? [256, 256, 256] : [30, 30, 30]
17
- reportStyleData.imgHeight = partnerData.reports.logoHeight || 0
18
- reportStyleData.imgWidth = partnerData.reports.logoWidth || 0
19
- }
20
-
21
- return reportStyleData
22
- }
23
-
24
- exports.getStyle = getStyle
25
1
 
26
2
  exports.pdfHeaderColor = [105, 105, 105]
27
3
  exports.pdfHeaderTextColor = [256, 256, 256]
@@ -30,5 +6,3 @@ exports.pdfBodyTextColor = [30, 30, 30]
30
6
  exports.pdfFooterColor = [210, 210, 210]
31
7
  exports.pdfFooterTextColor = [30, 30, 30]
32
8
 
33
-
34
-
@@ -1,150 +1,119 @@
1
+ const automaticReports = require("./automaticReports")
1
2
  const messages = require('../lang')
2
3
  const jsPDF = require('jspdf')
3
- const {convertMS, convertToLocaleString} = require("./util/utils")
4
- const {headerFromUser, AmiriRegular} = require("./util/pdfDocument")
4
+ const {convertMS} = require("./util/utils")
5
5
  require('jspdf-autotable')
6
6
  const { parse } = require('wkt')
7
7
  const turf = require('turf')
8
- const {getStyle} = require("./reportStyle")
8
+ const reportStyle = require("./reportStyle")
9
9
  const drivers = require("./util/driver")
10
10
  const {distance, point} = require('turf')
11
11
  const here = require('./here')
12
- const {getUserPartner} = require("fleetmap-partners");
13
- const traccar = require("./util/traccar");
14
12
 
15
13
  let traccarInstance
16
- let userData
17
14
 
18
15
  const fileName = 'SpeedingReport'
19
- const eventTypes = ['deviceOverspeed']
20
16
 
21
- async function createSpeedingReport(from, to, reportUserData, traccar) {
22
- console.log('Create SpeedingReport')
17
+ async function createSpeedingReport(from, to, userData, traccar, roadSpeedLimits) {
23
18
  traccarInstance = traccar
24
- userData = reportUserData
19
+ console.log('createSpeedingReport', from, to, userData, traccar, roadSpeedLimits)
25
20
  const reportData = []
26
21
 
27
- if (userData.byDriver) {
28
- console.log("ByDriver")
29
- const allData = await createSpeedingReportByDriver(from, to)
22
+ if(userData.byDriver){
23
+ const allData = await createSpeedingReportByDriver(from, to, userData, roadSpeedLimits)
30
24
  reportData.push(allData)
31
25
  }
32
- else if (userData.byGroup) {
26
+ else if(userData.byGroup){
33
27
  console.log("ByGroup")
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
- }
28
+ for (const g of userData.groups) {
29
+ const devices = userData.devices.filter(d => d.groupId === g.id)
30
+ console.log(g.name + ' devices:' + devices.length)
31
+ if(devices.length > 0) {
32
+ const groupData = {
33
+ devices: [],
34
+ group: g,
35
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
36
+ }
56
37
 
57
- const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
58
- const routes = await traccar.getRoute(traccarInstance, from, to, devices)
38
+ const data = await getReportData(from, to, devices)
59
39
 
60
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
40
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
61
41
 
62
- if (events.length > 0) {
63
- groupData.devices = await processDevices(from, to, devices, events, routes)
64
- reportData.push(groupData)
42
+ if (data.length > 0) {
43
+ groupData.devices = await processDevices(from, to, devices, userData.geofences, userData.drivers, data, roadSpeedLimits)
44
+ reportData.push(groupData)
45
+ }
65
46
  }
66
47
  }
67
- }
68
-
69
- const groupIds = userData.groups.map(g => g.id)
70
- const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
71
48
 
72
- const withoutGroupData = await createSpeedingReportByDevice(from, to, withoutGroupDevices)
73
- reportData.push(withoutGroupData)
49
+ const withoutGroupData = await createSpeedingReportByDevice(from, to, userData)
50
+ reportData.push(withoutGroupData)
51
+ } else {
52
+ const allData = await createSpeedingReportByDevice(from, to, userData, roadSpeedLimits)
53
+ reportData.push(allData)
54
+ }
74
55
 
75
56
  return reportData
76
57
  }
77
58
 
78
- async function createSpeedingReportByDevice(from, to, devices) {
79
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
59
+ async function createSpeedingReportByDevice(from, to, userData, roadSpeedLimits) {
60
+ const groupIds = userData.groups.map(g => g.id)
61
+ const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
80
62
 
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
- }
63
+ withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
88
64
 
89
- if(userData.roadSpeedLimits){
90
- events.push(...await getHereEvents(devices, routes, userData.maxSpeedThreshold))
91
- }
65
+ const data = await getReportData(from, to, withoutGroupDevices)
92
66
 
93
- if(!events.length) {
94
- //empty report
95
- return { devices: [] }
96
- }
67
+ const allData = { devices: [] }
97
68
 
98
- return {
99
- devices: await processDevices(from, to, devices, events, routes),
100
- xpert: devices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
69
+ if(data.length > 0 || roadSpeedLimits) {
70
+ allData.devices = await processDevices(from, to, withoutGroupDevices, userData.geofences, userData.drivers, data, roadSpeedLimits)
71
+ allData.xpert = withoutGroupDevices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
101
72
  }
73
+
74
+ return allData
102
75
  }
103
76
 
104
- async function createSpeedingReportByDriver(from, to) {
105
- const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
106
- console.log('Devices with driver',devices.length)
77
+ async function createSpeedingReportByDriver(from, to, userData) {
78
+ const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
79
+ console.log(deviceIds.length)
107
80
 
108
- if(!devices.length) {
109
- //empty report
110
- return { drivers: [] }
81
+ let eventsData = []
82
+ if(deviceIds.length > 0) {
83
+ console.log('getReportData', deviceIds.length)
84
+ const devices = userData.devices.filter(d => deviceIds.includes(d.id))
85
+ eventsData = await getReportData(from, to, devices)
111
86
  }
112
87
 
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))
88
+ const allData = {
89
+ drivers: []
119
90
  }
120
91
 
121
- if(userData.roadSpeedLimits){
122
- events.push(...await getHereEvents(devices, routes, userData.maxSpeedThreshold))
123
- }
92
+ console.log(eventsData.length)
124
93
 
125
- if(!events.length) {
126
- //empty report
127
- return { drivers: [] }
128
- }
94
+ await getEventsPosition(from , to, userData.devices, userData.geofences, userData.drivers, eventsData)
129
95
 
130
- return {drivers: await processDrivers(from, to, events, routes)}
96
+ allData.drivers = await processDrivers(from, to, userData.drivers, eventsData)
97
+ console.log(allData.drivers.length)
98
+ return allData
131
99
  }
132
100
 
133
- async function processDrivers(from, to, events, routes) {
101
+ async function processDrivers(from, to, drivers, data) {
102
+ console.log(data)
134
103
  const driversResult = []
104
+ const alertsWithPosition = data.filter(a => a.position)
105
+
106
+ drivers.forEach(d => {
107
+ const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
135
108
 
136
- await findEventsPosition(from, to, userData.devices, events, routes)
109
+ if (alerts.length > 0) {
137
110
 
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)
142
111
  driversResult.push({
143
112
  driver: d,
144
113
  from: from,
145
114
  to: to,
146
- alerts: driverEvents,
147
- maxSpeed: driverEvents.reduce((a, b) => {
115
+ alerts: alerts,
116
+ maxSpeed: alerts.reduce((a, b) => {
148
117
  return a > b.attributes.maxSpeed ? a : b.attributes.maxSpeed
149
118
  }, 0),
150
119
  })
@@ -154,20 +123,40 @@ async function processDrivers(from, to, events, routes) {
154
123
  return driversResult
155
124
  }
156
125
 
157
- async function processDevices(from, to, devices, events, routes) {
126
+ async function getReportData(from, to, devices) {
127
+ const types = ['deviceOverspeed']
128
+ let data = []
129
+ const arrayOfArrays = automaticReports.sliceArray(devices)
130
+ for (const a of arrayOfArrays) {
131
+ try {
132
+ const devices = a.map(d => d.id)
133
+ console.log('reportsEventsGet', from, to, devices, null, types)
134
+ const response = await traccarInstance.reports.reportsEventsGet(from, to, devices, null, types)
135
+ data = data.concat(response.data)
136
+ } catch (e) {
137
+ console.error(e)
138
+ }
139
+ }
140
+ console.log('Alerts:', data.length)
141
+ return data
142
+ }
143
+
144
+ async function processDevices(from, to, devices, geofences, drivers, data, roadSpeedLimits) {
158
145
  const devicesResult = []
159
- await findEventsPosition(from, to, devices, events, routes)
146
+
147
+ await getEventsPosition(from , to, devices, geofences, drivers, data, roadSpeedLimits)
160
148
 
161
149
  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)
150
+ const alerts = data.filter(t => t.deviceId === d.id)
151
+
152
+ if (alerts.length > 0) {
153
+ const alertsWithPosition = alerts.filter(a => a.position).sort((a,b) => a.positionId - b.positionId)
165
154
  devicesResult.push({
166
155
  device: d,
167
156
  from: from,
168
157
  to: to,
169
- alerts: deviceEvents,
170
- maxSpeed: deviceEvents.reduce((a, b) => {
158
+ alerts: alertsWithPosition,
159
+ maxSpeed: alertsWithPosition.reduce((a, b) => {
171
160
  return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
172
161
  }, 0),
173
162
  })
@@ -177,136 +166,93 @@ async function processDevices(from, to, devices, events, routes) {
177
166
  return devicesResult
178
167
  }
179
168
 
180
- async function findEventsPosition(from, to, devices, events, routes){
169
+ async function getEventsPosition(from, to, devices, geofences, drivers, data, roadSpeedLimits){
181
170
  for (const d of devices) {
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)
186
171
 
187
- for (const a of deviceEvents) {
172
+ let alerts = data.filter(t => t.deviceId === d.id)
173
+
174
+ if (alerts.length > 0 || roadSpeedLimits) {
175
+ const response = await traccarInstance.reports.reportsRouteGet(from, to, [d.id])
176
+ const positions = response.data
177
+
178
+ if (roadSpeedLimits && positions.length) {
179
+ try {
180
+ await new Promise(res => setTimeout(res, 1000))
181
+ const results = await here.routeMatch(positions)
182
+ const hereAlerts = results.map(r => {
183
+ const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
184
+ return {
185
+ ...r,
186
+ roadSpeedLimit: r.speedLimit,
187
+ deviceId: d.id,
188
+ position,
189
+ positionId: position && position.id,
190
+ attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
191
+ }
192
+ })
193
+ console.log('hereAlerts', hereAlerts)
194
+ const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
195
+ if (idx === 1) {
196
+ return [cur]
197
+ }
198
+ if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
199
+ return acc.concat(cur)
200
+ }
201
+ return acc
202
+ })
203
+ data.push(...reduced)
204
+ alerts = data.filter(t => t.deviceId === d.id)
205
+ } catch (e) {
206
+ console.error(e)
207
+ }
208
+ }
209
+
210
+ for (const a of alerts) {
188
211
  let pIndex = positions.findIndex(p => p.id === a.positionId)
189
212
  if (pIndex > 0) {
213
+ a.position = positions[pIndex]
190
214
  let geofence = null
215
+
191
216
  if (a.geofenceId) {
192
- geofence = userData.geofences.find(g => g.id === a.geofenceId)
217
+ geofence = geofences.find(g => g.id === a.geofenceId)
193
218
  if (geofence) {
194
219
  a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
195
220
  }
196
221
  }
197
222
 
198
- a.position = positions[pIndex]
199
- pIndex = calculateEventData(positions, pIndex, a, d, geofence)
200
- positions.slice(pIndex)
201
- }
202
- }
203
- }
204
- }
205
- }
206
-
207
- async function getCustomSpeedLimitEvents(devices, routes){
208
- console.log('custom speed limit events')
209
- const events = []
210
- const maxSpeed = userData.customSpeed / 1.85200
211
-
212
- for (const d of devices) {
213
- const positions = routes.filter(p => p.deviceId === d.id)
214
- let eventIsActive = false
215
-
216
- for (const position of positions) {
217
- if(position.speed > maxSpeed && !eventIsActive){
218
- const event = {
219
- positionId: position && position.id,
220
- deviceId: d.id,
221
- attributes: {
222
- speedLimit: maxSpeed,
223
- speed: position.speed
223
+ let endEventPosition = a.position
224
+ let maxSpeed = a.position.speed
225
+ let dist = 0
226
+ while (pIndex + 1 < positions.length) {
227
+ pIndex++
228
+
229
+ dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
230
+ point([positions[pIndex].longitude, positions[pIndex].latitude]))
231
+ endEventPosition = positions[pIndex]
232
+ if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
233
+ a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
234
+ a.attributes.maxSpeed = maxSpeed
235
+ a.distance = dist
236
+ break
237
+ } else {
238
+ if (maxSpeed < endEventPosition.speed) {
239
+ maxSpeed = endEventPosition.speed
240
+ }
241
+ }
224
242
  }
225
- }
226
- events.push(event)
227
- eventIsActive = true
228
- } else if (position.speed <= maxSpeed) {
229
- eventIsActive = false
230
- }
231
- }
232
- }
233
243
 
234
- return events
235
- }
244
+ if (a.position.attributes.driverUniqueId) {
245
+ const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
246
+ a.driver = driver && driver.name
247
+ }
236
248
 
237
- async function getHereEvents(devices, routes, threshold){
238
- console.log('here speed limit events')
239
- const events = []
240
- let i,j, temporary, chunk = 1;
241
- for (i = 0,j = devices.length; i < j; i += chunk) {
242
- temporary = devices.slice(i, i + chunk);
243
- await Promise.all(temporary.map(d =>
244
- here.routeMatch(routes.filter(p => p.deviceId === d.id)).then(r => d.results = r)
245
- ))
246
- }
249
+ a.deviceName = d.name
247
250
 
248
- for (const d of devices) {
249
- try {
250
- const results = d.results
251
- const hereAlerts = results.filter(r => r.currentSpeedKmh > (parseInt(r.speedLimit) + threshold)).map(r => {
252
- const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
253
- return {
254
- ...r,
255
- roadSpeedLimit: r.speedLimit,
256
- deviceId: d.id,
257
- position,
258
- positionId: position && position.id,
259
- attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
260
- }
261
- })
262
- const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
263
- if (idx === 1) {
264
- return [cur]
265
- }
266
- if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
267
- return acc.concat(cur)
251
+ positions.slice(pIndex)
268
252
  }
269
- return acc
270
- })
271
- events.push(...reduced)
272
- } catch (e) {
273
- console.error(e)
274
- }
275
- }
276
- return events
277
- }
278
-
279
- function calculateEventData(positions, pIndex, alert, device, geofence){
280
- let endEventPosition = alert.position
281
- let maxSpeed = alert.position.speed
282
- let dist = 0
283
- while (pIndex + 1 < positions.length) {
284
- pIndex++
285
-
286
- dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
287
- point([positions[pIndex].longitude, positions[pIndex].latitude]))
288
- endEventPosition = positions[pIndex]
289
- if (endEventPosition.speed <= alert.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
290
- alert.eventTime = new Date(endEventPosition.fixTime) - new Date(alert.position.fixTime)
291
- alert.attributes.maxSpeed = maxSpeed
292
- alert.distance = dist
293
- break
294
- } else {
295
- if (maxSpeed < endEventPosition.speed) {
296
- maxSpeed = endEventPosition.speed
297
253
  }
298
254
  }
299
255
  }
300
-
301
-
302
- if (alert.position.attributes.driverUniqueId) {
303
- const driver = userData.drivers.find(d => d.uniqueId === alert.position.attributes.driverUniqueId)
304
- alert.driver = driver && driver.name
305
- }
306
-
307
- alert.deviceName = device.name
308
-
309
- return pIndex
310
256
  }
311
257
 
312
258
  function isOutsideGeofence(geofence, endEventPosition) {
@@ -315,11 +261,10 @@ function isOutsideGeofence(geofence, endEventPosition) {
315
261
  return turf.inside(point, v)
316
262
  }
317
263
 
318
- async function exportSpeedingReportToPDF(userData, reportData) {
264
+ function exportSpeedingReportToPDF(userData, reportData) {
319
265
  console.log('Export to PDF')
320
266
 
321
267
  const lang = userData.user.attributes.lang
322
- const timezone = userData.user.attributes.timezone
323
268
  const translations = messages[lang] ? messages[lang] : messages['en-GB']
324
269
 
325
270
  const overspeedData = userData.byDriver ? reportData.drivers : reportData.devices
@@ -333,7 +278,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
333
278
  translations.report.duration,
334
279
  ]
335
280
 
336
- if(userData.roadSpeedLimits) {
281
+ if(userData.useRoadSpeedLimits) {
337
282
  headers.splice(2, 0, translations.report.roadSpeedLimit)
338
283
  }
339
284
 
@@ -346,7 +291,8 @@ async function exportSpeedingReportToPDF(userData, reportData) {
346
291
  if (overspeedData) {
347
292
  let first = true
348
293
  const doc = new jsPDF.jsPDF('l');
349
- await headerFromUser(doc, translations.report.titleSpeedingReport, userData.user)
294
+ doc.setFontSize(14)
295
+ doc.text(translations.report.titleSpeedingReport, 15, 15 )
350
296
 
351
297
  overspeedData.forEach(d => {
352
298
  try {
@@ -362,13 +308,13 @@ async function exportSpeedingReportToPDF(userData, reportData) {
362
308
  first = false
363
309
  space = 10
364
310
  }
365
- doc.setFontSize(13)
311
+ doc.setFontSize(12)
366
312
  doc.text(name, 20, space+20 )
367
- doc.setFontSize(11)
313
+ doc.setFontSize(10)
368
314
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
369
- doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
315
+ doc.text(new Date(d.from).toLocaleString() + ' - ' + new Date(d.to).toLocaleString(), 20, space+25 )
370
316
  if (d.alerts[0] && !userData.byDriver) {
371
- 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)
317
+ doc.text(translations.report.speedLimit + ": " + Math.round(d.alerts[0].attributes.speedLimit * 1.85200) + ' Km/h', 20, space + 30)
372
318
  }
373
319
  d.alerts.map(a => {
374
320
  const temp = [
@@ -381,7 +327,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
381
327
  userData.byDriver ? a.deviceName : a.driver
382
328
  ]
383
329
 
384
- if(userData.roadSpeedLimits){
330
+ if(userData.useRoadSpeedLimits){
385
331
  temp.splice(2, 0, a.roadSpeedLimit)
386
332
  }
387
333
 
@@ -397,34 +343,26 @@ async function exportSpeedingReportToPDF(userData, reportData) {
397
343
  convertMS(d.alerts.reduce((a, b) => a + b.eventTime, 0), true)
398
344
  ]
399
345
 
400
- if(userData.roadSpeedLimits){
346
+ if(userData.useRoadSpeedLimits){
401
347
  footValues.splice(2, 0, '')
402
348
  }
403
349
 
404
- doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
405
- doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
406
-
407
- const style = getStyle(getUserPartner(userData.user))
408
350
  doc.autoTable({
409
351
  head: [headers],
410
352
  body: data,
411
353
  foot: [footValues],
412
354
  showFoot: 'lastPage',
413
355
  headStyles: {
414
- fillColor: style.pdfHeaderColor,
415
- textColor: style.pdfHeaderTextColor,
416
- fontSize: 10
356
+ fillColor: reportStyle.pdfHeaderColor,
357
+ textColor: reportStyle.pdfHeaderTextColor
417
358
  },
418
359
  bodyStyles: {
419
- fillColor: style.pdfBodyColor,
420
- textColor: style.pdfBodyTextColor,
421
- fontSize: 8,
422
- font: timezone === 'Asia/Qatar' ? "Amiri" : ''
360
+ fillColor: reportStyle.pdfBodyColor,
361
+ textColor: reportStyle.pdfBodyTextColor
423
362
  },
424
363
  footStyles: {
425
- fillColor: style.pdfFooterColor,
426
- textColor: style.pdfFooterTextColor,
427
- fontSize: 9
364
+ fillColor: reportStyle.pdfFooterColor,
365
+ textColor: reportStyle.pdfFooterTextColor
428
366
  },
429
367
  startY: space+35 });
430
368
  } catch (e) {
@@ -460,7 +398,7 @@ function exportSpeedingReportToExcel(userData, reportData) {
460
398
  userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
461
399
  ]
462
400
 
463
- if (userData.roadSpeedLimits){
401
+ if (userData.useRoadSpeedLimits){
464
402
  headers.splice(3, 0, {label: translations.report.roadSpeedLimit, value:'roadSpeedLimit'})
465
403
  }
466
404
 
@@ -496,7 +434,10 @@ function deviceName(device){
496
434
  }
497
435
 
498
436
  function getAlertDate(row, user) {
499
- return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
437
+ return new Date(row.position.fixTime).toLocaleString(user.attributes.lang, {
438
+ timeZone: user.attributes.timezone,
439
+ hour12: false
440
+ })
500
441
  }
501
442
 
502
443
  function getMaxSpeed(data) {