fleetmap-reports 1.0.678 → 1.0.680
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/package.json +1 -1
- package/src/zone-report.js +173 -228
package/package.json
CHANGED
package/src/zone-report.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const moment = require('moment')
|
|
2
1
|
const automaticReports = require('./automaticReports')
|
|
3
2
|
const {
|
|
4
3
|
convertMS, convertToLocaleString, getTranslations, convertToFeature, convertPositionToFeature,
|
|
@@ -8,7 +7,7 @@ const {
|
|
|
8
7
|
const jsPDF = require('jspdf')
|
|
9
8
|
require('jspdf-autotable')
|
|
10
9
|
const traccarHelper = require('./util/traccar')
|
|
11
|
-
const { headerFromUser } = require('./util/pdfDocument')
|
|
10
|
+
const { headerFromUser, addTable } = require('./util/pdfDocument')
|
|
12
11
|
const { getStyle } = require('./reportStyle')
|
|
13
12
|
const { getUserPartner } = require('fleetmap-partners')
|
|
14
13
|
const { devicesToProcess } = require('./util/device')
|
|
@@ -96,30 +95,30 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
96
95
|
const alerts = data.alerts.filter(t => t.deviceId === d.id)
|
|
97
96
|
const deviceRoute = data.route.filter(p => p.deviceId === d.id)
|
|
98
97
|
|
|
99
|
-
const zoneInOutData = userData.
|
|
100
|
-
? analyseAlertsGroupGeofences(alerts, deviceRoute, from, to)
|
|
101
|
-
: analyseAlerts(alerts, deviceRoute, userData)
|
|
98
|
+
const zoneInOutData = analyseAlerts(alerts, deviceRoute, userData, from, to).filter(d => !userData.onlyWithStop || d.stopped)
|
|
102
99
|
|
|
103
|
-
if (
|
|
104
|
-
const
|
|
100
|
+
if (userData.groupByDay) {
|
|
101
|
+
const dates = getDates(from, to)
|
|
105
102
|
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
const geofencesData = []
|
|
104
|
+
for (const geofence of userData.geofences) {
|
|
105
|
+
const filteredByGeofence = zoneInOutData.filter(d => d.geofenceId === geofence.id)
|
|
108
106
|
|
|
109
107
|
const dataByDay = []
|
|
110
108
|
for (const date of dates) {
|
|
111
109
|
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
112
110
|
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
113
111
|
|
|
114
|
-
const
|
|
115
|
-
|
|
112
|
+
const dayRoute = deviceRoute.filter(p => new Date(p.fixTime) >= fromByDay && new Date(p.fixTime) < toByDay)
|
|
113
|
+
const zoneInOutDayData = filteredByGeofence.filter(z => (!z.inTime || (new Date(z.inTime.fixTime) < toByDay)) &&
|
|
114
|
+
(!z.outTime || (new Date(z.outTime.fixTime) > fromByDay)))
|
|
116
115
|
|
|
117
116
|
const firstIn = zoneInOutDayData.find(z => z.inTime && new Date(z.inTime.fixTime) > fromByDay)
|
|
118
117
|
const lastOut = zoneInOutDayData.slice().reverse().find(z => z.outTime && new Date(z.outTime.fixTime) < toByDay)
|
|
119
118
|
|
|
120
|
-
let timeIn = zoneInOutDayData.length ? zoneInOutDayData.reduce((a, b) => a + (b.
|
|
119
|
+
let timeIn = zoneInOutDayData.length ? zoneInOutDayData.reduce((a, b) => a + (b.totalInTime || 0), 0) : 0
|
|
121
120
|
|
|
122
|
-
let distanceIn = zoneInOutDayData.length ? zoneInOutDayData.reduce((a, b) => a + (b.distanceIn || 0), 0) : 0
|
|
121
|
+
let distanceIn = zoneInOutDayData.length && dayRoute.length ? zoneInOutDayData.reduce((a, b) => a + (b.distanceIn || 0), 0) : 0
|
|
123
122
|
let distanceOut = 0
|
|
124
123
|
if (zoneInOutDayData.length) {
|
|
125
124
|
distanceOut = zoneInOutDayData.reduce((a, b) => a + (b.distanceOut || 0), 0) - zoneInOutDayData[zoneInOutDayData.length - 1].distanceOut
|
|
@@ -132,14 +131,14 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
132
131
|
if (!zoneInOutDayData[0].inTime || new Date(zoneInOutDayData[0].inTime.fixTime) < fromByDay) {
|
|
133
132
|
const inTime = zoneInOutDayData[0].inTime ? new Date(zoneInOutDayData[0].inTime.fixTime) : from
|
|
134
133
|
timeIn = timeIn - (fromByDay.getTime() - inTime.getTime())
|
|
135
|
-
const routeDayBefore = deviceRoute.filter(p => (!zoneInOutDayData[0].inTime || new Date(p.fixTime)
|
|
136
|
-
|
|
134
|
+
const routeDayBefore = deviceRoute.filter(p => (!zoneInOutDayData[0].inTime || new Date(p.fixTime) >= new Date(zoneInOutDayData[0].inTime.fixTime)) &&
|
|
135
|
+
new Date(p.fixTime) < fromByDay)
|
|
137
136
|
distanceIn = distanceIn - calculateDistance(routeDayBefore)
|
|
138
137
|
} else {
|
|
139
138
|
// Add distanceOut before the first entry
|
|
140
139
|
const routeOut = deviceRoute.filter(p =>
|
|
141
140
|
new Date(p.fixTime).getTime() < new Date(zoneInOutDayData[0].inTime.fixTime).getTime() &&
|
|
142
|
-
|
|
141
|
+
new Date(p.fixTime).getTime() >= fromByDay.getTime()
|
|
143
142
|
)
|
|
144
143
|
distanceOut = distanceOut + calculateDistance(routeOut)
|
|
145
144
|
}
|
|
@@ -148,42 +147,47 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
148
147
|
if (!zoneInOutDayData[zoneInOutDayData.length - 1].outTime || new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime) > toByDay) {
|
|
149
148
|
const outTime = zoneInOutDayData[zoneInOutDayData.length - 1].outTime ? new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime) : to
|
|
150
149
|
timeIn = timeIn - (outTime.getTime() - (toByDay.getTime() + 1000))
|
|
151
|
-
const routeDayAfter = deviceRoute.filter(p => new Date(p.fixTime)
|
|
150
|
+
const routeDayAfter = deviceRoute.filter(p => new Date(p.fixTime) <= outTime && new Date(p.fixTime) > toByDay)
|
|
152
151
|
distanceIn = distanceIn - calculateDistance(routeDayAfter)
|
|
153
152
|
} else {
|
|
154
153
|
const routeOut = deviceRoute.filter(p =>
|
|
155
|
-
new Date(p.fixTime)
|
|
156
|
-
|
|
154
|
+
new Date(p.fixTime) >= new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime).getTime() &&
|
|
155
|
+
new Date(p.fixTime) < toByDay.getTime())
|
|
157
156
|
distanceOut = distanceOut + calculateDistance(routeOut)
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
|
-
|
|
161
159
|
dataByDay.push({
|
|
162
160
|
date,
|
|
163
161
|
firstIn: firstIn ? firstIn.inTime.fixTime : undefined,
|
|
164
162
|
lastOut: lastOut ? lastOut.outTime.fixTime : undefined,
|
|
165
|
-
distanceIn,
|
|
163
|
+
distanceIn: distanceIn > 0 ? distanceIn : 0,
|
|
166
164
|
distanceOut,
|
|
167
|
-
timeIn,
|
|
168
|
-
|
|
165
|
+
totalInTime: timeIn,
|
|
166
|
+
totalOutTime: (24 * 60 * 60 * 1000) - timeIn
|
|
169
167
|
})
|
|
170
168
|
}
|
|
171
169
|
|
|
170
|
+
geofencesData.push({
|
|
171
|
+
geofenceName: geofence.name,
|
|
172
|
+
days: dataByDay
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
devicesResult.push({
|
|
177
|
+
device: d,
|
|
178
|
+
from,
|
|
179
|
+
to,
|
|
180
|
+
groupByDay: true,
|
|
181
|
+
geofences: geofencesData
|
|
182
|
+
})
|
|
183
|
+
} else {
|
|
184
|
+
if (zoneInOutData.length > 0) {
|
|
172
185
|
devicesResult.push({
|
|
173
186
|
device: d,
|
|
174
187
|
from,
|
|
175
188
|
to,
|
|
176
|
-
|
|
189
|
+
geofences: zoneInOutData
|
|
177
190
|
})
|
|
178
|
-
} else {
|
|
179
|
-
if (result.length > 0) {
|
|
180
|
-
devicesResult.push({
|
|
181
|
-
device: d,
|
|
182
|
-
from,
|
|
183
|
-
to,
|
|
184
|
-
geofences: result
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
191
|
}
|
|
188
192
|
}
|
|
189
193
|
}
|
|
@@ -191,99 +195,7 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
191
195
|
return devicesResult
|
|
192
196
|
}
|
|
193
197
|
|
|
194
|
-
function
|
|
195
|
-
const zoneInOutData = []
|
|
196
|
-
const zoneInData = { inCount: 0 }
|
|
197
|
-
|
|
198
|
-
alerts.forEach(a => {
|
|
199
|
-
if (!a.position) {
|
|
200
|
-
return
|
|
201
|
-
}
|
|
202
|
-
if (a.type === 'geofenceEnter') {
|
|
203
|
-
if (zoneInData.inTime) {
|
|
204
|
-
zoneInData.inCount++
|
|
205
|
-
} else {
|
|
206
|
-
zoneInData.inTime = a
|
|
207
|
-
zoneInData.inCount = 1
|
|
208
|
-
}
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
if (a.type === 'geofenceExit') {
|
|
212
|
-
if (zoneInData.inCount === 0) {
|
|
213
|
-
zoneInOutData.splice(0, zoneInOutData.length)
|
|
214
|
-
const totalInTime = new Date(a.position.fixTime).getTime() - from.getTime()
|
|
215
|
-
const outDate = new Date(a.position.fixTime).getTime()
|
|
216
|
-
const routeIn = deviceRoute.filter(p =>
|
|
217
|
-
new Date(p.fixTime).getTime() >= from &&
|
|
218
|
-
new Date(p.fixTime).getTime() < outDate
|
|
219
|
-
)
|
|
220
|
-
const routeAfterOut = deviceRoute.filter(p =>
|
|
221
|
-
new Date(p.fixTime).getTime() >= outDate &&
|
|
222
|
-
new Date(p.fixTime).getTime() < getNextIn(outDate, alerts, undefined, deviceRoute)
|
|
223
|
-
)
|
|
224
|
-
const distanceOut = calculateDistance(routeAfterOut)
|
|
225
|
-
zoneInOutData.push({
|
|
226
|
-
outTime: a.position,
|
|
227
|
-
totalTime: totalInTime,
|
|
228
|
-
distanceIn: calculateDistance(routeIn),
|
|
229
|
-
distanceOut
|
|
230
|
-
})
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
zoneInData.inCount--
|
|
235
|
-
if (zoneInData.inCount === 0) {
|
|
236
|
-
const totalInTime = new Date(a.position.fixTime).getTime() - new Date(zoneInData.inTime.position.fixTime).getTime()
|
|
237
|
-
const inDate = new Date(zoneInData.inTime.position.fixTime).getTime()
|
|
238
|
-
const outDate = new Date(a.position.fixTime).getTime()
|
|
239
|
-
const routeAfterOut = deviceRoute.filter(p =>
|
|
240
|
-
new Date(p.fixTime).getTime() >= outDate &&
|
|
241
|
-
new Date(p.fixTime).getTime() < getNextIn(outDate, alerts, undefined, deviceRoute)
|
|
242
|
-
)
|
|
243
|
-
const distanceOut = calculateDistance(routeAfterOut)
|
|
244
|
-
const routeIn = deviceRoute.filter(p =>
|
|
245
|
-
new Date(p.fixTime).getTime() >= inDate &&
|
|
246
|
-
new Date(p.fixTime).getTime() < outDate
|
|
247
|
-
)
|
|
248
|
-
zoneInOutData.push({
|
|
249
|
-
inTime: zoneInData.inTime.position,
|
|
250
|
-
outTime: a.position,
|
|
251
|
-
totalTime: totalInTime,
|
|
252
|
-
distanceIn: calculateDistance(routeIn),
|
|
253
|
-
distanceOut
|
|
254
|
-
})
|
|
255
|
-
zoneInData.inTime = undefined
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
if (zoneInData.inTime) {
|
|
261
|
-
const totalInTime = to.getTime() - new Date(zoneInData.inTime.position.fixTime).getTime()
|
|
262
|
-
const routeIn = deviceRoute.filter(p =>
|
|
263
|
-
new Date(p.fixTime).getTime() >= new Date(zoneInData.inTime.position.fixTime).getTime() &&
|
|
264
|
-
new Date(p.fixTime).getTime() < to.getTime()
|
|
265
|
-
)
|
|
266
|
-
zoneInOutData.push({
|
|
267
|
-
inTime: zoneInData.inTime.position,
|
|
268
|
-
distanceIn: calculateDistance(routeIn),
|
|
269
|
-
distanceOut: 0,
|
|
270
|
-
totalTime: totalInTime
|
|
271
|
-
})
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (!zoneInOutData.length) {
|
|
275
|
-
const geofenceIn = alerts.find(a => a.type === 'geofenceIn')
|
|
276
|
-
zoneInOutData.push({
|
|
277
|
-
distanceIn: geofenceIn ? calculateDistance(deviceRoute) : 0,
|
|
278
|
-
distanceOut: !geofenceIn ? calculateDistance(deviceRoute) : 0,
|
|
279
|
-
totalTime: to.getTime() - from.getTime()
|
|
280
|
-
})
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return zoneInOutData
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function analyseAlerts (alerts, deviceRoute, userData) {
|
|
198
|
+
function analyseAlerts (alerts, deviceRoute, userData, from, to) {
|
|
287
199
|
const zoneInOutData = []
|
|
288
200
|
const zoneInData = {}
|
|
289
201
|
|
|
@@ -301,13 +213,15 @@ function analyseAlerts (alerts, deviceRoute, userData) {
|
|
|
301
213
|
return
|
|
302
214
|
}
|
|
303
215
|
const outDate = new Date(a.position.fixTime).getTime()
|
|
216
|
+
const nextIn = getNextIn(outDate, alerts, a.geofenceId, deviceRoute)
|
|
304
217
|
const routeAfterOut = deviceRoute.filter(p =>
|
|
305
218
|
new Date(p.fixTime).getTime() >= outDate &&
|
|
306
|
-
new Date(p.fixTime).getTime() <
|
|
219
|
+
new Date(p.fixTime).getTime() < nextIn
|
|
307
220
|
)
|
|
221
|
+
const totalOutTime = nextIn - outDate
|
|
308
222
|
const distanceOut = calculateDistance(routeAfterOut)
|
|
309
223
|
if (zoneInData[a.geofenceId]) {
|
|
310
|
-
const totalInTime =
|
|
224
|
+
const totalInTime = new Date(a.position.fixTime).getTime() - new Date(zoneInData[a.geofenceId].position.fixTime).getTime()
|
|
311
225
|
const inDate = new Date(zoneInData[a.geofenceId].position.fixTime).getTime()
|
|
312
226
|
const routeIn = deviceRoute.filter(p =>
|
|
313
227
|
new Date(p.fixTime).getTime() >= inDate &&
|
|
@@ -316,18 +230,29 @@ function analyseAlerts (alerts, deviceRoute, userData) {
|
|
|
316
230
|
zoneInOutData.push({
|
|
317
231
|
inTime: zoneInData[a.geofenceId].position,
|
|
318
232
|
outTime: a.position,
|
|
319
|
-
|
|
233
|
+
totalInTime,
|
|
234
|
+
totalOutTime,
|
|
320
235
|
distanceIn: calculateDistance(routeIn),
|
|
321
236
|
distanceOut,
|
|
322
237
|
geofenceName: geofence.name,
|
|
238
|
+
geofenceId: geofence.id,
|
|
323
239
|
stopped: routeIn.filter(p => !p.attributes.ignition).length > 0,
|
|
324
240
|
driverName: zoneInData[a.geofenceId].position.driverName
|
|
325
241
|
})
|
|
326
242
|
zoneInData[a.geofenceId] = null
|
|
327
243
|
} else {
|
|
244
|
+
const totalInTime = new Date(a.position.fixTime).getTime() - from.getTime()
|
|
245
|
+
const routeIn = deviceRoute.filter(p =>
|
|
246
|
+
new Date(p.fixTime).getTime() >= from.getTime() &&
|
|
247
|
+
new Date(p.fixTime).getTime() < outDate
|
|
248
|
+
)
|
|
328
249
|
zoneInOutData.push({
|
|
329
250
|
outTime: a.position,
|
|
330
251
|
geofenceName: geofence.name,
|
|
252
|
+
geofenceId: geofence.id,
|
|
253
|
+
totalInTime,
|
|
254
|
+
totalOutTime,
|
|
255
|
+
distanceIn: calculateDistance(routeIn),
|
|
331
256
|
driverName: '',
|
|
332
257
|
distanceOut
|
|
333
258
|
})
|
|
@@ -339,15 +264,32 @@ function analyseAlerts (alerts, deviceRoute, userData) {
|
|
|
339
264
|
if (zoneInData[i]) {
|
|
340
265
|
const geofence = userData.geofences.find(g => g.id === zoneInData[i].geofenceId)
|
|
341
266
|
if (geofence) {
|
|
267
|
+
const totalInTime = to.getTime() - new Date(zoneInData[i].position.fixTime).getTime()
|
|
268
|
+
const routeIn = deviceRoute.filter(p =>
|
|
269
|
+
new Date(p.fixTime).getTime() >= new Date(zoneInData[i].position.fixTime).getTime() &&
|
|
270
|
+
new Date(p.fixTime).getTime() < to.getTime()
|
|
271
|
+
)
|
|
342
272
|
zoneInOutData.push({
|
|
343
273
|
inTime: zoneInData[i].position,
|
|
274
|
+
totalInTime,
|
|
275
|
+
distanceIn: calculateDistance(routeIn),
|
|
344
276
|
geofenceName: geofence.name,
|
|
277
|
+
geofenceId: geofence.id,
|
|
345
278
|
driverName: zoneInData[i].position.driverName
|
|
346
279
|
})
|
|
347
280
|
}
|
|
348
281
|
}
|
|
349
282
|
}
|
|
350
283
|
|
|
284
|
+
if (!zoneInOutData.length && userData.groupByDay) {
|
|
285
|
+
const geofenceIn = alerts.find(a => a.type === 'geofenceIn')
|
|
286
|
+
zoneInOutData.push({
|
|
287
|
+
distanceIn: geofenceIn ? calculateDistance(deviceRoute) : 0,
|
|
288
|
+
distanceOut: !geofenceIn ? calculateDistance(deviceRoute) : 0,
|
|
289
|
+
totalTime: to.getTime() - from.getTime()
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
|
|
351
293
|
return zoneInOutData
|
|
352
294
|
}
|
|
353
295
|
|
|
@@ -437,92 +379,67 @@ async function exportZoneReportToPDF (userData, reportData) {
|
|
|
437
379
|
translations.report.driver
|
|
438
380
|
]
|
|
439
381
|
if (reportData.devices) {
|
|
440
|
-
let first = true
|
|
441
382
|
// eslint-disable-next-line new-cap
|
|
442
383
|
const doc = new jsPDF.jsPDF('l')
|
|
443
384
|
await headerFromUser(doc, translations.report.titleZoneReport, userData.user)
|
|
385
|
+
const style = getStyle(getUserPartner(userData.user))
|
|
386
|
+
let space = 0
|
|
444
387
|
|
|
445
|
-
reportData.devices.forEach(d => {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
a.
|
|
468
|
-
a.distanceIn && a.distanceIn.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
|
|
469
|
-
convertMS(a.timeIn, false),
|
|
470
|
-
a.distanceOut && a.distanceOut.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
|
|
471
|
-
convertMS(a.timeOut, false)
|
|
388
|
+
reportData.devices.forEach((d, index) => {
|
|
389
|
+
if (userData.groupByDay) {
|
|
390
|
+
d.geofences.forEach((g, i) => {
|
|
391
|
+
const data = []
|
|
392
|
+
space = reportHeader(index === 0 && i === 0, doc, translations, d, lang, timezone, userData, g)
|
|
393
|
+
g.days.forEach(a => {
|
|
394
|
+
const temp = [
|
|
395
|
+
convertToLocaleDateString(a.date, lang, timezone),
|
|
396
|
+
a.firstIn ? convertToLocaleTimeString(a.firstIn, lang, timezone) : '-',
|
|
397
|
+
a.lastOut ? convertToLocaleTimeString(a.lastOut, lang, timezone) : '-',
|
|
398
|
+
a.distanceIn ? a.distanceIn.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
399
|
+
convertMS(a.totalInTime, false),
|
|
400
|
+
a.distanceOut ? a.distanceOut.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
401
|
+
convertMS(a.totalOutTime, false)
|
|
402
|
+
]
|
|
403
|
+
data.push(temp)
|
|
404
|
+
})
|
|
405
|
+
const footer = [
|
|
406
|
+
'Total:' + g.days.length,
|
|
407
|
+
'', '',
|
|
408
|
+
g.days.reduce((a, b) => a + (b.distanceIn ? b.distanceIn : 0), 0).toLocaleString(lang, { maximumFractionDigits: 2 }),
|
|
409
|
+
'',
|
|
410
|
+
g.days.reduce((a, b) => a + (b.distanceOut ? b.distanceOut : 0), 0).toLocaleString(lang, { maximumFractionDigits: 2 })
|
|
472
411
|
]
|
|
473
|
-
data
|
|
412
|
+
addTable(doc, headers, data, footer, style, space + 40, {
|
|
413
|
+
3: { halign: 'right' },
|
|
414
|
+
4: { halign: 'right' },
|
|
415
|
+
5: { halign: 'right' },
|
|
416
|
+
6: { halign: 'right' }
|
|
417
|
+
})
|
|
474
418
|
})
|
|
475
|
-
|
|
419
|
+
} else {
|
|
420
|
+
const data = []
|
|
421
|
+
space = reportHeader(index === 0, doc, translations, d, lang, timezone, userData)
|
|
422
|
+
d.geofences.forEach(a => {
|
|
476
423
|
const temp = [
|
|
477
424
|
geofenceEnter(userData.user, a),
|
|
478
425
|
geofenceExit(userData.user, a),
|
|
479
426
|
a.stopped ? translations.report.yes : translations.report.no,
|
|
480
|
-
|
|
481
|
-
a.distanceIn
|
|
482
|
-
a.distanceOut
|
|
427
|
+
convertMS(a.totalInTime, true),
|
|
428
|
+
a.distanceIn ? a.distanceIn.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
429
|
+
a.distanceOut ? a.distanceOut.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
483
430
|
a.geofenceName,
|
|
484
431
|
a.driverName
|
|
485
432
|
]
|
|
486
433
|
data.push(temp)
|
|
487
434
|
})
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
d.days.reduce((a, b) => a + b.distanceOut, 0).toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 })
|
|
496
|
-
]
|
|
497
|
-
: [
|
|
498
|
-
'Total:' + d.geofences.length
|
|
499
|
-
]
|
|
500
|
-
|
|
501
|
-
const style = getStyle(getUserPartner(userData.user))
|
|
502
|
-
doc.autoTable({
|
|
503
|
-
head: [headers],
|
|
504
|
-
body: data,
|
|
505
|
-
foot: [footValues],
|
|
506
|
-
showFoot: 'lastPage',
|
|
507
|
-
headStyles: {
|
|
508
|
-
fillColor: style.pdfHeaderColor,
|
|
509
|
-
textColor: style.pdfHeaderTextColor,
|
|
510
|
-
fontSize: 10
|
|
511
|
-
},
|
|
512
|
-
bodyStyles: {
|
|
513
|
-
fillColor: style.pdfBodyColor,
|
|
514
|
-
textColor: style.pdfBodyTextColor,
|
|
515
|
-
fontSize: 8
|
|
516
|
-
},
|
|
517
|
-
footStyles: {
|
|
518
|
-
fillColor: style.pdfFooterColor,
|
|
519
|
-
textColor: style.pdfFooterTextColor,
|
|
520
|
-
fontSize: 9
|
|
521
|
-
},
|
|
522
|
-
startY: space + 35
|
|
523
|
-
})
|
|
435
|
+
const footer = ['Total:' + d.geofences.length]
|
|
436
|
+
addTable(doc, headers, data, footer, style, space + 35, {
|
|
437
|
+
3: { halign: 'right' },
|
|
438
|
+
4: { halign: 'right' },
|
|
439
|
+
5: { halign: 'right' }
|
|
440
|
+
})
|
|
441
|
+
}
|
|
524
442
|
})
|
|
525
|
-
|
|
526
443
|
return doc
|
|
527
444
|
}
|
|
528
445
|
}
|
|
@@ -538,21 +455,22 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
538
455
|
}
|
|
539
456
|
const headers = userData.groupByDay
|
|
540
457
|
? [
|
|
458
|
+
{ label: translations.report.geofence, value: 'zone' },
|
|
541
459
|
{ label: translations.report.vehicle, value: 'name' },
|
|
542
460
|
{ label: translations.report.date, value: 'date' },
|
|
543
461
|
{ label: translations.report.firstIn, value: 'firstIn' },
|
|
544
462
|
{ label: translations.report.lastOut, value: 'lastOut' },
|
|
545
463
|
{ label: translations.report.distanceIn || 'Kms Adentro', value: 'distanceIn' },
|
|
546
|
-
{ label: translations.report.timeIn, value: '
|
|
464
|
+
{ label: translations.report.timeIn, value: 'totalInTime' },
|
|
547
465
|
{ label: translations.report.distanceOut || 'Kms Afuera', value: 'distanceOut' },
|
|
548
|
-
{ label: translations.report.timeOut, value: '
|
|
466
|
+
{ label: translations.report.timeOut, value: 'totalOutTime' }
|
|
549
467
|
]
|
|
550
468
|
: [
|
|
551
469
|
{ label: translations.report.vehicle, value: 'name' },
|
|
552
470
|
{ label: translations.report.enter, value: 'enter' },
|
|
553
471
|
{ label: translations.report.exit, value: 'exit' },
|
|
554
472
|
{ label: translations.report.stopped, value: 'stopped' },
|
|
555
|
-
{ label: translations.report.duration, value: '
|
|
473
|
+
{ label: translations.report.duration, value: 'totalInTime' },
|
|
556
474
|
{ label: translations.report.distanceIn || 'Kms Adentro', value: 'distanceIn' },
|
|
557
475
|
{ label: translations.report.distanceOut || 'Kms Afuera', value: 'distanceOut' },
|
|
558
476
|
{ label: translations.report.geofence, value: 'zone' },
|
|
@@ -561,33 +479,20 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
561
479
|
let data = []
|
|
562
480
|
if (reportData.devices) {
|
|
563
481
|
reportData.devices.forEach(d => {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
}))
|
|
577
|
-
: data.concat(d.geofences.map(a => {
|
|
578
|
-
return {
|
|
579
|
-
...a,
|
|
580
|
-
name: d.device.name,
|
|
581
|
-
enter: geofenceEnter(userData.user, a),
|
|
582
|
-
exit: geofenceExit(userData.user, a),
|
|
583
|
-
stopped: a.stopped ? translations.report.yes : translations.report.no,
|
|
584
|
-
duration: a.totalTime ? convertMS(a.totalTime * 1000, true) : '',
|
|
585
|
-
distanceIn: a.distanceIn && a.distanceIn.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
|
|
586
|
-
distanceOut: a.distanceOut && a.distanceOut.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
|
|
587
|
-
zone: a.geofenceName,
|
|
588
|
-
driver: a.driverName
|
|
589
|
-
}
|
|
482
|
+
if (userData.groupByDay) {
|
|
483
|
+
d.geofences.forEach(g => {
|
|
484
|
+
data = data.concat([{ zone: g.geofenceName }])
|
|
485
|
+
data = data.concat(g.days.map(a => {
|
|
486
|
+
return getColumns(d, a, userData, translations)
|
|
487
|
+
}))
|
|
488
|
+
data = data.concat([{}])
|
|
489
|
+
})
|
|
490
|
+
} else {
|
|
491
|
+
data = data.concat(d.geofences.map(a => {
|
|
492
|
+
return getColumns(d, a, userData, translations)
|
|
590
493
|
}))
|
|
494
|
+
data = data.concat([{}])
|
|
495
|
+
}
|
|
591
496
|
})
|
|
592
497
|
return {
|
|
593
498
|
headers,
|
|
@@ -597,6 +502,46 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
597
502
|
}
|
|
598
503
|
}
|
|
599
504
|
|
|
505
|
+
function reportHeader (first, doc, translations, device, lang, timezone, userData, geofence) {
|
|
506
|
+
const name = deviceName(device.device)
|
|
507
|
+
const group = userData.groups.find(g => device.device.groupId === g.id)
|
|
508
|
+
|
|
509
|
+
const space = first ? 8 : 0
|
|
510
|
+
if (!first) {
|
|
511
|
+
doc.addPage()
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
doc.setFontSize(13)
|
|
515
|
+
doc.text(name, 20, space + 20)
|
|
516
|
+
doc.setFontSize(11)
|
|
517
|
+
doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space + 20)
|
|
518
|
+
doc.text(convertToLocaleString(device.from, lang, timezone) + ' - ' + convertToLocaleString(device.to, lang, timezone), 20, space + 25)
|
|
519
|
+
if (userData.groupByDay) {
|
|
520
|
+
doc.text(translations.report.geofence + ': ' + geofence.geofenceName, 20, space + 30)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return space
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function getColumns (device, data, userData, translations) {
|
|
527
|
+
return {
|
|
528
|
+
...data,
|
|
529
|
+
name: device.device.name,
|
|
530
|
+
enter: geofenceEnter(userData.user, data),
|
|
531
|
+
exit: geofenceExit(userData.user, data),
|
|
532
|
+
stopped: data.stopped ? translations.report.yes : translations.report.no,
|
|
533
|
+
date: convertToLocaleDateString(data.date, userData.user.attributes.lang, userData.user.attributes.timezone),
|
|
534
|
+
firstIn: data.firstIn ? convertToLocaleTimeString(data.firstIn, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
|
|
535
|
+
lastOut: data.lastOut ? convertToLocaleTimeString(data.lastOut, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
|
|
536
|
+
distanceIn: data.distanceIn ? data.distanceIn.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }) : 0,
|
|
537
|
+
distanceOut: data.distanceOut ? data.distanceOut.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }) : 0,
|
|
538
|
+
totalInTime: convertMS(data.totalInTime, !userData.groupByDay),
|
|
539
|
+
totalOutTime: convertMS(data.totalOutTime, !userData.groupByDay),
|
|
540
|
+
zone: data.geofenceName,
|
|
541
|
+
driver: data.driverName
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
600
545
|
function deviceName (device) {
|
|
601
546
|
return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
|
|
602
547
|
}
|