fleetmap-reports 1.0.409 → 1.0.412

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js ADDED
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ env: {
3
+ browser: true,
4
+ commonjs: true,
5
+ es2021: true
6
+ },
7
+ extends: [
8
+ 'standard'
9
+ ],
10
+ parserOptions: {
11
+ ecmaVersion: 'latest'
12
+ },
13
+ rules: {
14
+ }
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.409",
3
+ "version": "1.0.412",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -32,7 +32,7 @@
32
32
  "eslint": "^8.15.0",
33
33
  "eslint-config-standard": "^17.0.0",
34
34
  "eslint-plugin-import": "^2.26.0",
35
- "eslint-plugin-n": "^15.2.0",
35
+ "eslint-plugin-node": "^11.1.0",
36
36
  "eslint-plugin-promise": "^6.0.0",
37
37
  "jest": "^27.5.0",
38
38
  "mocha": "^9.0.3",
@@ -1,280 +1,350 @@
1
- const traccar = require("./util/traccar");
2
- const jsPDF = require("jspdf");
3
- const {headerFromUser, AmiriRegular} = require("./util/pdfDocument");
4
- const {convertToLocaleString, convertMS, getTranslations} = require("./util/utils");
5
- const {getStyle} = require("./reportStyle");
6
- const {getUserPartner} = require("fleetmap-partners");
7
- const {devicesToProcess} = require("./util/device");
1
+ const jsPDF = require('jspdf')
2
+ const { headerFromUser, AmiriRegular } = require('./util/pdfDocument')
3
+ const { convertToLocaleString, convertMS, getTranslations } = require('./util/utils')
4
+ const { getStyle } = require('./reportStyle')
5
+ const { getUserPartner } = require('fleetmap-partners')
6
+ const { devicesToProcess } = require('./util/device')
7
+ const automaticReports = require('./automaticReports')
8
+ const traccarHelper = require('./util/traccar')
8
9
 
9
10
  const fileName = 'IdleReport'
10
11
 
11
- async function createIdleReport(from, to, userData, traccarInstance) {
12
- console.log('Create IdleReport')
13
- const reportData = []
14
-
15
- if (userData.byGroup) {
16
- console.log("ByGroup")
17
- const allData = await createTripReportByGroup(from, to, userData, traccarInstance)
18
- reportData.push(...allData)
19
- } else {
20
- console.log("ByDevice")
21
- const report = await createTripReportByDevice(from, to, userData, traccarInstance)
22
- reportData.push(report)
23
- }
24
-
25
- return reportData
12
+ async function createIdleReport (from, to, userData, traccarInstance) {
13
+ console.log('Create IdleReport')
14
+ const reportData = []
15
+
16
+ if (userData.byDriver) {
17
+ console.log('ByDriver')
18
+ const report = await createIdleReportByDriver(from, to, userData, traccarInstance)
19
+ reportData.push(report)
20
+ } else if (userData.byGroup) {
21
+ console.log('ByGroup')
22
+ const allData = await createIdleReportByGroup(from, to, userData, traccarInstance)
23
+ reportData.push(...allData)
24
+ } else {
25
+ console.log('ByDevice')
26
+ const report = await createIdleReportByDevice(from, to, userData, traccarInstance)
27
+ reportData.push(report)
28
+ }
29
+
30
+ return reportData
26
31
  }
27
32
 
28
- async function createTripReportByGroup(from, to, userData, traccarInstance) {
29
- const reportData = []
30
- for (const g of userData.groups) {
31
- const devices = userData.devices.filter(d => d.groupId === g.id)
32
- console.log(g.name + ' devices:' + devices.length)
33
- if(devices.length > 0) {
34
- const groupData = {
35
- devices: [],
36
- group: g,
37
- from: from,
38
- to: to
39
- }
40
-
41
- const response = await traccarInstance.reports.reportsRouteGet(from, to, null, [g.id])
42
- const routes = response.data
43
-
44
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
45
-
46
- if (routes.length > 0) {
47
- console.log('Routes:' + routes.length)
48
- groupData.devices = processDevices(from, to, devices, routes, userData)
49
-
50
- reportData.push(groupData)
51
- }
52
- }
53
- }
33
+ async function createIdleReportByDriver (from, to, userData, traccarInstance) {
34
+ const devices = await traccarInstance.devices.devicesGet().then(d => d.data)
35
+ console.log(devices.length)
54
36
 
55
- const groupIds = userData.groups.map(g => g.id)
56
- const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
37
+ if (!devices.length) {
38
+ // Empty report
39
+ return { drivers: [] }
40
+ }
57
41
 
58
- const allData = await createTripReportByDevice(from, to, withoutGroupDevices, userData, traccarInstance)
59
- reportData.push(allData)
42
+ const { route } = await traccarHelper.getAllInOne(traccarInstance, from, to, devices, true, false, false, false)
60
43
 
61
- return reportData
44
+ return { drivers: processDrivers(from, to, userData, route) }
62
45
  }
63
46
 
64
- async function createTripReportByDevice(from, to, userData, traccarInstance) {
65
- const allData = {
47
+ async function createIdleReportByGroup (from, to, userData, traccarInstance) {
48
+ const reportData = []
49
+ for (const g of userData.groups) {
50
+ const devices = userData.devices.filter(d => d.groupId === g.id)
51
+ console.log(g.name + ' devices:' + devices.length)
52
+ if (devices.length > 0) {
53
+ const groupData = {
66
54
  devices: [],
67
- from: from,
68
- to: to
55
+ group: g,
56
+ from,
57
+ to
58
+ }
59
+
60
+ const response = await traccarInstance.reports.reportsRouteGet(from, to, null, [g.id])
61
+ const routes = response.data
62
+
63
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
64
+
65
+ if (routes.length > 0) {
66
+ console.log('Routes:' + routes.length)
67
+ groupData.devices = processDevices(from, to, devices, routes, userData)
68
+
69
+ reportData.push(groupData)
70
+ }
69
71
  }
72
+ }
73
+
74
+ const groupIds = userData.groups.map(g => g.id)
75
+ const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
70
76
 
71
- const devices = devicesToProcess(userData)
77
+ const allData = await createIdleReportByDevice(from, to, withoutGroupDevices, userData, traccarInstance)
78
+ reportData.push(allData)
72
79
 
73
- const route = await traccar.getRoute(traccarInstance, from, to, devices)
80
+ return reportData
81
+ }
82
+
83
+ async function createIdleReportByDevice (from, to, userData, traccarInstance) {
84
+ const allData = {
85
+ devices: [],
86
+ from,
87
+ to
88
+ }
89
+
90
+ const devices = devicesToProcess(userData)
91
+ const sliced = automaticReports.sliceArray(devices, 5)
74
92
 
75
- console.log('Route:' + route.length)
93
+ let deviceCount = 0
94
+ for (const slice of sliced) {
95
+ const { route } = await traccarHelper.getAllInOne(traccarInstance, from, to, slice, true, false, false, false, deviceCount, devices.length)
76
96
 
77
97
  if (route.length > 0) {
78
- allData.devices = processDevices(from, to, devices, route, userData)
98
+ allData.devices.push(...processDevices(from, to, slice, route, userData))
79
99
  }
80
100
 
81
- return allData
101
+ deviceCount = deviceCount + slice.length
102
+ }
103
+
104
+ return allData
82
105
  }
83
106
 
84
- function processDevices(from, to, devices, routes, userData) {
85
- const devicesResult = []
86
-
87
- devices.forEach(d => {
88
- const route = routes.filter(p => p.deviceId === d.id)
89
-
90
- const idleEvents = []
91
- let inIdle = false
92
- route.forEach(p => {
93
- if(p.attributes.ignition && p.speed === 0){
94
- if(!inIdle) {
95
- const idleEvent = {
96
- position: p,
97
- idleTime: 0
98
- }
99
- idleEvents.push(idleEvent)
100
- inIdle = true
101
- }
102
- } else if(inIdle) {
103
- const currentIdleEvent = idleEvents[idleEvents.length-1]
104
- currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
105
- inIdle = false
106
- }
107
- })
107
+ function processDrivers (from, to, userData, routes) {
108
+ const driversResult = []
109
+ userData.drivers.forEach(d => {
110
+ const route = routes.filter(p => p.attributes.driverUniqueId === d.uniqueId || !p.attributes.ignition)
108
111
 
109
- const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes*60*1000 : true)
112
+ const idleEvents = getIdleEvents(route)
113
+ console.log(idleEvents)
114
+ if (route.length > 0) {
115
+ const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
110
116
 
111
- if(filteredEvents.length) {
112
- const deviceData = {
113
- device: d,
114
- idleEvents: filteredEvents
115
- }
116
- devicesResult.push(deviceData)
117
+ if (filteredEvents.length) {
118
+ const driverData = {
119
+ driver: d,
120
+ idleEvents: filteredEvents
117
121
  }
118
- })
122
+ driversResult.push(driverData)
123
+ }
124
+ }
125
+ })
119
126
 
120
- return devicesResult
127
+ return driversResult
121
128
  }
122
129
 
123
- async function exportIdleReportToPDF(userData, reportData) {
124
- console.log('Export to PDF')
125
-
126
- const timezone = userData.user.attributes.timezone
127
- const lang = userData.user.attributes.lang || (navigator && navigator.language)
128
- const translations = getTranslations(userData)
130
+ function processDevices (from, to, devices, routes, userData) {
131
+ const devicesResult = []
129
132
 
130
- const idleData = userData.byDriver ? reportData.drivers : reportData.devices
133
+ devices.forEach(d => {
134
+ const route = routes.filter(p => p.deviceId === d.id)
131
135
 
132
- const headers = [
133
- translations.report.date,
134
- translations.report.address,
135
- translations.report.duration
136
- ]
136
+ const idleEvents = getIdleEvents(route)
137
+ console.log(idleEvents)
138
+ const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
137
139
 
138
- if (userData.byDriver) {
139
- headers.push(translations.report.vehicle)
140
- } else {
141
- headers.push(translations.report.driver)
140
+ if (filteredEvents.length) {
141
+ const deviceData = {
142
+ device: d,
143
+ idleEvents: filteredEvents
144
+ }
145
+ devicesResult.push(deviceData)
142
146
  }
147
+ })
143
148
 
144
- if (idleData) {
145
- let first = true
146
- const doc = new jsPDF.jsPDF('l');
147
- await headerFromUser(doc, translations.report.titleIdleReport, userData.user)
148
-
149
- idleData.forEach(d => {
150
- try {
151
- let data = []
152
-
153
- const name = userData.byDriver ? d.driver.name : deviceName(d.device)
154
- const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
155
-
156
- let space = 0
157
- if(!first) {
158
- doc.addPage()
159
- } else {
160
- first = false
161
- space = 10
162
- }
163
- doc.setFontSize(13)
164
- doc.text(name, 20, space+20 )
165
- doc.setFontSize(11)
166
- doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
167
- doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, space+25 )
168
-
169
- d.idleEvents.map(a => {
170
- const temp = [
171
- getIdleEventDate(a, userData.user),
172
- a.position.address,
173
- convertMS(a.idleTime, true),
174
- userData.byDriver ? a.deviceName : a.driver
175
- ]
176
-
177
- data.push(temp)
178
- })
179
-
180
- const footValues = [
181
- 'Total:' + d.idleEvents.length,
182
- '',
183
- convertMS(d.idleEvents.reduce((a, b) => a + b.idleTime, 0), true)
184
- ]
185
-
186
- if(userData.roadSpeedLimits){
187
- footValues.splice(2, 0, '')
188
- }
189
-
190
- if(timezone === 'Asia/Qatar') {
191
- doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
192
- doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
193
- }
194
-
195
- const style = getStyle(getUserPartner(userData.user))
196
- doc.autoTable({
197
- head: [headers],
198
- body: data,
199
- foot: [footValues],
200
- showFoot: 'lastPage',
201
- headStyles: {
202
- fillColor: style.pdfHeaderColor,
203
- textColor: style.pdfHeaderTextColor,
204
- fontSize: 10
205
- },
206
- bodyStyles: {
207
- fillColor: style.pdfBodyColor,
208
- textColor: style.pdfBodyTextColor,
209
- fontSize: 8,
210
- font: timezone === 'Asia/Qatar' ? "Amiri" : ''
211
-
212
- },
213
- footStyles: {
214
- fillColor: style.pdfFooterColor,
215
- textColor: style.pdfFooterTextColor,
216
- fontSize: 9
217
- },
218
- startY: space+35 });
219
- } catch (e) {
220
- console.error(e, 'moving on...')
221
- }
222
- })
149
+ return devicesResult
150
+ }
223
151
 
224
- return doc
225
- }
152
+ function getIdleEvents (route) {
153
+ const idleEvents = []
154
+
155
+ const routeByDevice = route.reduce(function (a, x) {
156
+ (a[x.deviceId] = a[x.deviceId] || []).push(x)
157
+ return a
158
+ }, {})
159
+
160
+ Object.keys(routeByDevice).forEach(function (key) {
161
+ let inIdle = false
162
+ routeByDevice[key].forEach(p => {
163
+ if (p.attributes.ignition && p.speed === 0) {
164
+ if (!inIdle) {
165
+ const idleEvent = {
166
+ position: p,
167
+ idleTime: 0
168
+ }
169
+ idleEvents.push(idleEvent)
170
+ inIdle = true
171
+ } else {
172
+ if (!idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId) {
173
+ idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId = p.attributes.driverUniqueId
174
+ }
175
+ if (p.attributes.idleTime) {
176
+ idleEvents[idleEvents.length - 1].idleTime = p.attributes.idleTime
177
+ }
178
+ }
179
+ } else if (inIdle) {
180
+ const currentIdleEvent = idleEvents[idleEvents.length - 1]
181
+ if (p.attributes.idleTime === undefined) {
182
+ currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
183
+ }
184
+ inIdle = false
185
+ }
186
+ })
187
+ })
188
+
189
+ return idleEvents
226
190
  }
227
191
 
228
- function exportIdleReportToExcel(userData, reportData) {
229
- console.log('Export to Excel')
192
+ async function exportIdleReportToPDF (userData, reportData) {
193
+ console.log('Export to PDF')
194
+
195
+ const timezone = userData.user.attributes.timezone
196
+ const lang = userData.user.attributes.lang || (navigator && navigator.language)
197
+ const translations = getTranslations(userData)
198
+
199
+ const idleData = userData.byDriver ? reportData.drivers : reportData.devices
200
+
201
+ const headers = [
202
+ translations.report.date,
203
+ translations.report.address,
204
+ translations.report.duration
205
+ ]
206
+
207
+ if (userData.byDriver) {
208
+ headers.push(translations.report.vehicle)
209
+ } else {
210
+ headers.push(translations.report.driver)
211
+ }
212
+
213
+ if (idleData) {
214
+ let first = true
215
+ // eslint-disable-next-line new-cap
216
+ const doc = new jsPDF.jsPDF('l')
217
+ await headerFromUser(doc, translations.report.titleIdleReport, userData.user)
218
+
219
+ idleData.forEach(d => {
220
+ try {
221
+ const data = []
222
+
223
+ const name = userData.byDriver ? d.driver.name : deviceName(d.device)
224
+ const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
225
+
226
+ let space = 0
227
+ if (!first) {
228
+ doc.addPage()
229
+ } else {
230
+ first = false
231
+ space = 10
232
+ }
233
+ doc.setFontSize(13)
234
+ doc.text(name, 20, space + 20)
235
+ doc.setFontSize(11)
236
+ doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
237
+ doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, space + 25)
238
+
239
+ d.idleEvents.forEach(a => {
240
+ const temp = [
241
+ getIdleEventDate(a, userData.user),
242
+ a.position.address,
243
+ convertMS(a.idleTime, true),
244
+ userData.byDriver ? a.deviceName : a.driver
245
+ ]
246
+ data.push(temp)
247
+ })
248
+
249
+ const footValues = [
250
+ 'Total:' + d.idleEvents.length,
251
+ '',
252
+ convertMS(d.idleEvents.reduce((a, b) => a + b.idleTime, 0), true)
253
+ ]
230
254
 
231
- const translations = getTranslations(userData)
255
+ if (userData.roadSpeedLimits) {
256
+ footValues.splice(2, 0, '')
257
+ }
232
258
 
233
- const idleData = userData.byDriver ? reportData.drivers : reportData.devices
259
+ if (timezone === 'Asia/Qatar') {
260
+ doc.addFileToVFS('Amiri-Regular.ttf', AmiriRegular())
261
+ doc.addFont('Amiri-Regular.ttf', 'Amiri', 'normal')
262
+ }
234
263
 
235
- const settings = {
236
- sheetName: translations.report.titleIdleReport.substring(0, 31), // The name of the sheet
237
- fileName: fileName, // The name of the spreadsheet
238
- }
239
- const headers = [
240
- userData.byDriver ? {label: translations.report.driver, value:'driver'} : {label: translations.report.vehicle, value:'name'},
241
- {label: translations.report.date, value:'fixTime'},
242
- {label: translations.report.address, value:'address'},
243
- {label: translations.report.duration, value:'duration'},
244
- userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
245
- ]
246
-
247
- let data = []
248
- if (idleData) {
249
- idleData.forEach(d => {
250
- data = data.concat([{}])
251
- data = data.concat(d.idleEvents.map(a => {
252
- return {
253
- driver: userData.byDriver ? d.driver.name : a.driver,
254
- duration: convertMS(a.idleTime, true),
255
- fixTime: getIdleEventDate(a, userData.user),
256
- name: userData.byDriver ? a.deviceName : d.device.name,
257
- address: a.position.address + (a.geofenceName ? ' - ' + a.geofenceName : '')
258
- }
259
- }))
264
+ const style = getStyle(getUserPartner(userData.user))
265
+ doc.autoTable({
266
+ head: [headers],
267
+ body: data,
268
+ foot: [footValues],
269
+ showFoot: 'lastPage',
270
+ headStyles: {
271
+ fillColor: style.pdfHeaderColor,
272
+ textColor: style.pdfHeaderTextColor,
273
+ fontSize: 10
274
+ },
275
+ bodyStyles: {
276
+ fillColor: style.pdfBodyColor,
277
+ textColor: style.pdfBodyTextColor,
278
+ fontSize: 8,
279
+ font: timezone === 'Asia/Qatar' ? 'Amiri' : ''
280
+
281
+ },
282
+ footStyles: {
283
+ fillColor: style.pdfFooterColor,
284
+ textColor: style.pdfFooterTextColor,
285
+ fontSize: 9
286
+ },
287
+ startY: space + 35
260
288
  })
261
- console.log(data)
289
+ } catch (e) {
290
+ console.error(e, 'moving on...')
291
+ }
292
+ })
293
+
294
+ return doc
295
+ }
296
+ }
297
+
298
+ function exportIdleReportToExcel (userData, reportData) {
299
+ console.log('Export to Excel')
300
+
301
+ const translations = getTranslations(userData)
302
+
303
+ const idleData = userData.byDriver ? reportData.drivers : reportData.devices
304
+
305
+ const settings = {
306
+ sheetName: translations.report.titleIdleReport.substring(0, 31), // The name of the sheet
307
+ fileName // The name of the spreadsheet
308
+ }
309
+ const headers = [
310
+ userData.byDriver ? { label: translations.report.driver, value: 'driver' } : { label: translations.report.vehicle, value: 'name' },
311
+ { label: translations.report.date, value: 'fixTime' },
312
+ { label: translations.report.address, value: 'address' },
313
+ { label: translations.report.duration, value: 'duration' },
314
+ userData.byDriver ? { label: translations.report.vehicle, value: 'name' } : { label: translations.report.driver, value: 'driver' }
315
+ ]
316
+
317
+ let data = []
318
+ if (idleData) {
319
+ idleData.forEach(d => {
320
+ data = data.concat([{}])
321
+ data = data.concat(d.idleEvents.map(a => {
262
322
  return {
263
- headers,
264
- data,
265
- settings
323
+ driver: userData.byDriver ? d.driver.name : a.driver,
324
+ duration: convertMS(a.idleTime, true),
325
+ fixTime: getIdleEventDate(a, userData.user),
326
+ name: userData.byDriver ? a.deviceName : d.device.name,
327
+ address: a.position.address + (a.geofenceName ? ' - ' + a.geofenceName : '')
266
328
  }
329
+ }))
330
+ })
331
+ console.log(data)
332
+ return {
333
+ headers,
334
+ data,
335
+ settings
267
336
  }
337
+ }
268
338
  }
269
339
 
270
- function deviceName(device){
271
- return device.name + (device.attributes.license_plate ? ', ' +device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
340
+ function deviceName (device) {
341
+ return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
272
342
  }
273
343
 
274
- function getIdleEventDate(row, user) {
275
- return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
344
+ function getIdleEventDate (row, user) {
345
+ return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
276
346
  }
277
347
 
278
- exports.createIdleReport = createIdleReport;
279
- exports.exportIdleReportToPDF = exportIdleReportToPDF;
280
- exports.exportIdleReportToExcel = exportIdleReportToExcel;
348
+ exports.createIdleReport = createIdleReport
349
+ exports.exportIdleReportToPDF = exportIdleReportToPDF
350
+ exports.exportIdleReportToExcel = exportIdleReportToExcel
package/src/index.test.js CHANGED
@@ -197,6 +197,21 @@ describe('Test_Reports', function () {
197
197
  assert.equal(totalIdleTime, 1294000) // Total Duration
198
198
  }, 20000)
199
199
  // eslint-disable-next-line no-undef
200
+ it('Idle by driver', async () => {
201
+ const report = await getReports()
202
+ const userData = await report.getUserData()
203
+ userData.minimumIdleMinutes = 2
204
+ userData.byDriver = true
205
+ const data = await report.idleReport(new Date(2022, 0, 3, 0, 0, 0, 0),
206
+ new Date(2022, 0, 7, 23, 59, 59, 0),
207
+ userData)
208
+ assert.equal(data.length, 1)
209
+ const driver = data[0].drivers.find(d => d.driver.id === 14020)
210
+ const totalIdleTime = driver.idleEvents.reduce((a, b) => a + b.idleTime, 0)
211
+ assert.equal(driver.idleEvents.length, 12) // Total Alerts
212
+ assert.equal(totalIdleTime, 30785000) // Total Duration
213
+ }, 20000)
214
+ // eslint-disable-next-line no-undef
200
215
  it('Activity by device', async () => {
201
216
  const report = await getReports()
202
217
  const userData = await report.getUserData()
@@ -77,7 +77,8 @@ async function getAllInOne (
77
77
  currentDeviceCount = 0,
78
78
  totalDevices = devices.length,
79
79
  sliceSize = 5,
80
- devicesPerRequest = 1) {
80
+ devicesPerRequest = 1,
81
+ counter = undefined) {
81
82
  let url = `/reports/allinone?from=${from.toISOString()}&to=${to.toISOString()}`
82
83
  if (getRoutes) url += '&type=route'
83
84
  if (getTrips) url += '&type=trips'
@@ -96,8 +97,13 @@ async function getAllInOne (
96
97
  withCredentials: true
97
98
  }).then(r => r.data).then(x => {
98
99
  console.log('LOADING_MESSAGE:' + _chunk[0].name)
99
- currentDeviceCount += devicesPerRequest
100
- console.log(`PROGRESS_PERC:${currentDeviceCount / totalDevices * 100}`)
100
+ if (counter) {
101
+ counter.count += devicesPerRequest
102
+ console.log(`PROGRESS_PERC:${counter.count / totalDevices * 100}`)
103
+ } else {
104
+ currentDeviceCount += devicesPerRequest
105
+ console.log(`PROGRESS_PERC:${currentDeviceCount / totalDevices * 100}`)
106
+ }
101
107
  return x
102
108
  }))
103
109
  }
@@ -53,14 +53,14 @@ async function createZoneReport (from, to, userData, traccar) {
53
53
  xpert: devices.filter(d => d.attributes.xpert).length > 0
54
54
  }
55
55
 
56
- const sliced = automaticReports.sliceArray(devices, 50)
56
+ const sliced = automaticReports.sliceArray(devices, 30)
57
57
 
58
- let deviceCount = 0
58
+ const deviceCount = { count: 0 }
59
59
  const promises = []
60
60
  for (const slice of sliced) {
61
61
  promises.push(traccarHelper.getAllInOne(
62
62
  traccar, from, to, slice, true, false, false, false,
63
- deviceCount, devices.length, 30, 5).then(async allInOne => {
63
+ deviceCount, devices.length, 20, 5, deviceCount).then(async allInOne => {
64
64
  const routeData = allInOne.route
65
65
 
66
66
  const data = getInAndOutEvents(slice, routeData, userData)
@@ -70,7 +70,6 @@ async function createZoneReport (from, to, userData, traccar) {
70
70
  if (data.length) {
71
71
  allData.devices.push(...await processDevices(from, to, devices, userData.drivers, userData.geofences, data, traccar))
72
72
  }
73
- deviceCount = deviceCount + slice.length
74
73
  }))
75
74
  }
76
75
  await Promise.all(promises)