fleetmap-reports 1.0.410 → 1.0.411
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 +15 -0
- package/package.json +2 -2
- package/src/idle-report.js +292 -231
- package/src/index.test.js +15 -0
package/.eslintrc.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetmap-reports",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.411",
|
|
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-
|
|
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",
|
package/src/idle-report.js
CHANGED
|
@@ -1,280 +1,341 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const {
|
|
4
|
-
const {
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
const
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
56
|
-
|
|
37
|
+
if (!devices.length) {
|
|
38
|
+
// Empty report
|
|
39
|
+
return { drivers: [] }
|
|
40
|
+
}
|
|
57
41
|
|
|
58
|
-
|
|
59
|
-
reportData.push(allData)
|
|
42
|
+
const { route } = await traccarHelper.getAllInOne(traccarInstance, from, to, devices, true, false, false, false)
|
|
60
43
|
|
|
61
|
-
|
|
44
|
+
return { drivers: processDrivers(from, to, userData, route) }
|
|
62
45
|
}
|
|
63
46
|
|
|
64
|
-
async function
|
|
65
|
-
|
|
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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
77
|
+
const allData = await createIdleReportByDevice(from, to, withoutGroupDevices, userData, traccarInstance)
|
|
78
|
+
reportData.push(allData)
|
|
72
79
|
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
+
allData.devices.push(...processDevices(from, to, slice, route, userData))
|
|
79
99
|
}
|
|
80
100
|
|
|
81
|
-
|
|
101
|
+
deviceCount = deviceCount + slice.length
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return allData
|
|
82
105
|
}
|
|
83
106
|
|
|
84
|
-
function
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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)
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
const idleEvents = getIdleEvents(route)
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
if (route.length > 0) {
|
|
115
|
+
const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
|
|
116
|
+
|
|
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
|
-
|
|
127
|
+
return driversResult
|
|
121
128
|
}
|
|
122
129
|
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
function processDevices (from, to, devices, routes, userData) {
|
|
131
|
+
const devicesResult = []
|
|
125
132
|
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
const translations = getTranslations(userData)
|
|
133
|
+
devices.forEach(d => {
|
|
134
|
+
const route = routes.filter(p => p.deviceId === d.id)
|
|
129
135
|
|
|
130
|
-
const
|
|
136
|
+
const idleEvents = getIdleEvents(route)
|
|
131
137
|
|
|
132
|
-
const
|
|
133
|
-
translations.report.date,
|
|
134
|
-
translations.report.address,
|
|
135
|
-
translations.report.duration
|
|
136
|
-
]
|
|
138
|
+
const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
|
|
137
139
|
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
if (filteredEvents.length) {
|
|
141
|
+
const deviceData = {
|
|
142
|
+
device: d,
|
|
143
|
+
idleEvents: filteredEvents
|
|
144
|
+
}
|
|
145
|
+
devicesResult.push(deviceData)
|
|
142
146
|
}
|
|
147
|
+
})
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
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
|
+
}
|
|
172
|
+
} else if (inIdle) {
|
|
173
|
+
const currentIdleEvent = idleEvents[idleEvents.length - 1]
|
|
174
|
+
currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
|
|
175
|
+
inIdle = false
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
return idleEvents
|
|
226
181
|
}
|
|
227
182
|
|
|
228
|
-
function
|
|
229
|
-
|
|
183
|
+
async function exportIdleReportToPDF (userData, reportData) {
|
|
184
|
+
console.log('Export to PDF')
|
|
185
|
+
|
|
186
|
+
const timezone = userData.user.attributes.timezone
|
|
187
|
+
const lang = userData.user.attributes.lang || (navigator && navigator.language)
|
|
188
|
+
const translations = getTranslations(userData)
|
|
189
|
+
|
|
190
|
+
const idleData = userData.byDriver ? reportData.drivers : reportData.devices
|
|
191
|
+
|
|
192
|
+
const headers = [
|
|
193
|
+
translations.report.date,
|
|
194
|
+
translations.report.address,
|
|
195
|
+
translations.report.duration
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
if (userData.byDriver) {
|
|
199
|
+
headers.push(translations.report.vehicle)
|
|
200
|
+
} else {
|
|
201
|
+
headers.push(translations.report.driver)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (idleData) {
|
|
205
|
+
let first = true
|
|
206
|
+
// eslint-disable-next-line new-cap
|
|
207
|
+
const doc = new jsPDF.jsPDF('l')
|
|
208
|
+
await headerFromUser(doc, translations.report.titleIdleReport, userData.user)
|
|
209
|
+
|
|
210
|
+
idleData.forEach(d => {
|
|
211
|
+
try {
|
|
212
|
+
const data = []
|
|
213
|
+
|
|
214
|
+
const name = userData.byDriver ? d.driver.name : deviceName(d.device)
|
|
215
|
+
const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
|
|
216
|
+
|
|
217
|
+
let space = 0
|
|
218
|
+
if (!first) {
|
|
219
|
+
doc.addPage()
|
|
220
|
+
} else {
|
|
221
|
+
first = false
|
|
222
|
+
space = 10
|
|
223
|
+
}
|
|
224
|
+
doc.setFontSize(13)
|
|
225
|
+
doc.text(name, 20, space + 20)
|
|
226
|
+
doc.setFontSize(11)
|
|
227
|
+
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
|
|
228
|
+
doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, space + 25)
|
|
229
|
+
|
|
230
|
+
d.idleEvents.forEach(a => {
|
|
231
|
+
const temp = [
|
|
232
|
+
getIdleEventDate(a, userData.user),
|
|
233
|
+
a.position.address,
|
|
234
|
+
convertMS(a.idleTime, true),
|
|
235
|
+
userData.byDriver ? a.deviceName : a.driver
|
|
236
|
+
]
|
|
237
|
+
data.push(temp)
|
|
238
|
+
})
|
|
230
239
|
|
|
231
|
-
|
|
240
|
+
const footValues = [
|
|
241
|
+
'Total:' + d.idleEvents.length,
|
|
242
|
+
'',
|
|
243
|
+
convertMS(d.idleEvents.reduce((a, b) => a + b.idleTime, 0), true)
|
|
244
|
+
]
|
|
232
245
|
|
|
233
|
-
|
|
246
|
+
if (userData.roadSpeedLimits) {
|
|
247
|
+
footValues.splice(2, 0, '')
|
|
248
|
+
}
|
|
234
249
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
250
|
+
if (timezone === 'Asia/Qatar') {
|
|
251
|
+
doc.addFileToVFS('Amiri-Regular.ttf', AmiriRegular())
|
|
252
|
+
doc.addFont('Amiri-Regular.ttf', 'Amiri', 'normal')
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const style = getStyle(getUserPartner(userData.user))
|
|
256
|
+
doc.autoTable({
|
|
257
|
+
head: [headers],
|
|
258
|
+
body: data,
|
|
259
|
+
foot: [footValues],
|
|
260
|
+
showFoot: 'lastPage',
|
|
261
|
+
headStyles: {
|
|
262
|
+
fillColor: style.pdfHeaderColor,
|
|
263
|
+
textColor: style.pdfHeaderTextColor,
|
|
264
|
+
fontSize: 10
|
|
265
|
+
},
|
|
266
|
+
bodyStyles: {
|
|
267
|
+
fillColor: style.pdfBodyColor,
|
|
268
|
+
textColor: style.pdfBodyTextColor,
|
|
269
|
+
fontSize: 8,
|
|
270
|
+
font: timezone === 'Asia/Qatar' ? 'Amiri' : ''
|
|
271
|
+
|
|
272
|
+
},
|
|
273
|
+
footStyles: {
|
|
274
|
+
fillColor: style.pdfFooterColor,
|
|
275
|
+
textColor: style.pdfFooterTextColor,
|
|
276
|
+
fontSize: 9
|
|
277
|
+
},
|
|
278
|
+
startY: space + 35
|
|
260
279
|
})
|
|
261
|
-
|
|
280
|
+
} catch (e) {
|
|
281
|
+
console.error(e, 'moving on...')
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
return doc
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function exportIdleReportToExcel (userData, reportData) {
|
|
290
|
+
console.log('Export to Excel')
|
|
291
|
+
|
|
292
|
+
const translations = getTranslations(userData)
|
|
293
|
+
|
|
294
|
+
const idleData = userData.byDriver ? reportData.drivers : reportData.devices
|
|
295
|
+
|
|
296
|
+
const settings = {
|
|
297
|
+
sheetName: translations.report.titleIdleReport.substring(0, 31), // The name of the sheet
|
|
298
|
+
fileName // The name of the spreadsheet
|
|
299
|
+
}
|
|
300
|
+
const headers = [
|
|
301
|
+
userData.byDriver ? { label: translations.report.driver, value: 'driver' } : { label: translations.report.vehicle, value: 'name' },
|
|
302
|
+
{ label: translations.report.date, value: 'fixTime' },
|
|
303
|
+
{ label: translations.report.address, value: 'address' },
|
|
304
|
+
{ label: translations.report.duration, value: 'duration' },
|
|
305
|
+
userData.byDriver ? { label: translations.report.vehicle, value: 'name' } : { label: translations.report.driver, value: 'driver' }
|
|
306
|
+
]
|
|
307
|
+
|
|
308
|
+
let data = []
|
|
309
|
+
if (idleData) {
|
|
310
|
+
idleData.forEach(d => {
|
|
311
|
+
data = data.concat([{}])
|
|
312
|
+
data = data.concat(d.idleEvents.map(a => {
|
|
262
313
|
return {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
314
|
+
driver: userData.byDriver ? d.driver.name : a.driver,
|
|
315
|
+
duration: convertMS(a.idleTime, true),
|
|
316
|
+
fixTime: getIdleEventDate(a, userData.user),
|
|
317
|
+
name: userData.byDriver ? a.deviceName : d.device.name,
|
|
318
|
+
address: a.position.address + (a.geofenceName ? ' - ' + a.geofenceName : '')
|
|
266
319
|
}
|
|
320
|
+
}))
|
|
321
|
+
})
|
|
322
|
+
console.log(data)
|
|
323
|
+
return {
|
|
324
|
+
headers,
|
|
325
|
+
data,
|
|
326
|
+
settings
|
|
267
327
|
}
|
|
328
|
+
}
|
|
268
329
|
}
|
|
269
330
|
|
|
270
|
-
function deviceName(device){
|
|
271
|
-
|
|
331
|
+
function deviceName (device) {
|
|
332
|
+
return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
|
|
272
333
|
}
|
|
273
334
|
|
|
274
|
-
function getIdleEventDate(row, user) {
|
|
275
|
-
|
|
335
|
+
function getIdleEventDate (row, user) {
|
|
336
|
+
return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
|
|
276
337
|
}
|
|
277
338
|
|
|
278
|
-
exports.createIdleReport = createIdleReport
|
|
279
|
-
exports.exportIdleReportToPDF = exportIdleReportToPDF
|
|
280
|
-
exports.exportIdleReportToExcel = exportIdleReportToExcel
|
|
339
|
+
exports.createIdleReport = createIdleReport
|
|
340
|
+
exports.exportIdleReportToPDF = exportIdleReportToPDF
|
|
341
|
+
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, 3) // Total Alerts
|
|
212
|
+
assert.equal(totalIdleTime, 184400000) // 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()
|