fleetmap-reports 1.0.439 → 1.0.440

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/events-report.js +234 -232
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.439",
3
+ "version": "1.0.440",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,273 +1,275 @@
1
- const automaticReports = require("./automaticReports")
1
+ const automaticReports = require('./automaticReports')
2
2
  const jsPDF = require('jspdf')
3
3
  require('jspdf-autotable')
4
- const {getStyle} = require("./reportStyle");
5
- const {headerFromUser} = require("./util/pdfDocument");
6
- const {getUserPartner} = require("fleetmap-partners");
7
- const {convertToLocaleString, getTranslations} = require("./util/utils");
8
- const {devicesToProcess} = require("./util/device");
4
+ const { getStyle } = require('./reportStyle')
5
+ const { headerFromUser } = require('./util/pdfDocument')
6
+ const { getUserPartner } = require('fleetmap-partners')
7
+ const { convertToLocaleString, getTranslations } = require('./util/utils')
8
+ const { devicesToProcess } = require('./util/device')
9
9
 
10
10
  const fileName = 'EventReport'
11
11
 
12
- async function createEventsReport(from, to, userData, traccar) {
13
- console.log('Create EventsReport')
14
- const reportData = []
15
-
16
- if(userData.byGroup){
17
- console.log("ByGroup")
18
- for (const g of userData.groups) {
19
- const devices = userData.devices.filter(d => d.groupId === g.id)
20
- console.log(g.name + ' devices:' + devices.length)
21
- if(devices.length > 0) {
22
- const groupData = {
23
- devices: [],
24
- group: g,
25
- xpert: devices.filter(d => d.attributes.xpert).length > 0
26
- }
27
-
28
- const data = await getReportData(from, to, devices, userData.eventTypes, traccar)
29
-
30
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
31
-
32
- if (data.length > 0) {
33
- groupData.devices = await processDevices(from, to, devices, userData.geofences, userData.drivers, data)
34
- reportData.push(groupData)
35
- }
36
- }
12
+ async function createEventsReport (from, to, userData, traccar) {
13
+ console.log('Create EventsReport')
14
+ const reportData = []
15
+
16
+ if (userData.byGroup) {
17
+ console.log('ByGroup')
18
+ for (const g of userData.groups) {
19
+ const devices = userData.devices.filter(d => d.groupId === g.id)
20
+ console.log(g.name + ' devices:' + devices.length)
21
+ if (devices.length > 0) {
22
+ const groupData = {
23
+ devices: [],
24
+ group: g,
25
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
37
26
  }
38
- }
39
-
40
- const devices = devicesToProcess(userData)
41
27
 
42
- const data = await getReportData(from, to, devices, userData.eventTypes, traccar)
28
+ const data = await getReportData(from, to, devices, userData.eventTypes, traccar)
43
29
 
44
- if(data.length > 0) {
45
- reportData.push({
46
- devices: await processDevices(from, to, devices, userData.geofences, userData.drivers, data, traccar),
47
- xpert: devices.filter(d => d.attributes.xpert).length > 0
48
- })
49
- }
50
-
51
- return reportData
52
- }
30
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
53
31
 
54
- async function getReportData(from, to, devices, types, traccar) {
55
- let data = []
56
- const arrayOfArrays = automaticReports.sliceArray(devices)
57
- const traccarTypes = new Set(types.map(t => t.startsWith('alarm') ? 'alarm' : t))
58
- const traccarSubTypes = types.map(t => t.startsWith('alarm') ? t.replace('alarm_', '') : '').filter(Boolean)
59
- for (const a of arrayOfArrays) {
60
- const response = await traccar.reports.reportsEventsGet(from, to, a.map(d => d.id), null, traccarTypes)
61
- if(types.length > 0) {
62
- data = data.concat(response.data.filter(e => e.type === 'alarm' ? traccarSubTypes.includes(e.attributes.alarm) : true))
63
- } else {
64
- data = data.concat(response.data)
32
+ if (data.length > 0) {
33
+ groupData.devices = await processDevices(from, to, devices, userData.geofences, userData.drivers, data)
34
+ reportData.push(groupData)
65
35
  }
36
+ }
66
37
  }
67
- console.log('Alerts:'+data.length)
68
- return data
69
- }
70
-
71
- async function processDevices(from, to, devices, geofences, drivers, data, traccar) {
72
- const devicesResult = []
38
+ }
73
39
 
74
- for (const d of devices) {
75
- const alerts = data.filter(t => t.deviceId === d.id)
40
+ const devices = devicesToProcess(userData)
76
41
 
77
- if (alerts.length > 0) {
78
- const response = await traccar.reports.reportsRouteGet(from, to, [d.id])
79
- const positions = response.data
42
+ const data = await getReportData(from, to, devices, userData.eventTypes, traccar)
80
43
 
81
- for (const a of alerts) {
82
- a.position = positions.find(p => p.id === a.positionId)
44
+ if (data.length > 0) {
45
+ reportData.push({
46
+ devices: await processDevices(from, to, devices, userData.geofences, userData.drivers, data, traccar),
47
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
48
+ })
49
+ }
83
50
 
84
- if (a.geofenceId) {
85
- const geofence = geofences.find(g => g.id === a.geofenceId)
86
- if (geofence) {
87
- if(a.type === 'deviceOverspeed'){
88
- a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
89
- } else {
90
- a.geofenceName = geofence.name
91
- }
51
+ return reportData
52
+ }
92
53
 
93
- }
94
- }
54
+ async function getReportData (from, to, devices, types, traccar) {
55
+ let data = []
56
+ const arrayOfArrays = automaticReports.sliceArray(devices)
57
+ const traccarTypes = new Set(types.map(t => t.startsWith('alarm') ? 'alarm' : t))
58
+ const traccarSubTypes = types.map(t => t.startsWith('alarm') ? t.replace('alarm_', '') : '').filter(Boolean)
59
+ for (const a of arrayOfArrays) {
60
+ const response = await traccar.reports.reportsEventsGet(from, to, a.map(d => d.id), null, traccarTypes)
61
+ if (types.length > 0) {
62
+ data = data.concat(response.data.filter(e => e.type === 'alarm' ? traccarSubTypes.includes(e.attributes.alarm) : true))
63
+ } else {
64
+ data = data.concat(response.data)
65
+ }
66
+ }
67
+ console.log('Alerts:' + data.length)
68
+ return data
69
+ }
95
70
 
96
- if (a.position && a.position.attributes.driverUniqueId) {
97
- const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
98
- a.driver = driver && driver.name
99
- }
71
+ async function processDevices (from, to, devices, geofences, drivers, data, traccar) {
72
+ const devicesResult = []
73
+ let i = 0
74
+ for (const d of devices) {
75
+ console.log('LOADING_MESSAGE:' + d.name)
76
+ console.log(`PROGRESS_PERC:${++i / devices.length * 100}`)
77
+ const alerts = data.filter(t => t.deviceId === d.id)
78
+
79
+ if (alerts.length > 0) {
80
+ const response = await traccar.reports.reportsRouteGet(from, to, [d.id])
81
+ const positions = response.data
82
+
83
+ for (const a of alerts) {
84
+ a.position = positions.find(p => p.id === a.positionId)
85
+
86
+ if (a.geofenceId) {
87
+ const geofence = geofences.find(g => g.id === a.geofenceId)
88
+ if (geofence) {
89
+ if (a.type === 'deviceOverspeed') {
90
+ a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
91
+ } else {
92
+ a.geofenceName = geofence.name
100
93
  }
94
+ }
95
+ }
101
96
 
102
- devicesResult.push({
103
- device: d,
104
- from: from,
105
- to: to,
106
- alerts: alerts
107
- })
97
+ if (a.position && a.position.attributes.driverUniqueId) {
98
+ const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
99
+ a.driver = driver && driver.name
108
100
  }
101
+ }
102
+
103
+ devicesResult.push({
104
+ device: d,
105
+ from,
106
+ to,
107
+ alerts
108
+ })
109
109
  }
110
+ }
110
111
 
111
- return devicesResult
112
+ return devicesResult
112
113
  }
113
114
 
114
- async function exportSpeedingReportToPDF(userData, reportData) {
115
- console.log('Export to PDF')
116
- const lang = userData.user.attributes.lang || (navigator && navigator.language)
117
- const translations = getTranslations(userData)
118
- const timezone = userData.user.attributes.timezone
119
-
120
- const headers = [
121
- translations.report.eventType,
122
- translations.report.date,
123
- translations.report.address,
124
- translations.report.info
125
- ]
126
- if (reportData.devices) {
127
- let first = true
128
- const doc = new jsPDF.jsPDF('l');
129
- await headerFromUser(doc, translations.report.titleEventsReport, userData.user)
130
-
131
- reportData.devices.forEach(d => {
132
- let data = []
133
- const name = deviceName(d.device)
134
- const group = deviceGroupName(translations, userData.groups, d.device)
135
-
136
- let space = 0
137
- if(!first) {
138
- doc.addPage()
139
- } else {
140
- first = false
141
- space = 10
142
- }
143
- doc.setFontSize(13)
144
- doc.text(name, 20, space+20 )
145
- doc.setFontSize(11)
146
- doc.text(group, 200, space+20 )
147
- doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
148
-
149
- doc.autoTable(['','','','',''], [
150
- [translations.report.event_ignitionOn,translations.report.event_ignitionOff, translations.report.event_geofenceEnter,
151
- translations.report.event_geofenceExit, translations.report.event_deviceOverspeed],
152
- [d.alerts.filter(a => a.type === 'ignitionOn').length,d.alerts.filter(a => a.type === 'ignitionOff').length,
153
- d.alerts.filter(a => a.type === 'geofenceEnter').length,d.alerts.filter(a => a.type === 'geofenceExit').length,
154
- d.alerts.filter(a => a.type === 'deviceOverspeed').length],
155
- [translations.report.event_driverChanged,translations.report.event_powerOn, translations.report.event_sos,
156
- translations.report.event_deviceFuelDrop, translations.report.eve],
157
- [d.alerts.filter(a => a.type === 'driverChanged').length,d.alerts.filter(a => a.type === 'powerOn').length,
158
- d.alerts.filter(a => a.type === 'sos').length,d.alerts.filter(a => a.type === 'deviceFuelDrop').length,
159
- d.alerts.filter(a => a.type === 'powerCut').length]
160
- ], { startY: space+30 , showHead: false, bodyStyles: { fillColor: [256, 256, 256], textColor: [30, 30, 30], halign: 'center', valign: 'middle' } , alternateRowStyles: {fillColor: [256, 256, 256], valign: 'bottom'}});
161
-
162
- d.alerts.map(a => {
163
- const temp = [
164
- a.type === 'alarm' ? translations.report['event_'+a.attributes.alarm] : translations.report['event_'+a.type],
165
- getAlertDate(userData.user, a),
166
- a.geofenceName || (a.position ? a.position.address : ''),
167
- getAlertInfo(userData.drivers, a)
168
- ]
169
- data.push(temp)
170
- })
171
-
172
- const footValues = [
173
- 'Total:' + d.alerts.length,
174
- '','',''
175
- ]
176
-
177
- const style = getStyle(getUserPartner(userData.user))
178
- doc.autoTable({
179
- head: [headers],
180
- body: data,
181
- foot: [footValues],
182
- showFoot: 'lastPage',
183
- headStyles: {
184
- fillColor: style.pdfHeaderColor,
185
- textColor: style.pdfHeaderTextColor,
186
- fontSize: 10
187
- },
188
- bodyStyles: {
189
- fillColor: style.pdfBodyColor,
190
- textColor: style.pdfBodyTextColor,
191
- fontSize: 8
192
- },
193
- footStyles: {
194
- fillColor: style.pdfFooterColor,
195
- textColor: style.pdfFooterTextColor,
196
- fontSize: 9
197
- },
198
- startY: space + 65
199
- })
200
- })
201
- return doc
202
- }
115
+ async function exportSpeedingReportToPDF (userData, reportData) {
116
+ console.log('Export to PDF')
117
+ const lang = userData.user.attributes.lang || (navigator && navigator.language)
118
+ const translations = getTranslations(userData)
119
+ const timezone = userData.user.attributes.timezone
120
+
121
+ const headers = [
122
+ translations.report.eventType,
123
+ translations.report.date,
124
+ translations.report.address,
125
+ translations.report.info
126
+ ]
127
+ if (reportData.devices) {
128
+ let first = true
129
+ // eslint-disable-next-line new-cap
130
+ const doc = new jsPDF.jsPDF('l')
131
+ await headerFromUser(doc, translations.report.titleEventsReport, userData.user)
132
+
133
+ reportData.devices.forEach(d => {
134
+ const data = []
135
+ const name = deviceName(d.device)
136
+ const group = deviceGroupName(translations, userData.groups, d.device)
137
+
138
+ let space = 0
139
+ if (!first) {
140
+ doc.addPage()
141
+ } else {
142
+ first = false
143
+ space = 10
144
+ }
145
+ doc.setFontSize(13)
146
+ doc.text(name, 20, space + 20)
147
+ doc.setFontSize(11)
148
+ doc.text(group, 200, space + 20)
149
+ doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space + 25)
150
+
151
+ doc.autoTable(['', '', '', '', ''], [
152
+ [translations.report.event_ignitionOn, translations.report.event_ignitionOff, translations.report.event_geofenceEnter,
153
+ translations.report.event_geofenceExit, translations.report.event_deviceOverspeed],
154
+ [d.alerts.filter(a => a.type === 'ignitionOn').length, d.alerts.filter(a => a.type === 'ignitionOff').length,
155
+ d.alerts.filter(a => a.type === 'geofenceEnter').length, d.alerts.filter(a => a.type === 'geofenceExit').length,
156
+ d.alerts.filter(a => a.type === 'deviceOverspeed').length],
157
+ [translations.report.event_driverChanged, translations.report.event_powerOn, translations.report.event_sos,
158
+ translations.report.event_deviceFuelDrop, translations.report.eve],
159
+ [d.alerts.filter(a => a.type === 'driverChanged').length, d.alerts.filter(a => a.type === 'powerOn').length,
160
+ d.alerts.filter(a => a.type === 'sos').length, d.alerts.filter(a => a.type === 'deviceFuelDrop').length,
161
+ d.alerts.filter(a => a.type === 'powerCut').length]
162
+ ], { startY: space + 30, showHead: false, bodyStyles: { fillColor: [256, 256, 256], textColor: [30, 30, 30], halign: 'center', valign: 'middle' }, alternateRowStyles: { fillColor: [256, 256, 256], valign: 'bottom' } })
163
+
164
+ d.alerts.forEach(a => {
165
+ const temp = [
166
+ a.type === 'alarm' ? translations.report['event_' + a.attributes.alarm] : translations.report['event_' + a.type],
167
+ getAlertDate(userData.user, a),
168
+ a.geofenceName || (a.position ? a.position.address : ''),
169
+ getAlertInfo(userData.drivers, a)
170
+ ]
171
+ data.push(temp)
172
+ })
173
+
174
+ const footValues = [
175
+ 'Total:' + d.alerts.length,
176
+ '', '', ''
177
+ ]
178
+
179
+ const style = getStyle(getUserPartner(userData.user))
180
+ doc.autoTable({
181
+ head: [headers],
182
+ body: data,
183
+ foot: [footValues],
184
+ showFoot: 'lastPage',
185
+ headStyles: {
186
+ fillColor: style.pdfHeaderColor,
187
+ textColor: style.pdfHeaderTextColor,
188
+ fontSize: 10
189
+ },
190
+ bodyStyles: {
191
+ fillColor: style.pdfBodyColor,
192
+ textColor: style.pdfBodyTextColor,
193
+ fontSize: 8
194
+ },
195
+ footStyles: {
196
+ fillColor: style.pdfFooterColor,
197
+ textColor: style.pdfFooterTextColor,
198
+ fontSize: 9
199
+ },
200
+ startY: space + 65
201
+ })
202
+ })
203
+ return doc
204
+ }
203
205
  }
204
206
 
205
- function exportSpeedingReportToExcel(userData, reportData) {
206
- console.log('exportSpeedingReportToExcel')
207
-
208
- const translations = getTranslations(userData)
209
-
210
- const settings = {
211
- sheetName: translations.report.titleEventsReport, // The name of the sheet
212
- fileName: fileName, // The name of the spreadsheet
213
- }
214
- const headers = [
215
- {label: translations.report.vehicle, value:'name'},
216
- {label: translations.report.eventType, value:'eventType'},
217
- {label: translations.report.date, value:'fixTime'},
218
- {label: translations.report.address, value:'address'},
219
- {label: translations.report.info, value:'info'}
220
- ]
221
- let data = []
222
- if (reportData.devices) {
223
- reportData.devices.forEach(d => {
224
- data = data.concat(d.alerts.map(a => {
225
- return {
226
- name: d.device.name,
227
- eventType: a.type === 'alarm' ? translations.report['event_'+a.attributes.alarm] : translations.report['event_'+a.type],
228
- fixTime: getAlertDate(userData.user, a),
229
- address: a.geofenceName || (a.position ? a.position.address : ''),
230
- info: getAlertInfo(userData.drivers, a)
231
- }
232
- }))
233
- })
207
+ function exportSpeedingReportToExcel (userData, reportData) {
208
+ console.log('exportSpeedingReportToExcel')
209
+
210
+ const translations = getTranslations(userData)
211
+
212
+ const settings = {
213
+ sheetName: translations.report.titleEventsReport, // The name of the sheet
214
+ fileName // The name of the spreadsheet
215
+ }
216
+ const headers = [
217
+ { label: translations.report.vehicle, value: 'name' },
218
+ { label: translations.report.eventType, value: 'eventType' },
219
+ { label: translations.report.date, value: 'fixTime' },
220
+ { label: translations.report.address, value: 'address' },
221
+ { label: translations.report.info, value: 'info' }
222
+ ]
223
+ let data = []
224
+ if (reportData.devices) {
225
+ reportData.devices.forEach(d => {
226
+ data = data.concat(d.alerts.map(a => {
234
227
  return {
235
- headers,
236
- data,
237
- settings
228
+ name: d.device.name,
229
+ eventType: a.type === 'alarm' ? translations.report['event_' + a.attributes.alarm] : translations.report['event_' + a.type],
230
+ fixTime: getAlertDate(userData.user, a),
231
+ address: a.geofenceName || (a.position ? a.position.address : ''),
232
+ info: getAlertInfo(userData.drivers, a)
238
233
  }
234
+ }))
235
+ })
236
+ return {
237
+ headers,
238
+ data,
239
+ settings
239
240
  }
241
+ }
240
242
  }
241
243
 
242
- function deviceGroupName(translation, groups, device){
243
- const group = groups.find(g => device.groupId === g.id)
244
- if(group) {
245
- return translation.report.group + ': ' + group.name
246
- }
247
- return ''
244
+ function deviceGroupName (translation, groups, device) {
245
+ const group = groups.find(g => device.groupId === g.id)
246
+ if (group) {
247
+ return translation.report.group + ': ' + group.name
248
+ }
249
+ return ''
248
250
  }
249
251
 
250
- function deviceName(device){
251
- return device.name + (device.attributes.license_plate ? ', ' +device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
252
+ function deviceName (device) {
253
+ return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
252
254
  }
253
255
 
254
- function getAlertInfo(drivers, alert) {
255
- if(alert.type === 'deviceOverspeed'){
256
- return Math.round(alert.attributes.speed * 1.85200) + ' Km/h'
257
- }
258
- if(alert.type === 'driverChanged'){
259
- const driver = drivers.find(d => d.uniqueId === alert.attributes.driverUniqueId)
260
- return driver ? driver.name : alert.attributes.driverUniqueId
261
- }
262
- return ''
256
+ function getAlertInfo (drivers, alert) {
257
+ if (alert.type === 'deviceOverspeed') {
258
+ return Math.round(alert.attributes.speed * 1.85200) + ' Km/h'
259
+ }
260
+ if (alert.type === 'driverChanged') {
261
+ const driver = drivers.find(d => d.uniqueId === alert.attributes.driverUniqueId)
262
+ return driver ? driver.name : alert.attributes.driverUniqueId
263
+ }
264
+ return ''
263
265
  }
264
266
 
265
- function getAlertDate(user, alert) {
266
- if(alert.position) {
267
- return convertToLocaleString(alert.position.fixTime, user.attributes.lang, user.attributes.timezone)
268
- }
267
+ function getAlertDate (user, alert) {
268
+ if (alert.position) {
269
+ return convertToLocaleString(alert.position.fixTime, user.attributes.lang, user.attributes.timezone)
270
+ }
269
271
  }
270
272
 
271
- exports.createEventsReport = createEventsReport;
273
+ exports.createEventsReport = createEventsReport
272
274
  exports.exportSpeedingReportToPDF = exportSpeedingReportToPDF
273
275
  exports.exportSpeedingReportToExcel = exportSpeedingReportToExcel