fleetmap-reports 1.0.287 → 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
48
 
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)
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)
135
105
 
136
- await findEventsPosition(from, to, userData.devices, events, routes)
106
+ drivers.forEach(d => {
107
+ const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
108
+
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,129 +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
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
+ }
242
+ }
211
243
 
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
244
+ if (a.position.attributes.driverUniqueId) {
245
+ const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
246
+ a.driver = driver && driver.name
224
247
  }
225
- }
226
- events.push(event)
227
- eventIsActive = true
228
- } else if (position.speed <= maxSpeed) {
229
- eventIsActive = false
230
- }
231
- }
232
- }
233
248
 
234
- return events
235
- }
249
+ a.deviceName = d.name
236
250
 
237
- async function getHereEvents(devices, routes, threshold){
238
- console.log('here speed limit events')
239
- const events = []
240
- for (const d of devices) {
241
- const positions = routes.filter(p => p.deviceId === d.id)
242
- try {
243
- const results = await here.routeMatch(positions)
244
- const hereAlerts = results.filter(r => r.currentSpeedKmh > (parseInt(r.speedLimit) + threshold)).map(r => {
245
- const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
246
- return {
247
- ...r,
248
- roadSpeedLimit: r.speedLimit,
249
- deviceId: d.id,
250
- position,
251
- positionId: position && position.id,
252
- attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
253
- }
254
- })
255
- const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
256
- if (idx === 1) {
257
- return [cur]
258
- }
259
- if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
260
- return acc.concat(cur)
251
+ positions.slice(pIndex)
261
252
  }
262
- return acc
263
- })
264
- events.push(...reduced)
265
- } catch (e) {
266
- console.error(e)
267
- }
268
- }
269
- return events
270
- }
271
-
272
- function calculateEventData(positions, pIndex, alert, device, geofence){
273
- let endEventPosition = alert.position
274
- let maxSpeed = alert.position.speed
275
- let dist = 0
276
- while (pIndex + 1 < positions.length) {
277
- pIndex++
278
-
279
- dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
280
- point([positions[pIndex].longitude, positions[pIndex].latitude]))
281
- endEventPosition = positions[pIndex]
282
- if (endEventPosition.speed <= alert.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
283
- alert.eventTime = new Date(endEventPosition.fixTime) - new Date(alert.position.fixTime)
284
- alert.attributes.maxSpeed = maxSpeed
285
- alert.distance = dist
286
- break
287
- } else {
288
- if (maxSpeed < endEventPosition.speed) {
289
- maxSpeed = endEventPosition.speed
290
253
  }
291
254
  }
292
255
  }
293
-
294
-
295
- if (alert.position.attributes.driverUniqueId) {
296
- const driver = userData.drivers.find(d => d.uniqueId === alert.position.attributes.driverUniqueId)
297
- alert.driver = driver && driver.name
298
- }
299
-
300
- alert.deviceName = device.name
301
-
302
- return pIndex
303
256
  }
304
257
 
305
258
  function isOutsideGeofence(geofence, endEventPosition) {
@@ -308,11 +261,10 @@ function isOutsideGeofence(geofence, endEventPosition) {
308
261
  return turf.inside(point, v)
309
262
  }
310
263
 
311
- async function exportSpeedingReportToPDF(userData, reportData) {
264
+ function exportSpeedingReportToPDF(userData, reportData) {
312
265
  console.log('Export to PDF')
313
266
 
314
267
  const lang = userData.user.attributes.lang
315
- const timezone = userData.user.attributes.timezone
316
268
  const translations = messages[lang] ? messages[lang] : messages['en-GB']
317
269
 
318
270
  const overspeedData = userData.byDriver ? reportData.drivers : reportData.devices
@@ -326,7 +278,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
326
278
  translations.report.duration,
327
279
  ]
328
280
 
329
- if(userData.roadSpeedLimits) {
281
+ if(userData.useRoadSpeedLimits) {
330
282
  headers.splice(2, 0, translations.report.roadSpeedLimit)
331
283
  }
332
284
 
@@ -339,7 +291,8 @@ async function exportSpeedingReportToPDF(userData, reportData) {
339
291
  if (overspeedData) {
340
292
  let first = true
341
293
  const doc = new jsPDF.jsPDF('l');
342
- await headerFromUser(doc, translations.report.titleSpeedingReport, userData.user)
294
+ doc.setFontSize(14)
295
+ doc.text(translations.report.titleSpeedingReport, 15, 15 )
343
296
 
344
297
  overspeedData.forEach(d => {
345
298
  try {
@@ -355,13 +308,13 @@ async function exportSpeedingReportToPDF(userData, reportData) {
355
308
  first = false
356
309
  space = 10
357
310
  }
358
- doc.setFontSize(13)
311
+ doc.setFontSize(12)
359
312
  doc.text(name, 20, space+20 )
360
- doc.setFontSize(11)
313
+ doc.setFontSize(10)
361
314
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
362
- 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 )
363
316
  if (d.alerts[0] && !userData.byDriver) {
364
- 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)
365
318
  }
366
319
  d.alerts.map(a => {
367
320
  const temp = [
@@ -374,7 +327,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
374
327
  userData.byDriver ? a.deviceName : a.driver
375
328
  ]
376
329
 
377
- if(userData.roadSpeedLimits){
330
+ if(userData.useRoadSpeedLimits){
378
331
  temp.splice(2, 0, a.roadSpeedLimit)
379
332
  }
380
333
 
@@ -390,34 +343,26 @@ async function exportSpeedingReportToPDF(userData, reportData) {
390
343
  convertMS(d.alerts.reduce((a, b) => a + b.eventTime, 0), true)
391
344
  ]
392
345
 
393
- if(userData.roadSpeedLimits){
346
+ if(userData.useRoadSpeedLimits){
394
347
  footValues.splice(2, 0, '')
395
348
  }
396
349
 
397
- doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
398
- doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
399
-
400
- const style = getStyle(getUserPartner(userData.user))
401
350
  doc.autoTable({
402
351
  head: [headers],
403
352
  body: data,
404
353
  foot: [footValues],
405
354
  showFoot: 'lastPage',
406
355
  headStyles: {
407
- fillColor: style.pdfHeaderColor,
408
- textColor: style.pdfHeaderTextColor,
409
- fontSize: 10
356
+ fillColor: reportStyle.pdfHeaderColor,
357
+ textColor: reportStyle.pdfHeaderTextColor
410
358
  },
411
359
  bodyStyles: {
412
- fillColor: style.pdfBodyColor,
413
- textColor: style.pdfBodyTextColor,
414
- fontSize: 8,
415
- font: timezone === 'Asia/Qatar' ? "Amiri" : ''
360
+ fillColor: reportStyle.pdfBodyColor,
361
+ textColor: reportStyle.pdfBodyTextColor
416
362
  },
417
363
  footStyles: {
418
- fillColor: style.pdfFooterColor,
419
- textColor: style.pdfFooterTextColor,
420
- fontSize: 9
364
+ fillColor: reportStyle.pdfFooterColor,
365
+ textColor: reportStyle.pdfFooterTextColor
421
366
  },
422
367
  startY: space+35 });
423
368
  } catch (e) {
@@ -453,7 +398,7 @@ function exportSpeedingReportToExcel(userData, reportData) {
453
398
  userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
454
399
  ]
455
400
 
456
- if (userData.roadSpeedLimits){
401
+ if (userData.useRoadSpeedLimits){
457
402
  headers.splice(3, 0, {label: translations.report.roadSpeedLimit, value:'roadSpeedLimit'})
458
403
  }
459
404
 
@@ -489,7 +434,10 @@ function deviceName(device){
489
434
  }
490
435
 
491
436
  function getAlertDate(row, user) {
492
- 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
+ })
493
441
  }
494
442
 
495
443
  function getMaxSpeed(data) {