fleetmap-reports 1.0.678 → 1.0.679
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 +196 -260
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,76 +95,82 @@ 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
100
|
if (zoneInOutData.length > 0) {
|
|
104
|
-
const result = userData.onlyWithStop ? zoneInOutData.filter(d => d.stopped) : zoneInOutData
|
|
105
|
-
|
|
106
101
|
if (userData.groupByDay) {
|
|
107
102
|
const dates = getDates(from, to)
|
|
108
103
|
|
|
109
|
-
const
|
|
110
|
-
for (const
|
|
111
|
-
const
|
|
112
|
-
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
104
|
+
const geofencesData = []
|
|
105
|
+
for (const geofence of userData.geofences) {
|
|
106
|
+
const filteredByGeofence = zoneInOutData.filter(d => d.geofenceId === geofence.id)
|
|
113
107
|
|
|
114
|
-
const
|
|
115
|
-
|
|
108
|
+
const dataByDay = []
|
|
109
|
+
for (const date of dates) {
|
|
110
|
+
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
111
|
+
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
const dayRoute = deviceRoute.filter(p => new Date(p.fixTime) >= fromByDay && new Date(p.fixTime) < toByDay)
|
|
114
|
+
const zoneInOutDayData = filteredByGeofence.filter(z => (!z.inTime || (new Date(z.inTime.fixTime) < toByDay)) &&
|
|
115
|
+
(!z.outTime || (new Date(z.outTime.fixTime) > fromByDay)))
|
|
119
116
|
|
|
120
|
-
|
|
117
|
+
const firstIn = zoneInOutDayData.find(z => z.inTime && new Date(z.inTime.fixTime) > fromByDay)
|
|
118
|
+
const lastOut = zoneInOutDayData.slice().reverse().find(z => z.outTime && new Date(z.outTime.fixTime) < toByDay)
|
|
121
119
|
|
|
122
|
-
|
|
123
|
-
let distanceOut = 0
|
|
124
|
-
if (zoneInOutDayData.length) {
|
|
125
|
-
distanceOut = zoneInOutDayData.reduce((a, b) => a + (b.distanceOut || 0), 0) - zoneInOutDayData[zoneInOutDayData.length - 1].distanceOut
|
|
126
|
-
} else {
|
|
127
|
-
distanceOut = calculateDistance(deviceRoute.filter(p => new Date(p.fixTime) >= fromByDay && new Date(p.fixTime) < toByDay))
|
|
128
|
-
}
|
|
120
|
+
let timeIn = zoneInOutDayData.length ? zoneInOutDayData.reduce((a, b) => a + (b.totalInTime || 0), 0) : 0
|
|
129
121
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
timeIn = timeIn - (fromByDay.getTime() - inTime.getTime())
|
|
135
|
-
const routeDayBefore = deviceRoute.filter(p => (!zoneInOutDayData[0].inTime || new Date(p.fixTime) > new Date(zoneInOutDayData[0].inTime.fixTime)) &&
|
|
136
|
-
new Date(p.fixTime) < fromByDay)
|
|
137
|
-
distanceIn = distanceIn - calculateDistance(routeDayBefore)
|
|
122
|
+
let distanceIn = zoneInOutDayData.length && dayRoute.length ? zoneInOutDayData.reduce((a, b) => a + (b.distanceIn || 0), 0) : 0
|
|
123
|
+
let distanceOut = 0
|
|
124
|
+
if (zoneInOutDayData.length) {
|
|
125
|
+
distanceOut = zoneInOutDayData.reduce((a, b) => a + (b.distanceOut || 0), 0) - zoneInOutDayData[zoneInOutDayData.length - 1].distanceOut
|
|
138
126
|
} else {
|
|
139
|
-
|
|
140
|
-
const routeOut = deviceRoute.filter(p =>
|
|
141
|
-
new Date(p.fixTime).getTime() < new Date(zoneInOutDayData[0].inTime.fixTime).getTime() &&
|
|
142
|
-
new Date(p.fixTime).getTime() >= fromByDay.getTime()
|
|
143
|
-
)
|
|
144
|
-
distanceOut = distanceOut + calculateDistance(routeOut)
|
|
127
|
+
distanceOut = calculateDistance(deviceRoute.filter(p => new Date(p.fixTime) >= fromByDay && new Date(p.fixTime) < toByDay))
|
|
145
128
|
}
|
|
146
129
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
130
|
+
if (zoneInOutDayData.length) {
|
|
131
|
+
// Check if the first entry starts only on the day before
|
|
132
|
+
if (!zoneInOutDayData[0].inTime || new Date(zoneInOutDayData[0].inTime.fixTime) < fromByDay) {
|
|
133
|
+
const inTime = zoneInOutDayData[0].inTime ? new Date(zoneInOutDayData[0].inTime.fixTime) : from
|
|
134
|
+
timeIn = timeIn - (fromByDay.getTime() - inTime.getTime())
|
|
135
|
+
const routeDayBefore = deviceRoute.filter(p => (!zoneInOutDayData[0].inTime || new Date(p.fixTime) >= new Date(zoneInOutDayData[0].inTime.fixTime)) &&
|
|
136
|
+
new Date(p.fixTime) < fromByDay)
|
|
137
|
+
distanceIn = distanceIn - calculateDistance(routeDayBefore)
|
|
138
|
+
} else {
|
|
139
|
+
// Add distanceOut before the first entry
|
|
140
|
+
const routeOut = deviceRoute.filter(p =>
|
|
141
|
+
new Date(p.fixTime).getTime() < new Date(zoneInOutDayData[0].inTime.fixTime).getTime() &&
|
|
142
|
+
new Date(p.fixTime).getTime() >= fromByDay.getTime()
|
|
143
|
+
)
|
|
144
|
+
distanceOut = distanceOut + calculateDistance(routeOut)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check if the last entry ends only on the next day
|
|
148
|
+
if (!zoneInOutDayData[zoneInOutDayData.length - 1].outTime || new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime) > toByDay) {
|
|
149
|
+
const outTime = zoneInOutDayData[zoneInOutDayData.length - 1].outTime ? new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime) : to
|
|
150
|
+
timeIn = timeIn - (outTime.getTime() - (toByDay.getTime() + 1000))
|
|
151
|
+
const routeDayAfter = deviceRoute.filter(p => new Date(p.fixTime) <= outTime && new Date(p.fixTime) > toByDay)
|
|
152
|
+
distanceIn = distanceIn - calculateDistance(routeDayAfter)
|
|
153
|
+
} else {
|
|
154
|
+
const routeOut = deviceRoute.filter(p =>
|
|
155
|
+
new Date(p.fixTime) >= new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime).getTime() &&
|
|
156
|
+
new Date(p.fixTime) < toByDay.getTime())
|
|
157
|
+
distanceOut = distanceOut + calculateDistance(routeOut)
|
|
158
|
+
}
|
|
158
159
|
}
|
|
160
|
+
dataByDay.push({
|
|
161
|
+
date,
|
|
162
|
+
firstIn: firstIn ? firstIn.inTime.fixTime : undefined,
|
|
163
|
+
lastOut: lastOut ? lastOut.outTime.fixTime : undefined,
|
|
164
|
+
distanceIn: distanceIn > 0 ? distanceIn : 0,
|
|
165
|
+
distanceOut,
|
|
166
|
+
totalInTime: timeIn,
|
|
167
|
+
totalOutTime: (24 * 60 * 60 * 1000) - timeIn
|
|
168
|
+
})
|
|
159
169
|
}
|
|
160
170
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
lastOut: lastOut ? lastOut.outTime.fixTime : undefined,
|
|
165
|
-
distanceIn,
|
|
166
|
-
distanceOut,
|
|
167
|
-
timeIn,
|
|
168
|
-
timeOut: (24 * 60 * 60 * 1000) - timeIn
|
|
171
|
+
geofencesData.push({
|
|
172
|
+
geofenceName: geofence.name,
|
|
173
|
+
days: dataByDay
|
|
169
174
|
})
|
|
170
175
|
}
|
|
171
176
|
|
|
@@ -173,117 +178,24 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
173
178
|
device: d,
|
|
174
179
|
from,
|
|
175
180
|
to,
|
|
176
|
-
|
|
181
|
+
groupByDay: true,
|
|
182
|
+
geofences: geofencesData
|
|
177
183
|
})
|
|
178
184
|
} else {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
geofences: result
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return devicesResult
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function analyseAlertsGroupGeofences (alerts, deviceRoute, from, to) {
|
|
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
|
|
185
|
+
devicesResult.push({
|
|
186
|
+
device: d,
|
|
187
|
+
from,
|
|
188
|
+
to,
|
|
189
|
+
geofences: zoneInOutData
|
|
254
190
|
})
|
|
255
|
-
zoneInData.inTime = undefined
|
|
256
191
|
}
|
|
257
192
|
}
|
|
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
193
|
}
|
|
273
194
|
|
|
274
|
-
|
|
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
|
|
195
|
+
return devicesResult
|
|
284
196
|
}
|
|
285
197
|
|
|
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,9 +264,17 @@ 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
|
}
|
|
@@ -437,92 +370,67 @@ async function exportZoneReportToPDF (userData, reportData) {
|
|
|
437
370
|
translations.report.driver
|
|
438
371
|
]
|
|
439
372
|
if (reportData.devices) {
|
|
440
|
-
let first = true
|
|
441
373
|
// eslint-disable-next-line new-cap
|
|
442
374
|
const doc = new jsPDF.jsPDF('l')
|
|
443
375
|
await headerFromUser(doc, translations.report.titleZoneReport, userData.user)
|
|
376
|
+
const style = getStyle(getUserPartner(userData.user))
|
|
377
|
+
let space = 0
|
|
444
378
|
|
|
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)
|
|
379
|
+
reportData.devices.forEach((d, index) => {
|
|
380
|
+
if (userData.groupByDay) {
|
|
381
|
+
d.geofences.forEach((g, i) => {
|
|
382
|
+
const data = []
|
|
383
|
+
space = reportHeader(index === 0 && i === 0, doc, translations, d, lang, timezone, userData, g)
|
|
384
|
+
g.days.forEach(a => {
|
|
385
|
+
const temp = [
|
|
386
|
+
convertToLocaleDateString(a.date, lang, timezone),
|
|
387
|
+
a.firstIn ? convertToLocaleTimeString(a.firstIn, lang, timezone) : '-',
|
|
388
|
+
a.lastOut ? convertToLocaleTimeString(a.lastOut, lang, timezone) : '-',
|
|
389
|
+
a.distanceIn ? a.distanceIn.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
390
|
+
convertMS(a.totalInTime, false),
|
|
391
|
+
a.distanceOut ? a.distanceOut.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
392
|
+
convertMS(a.totalOutTime, false)
|
|
393
|
+
]
|
|
394
|
+
data.push(temp)
|
|
395
|
+
})
|
|
396
|
+
const footer = [
|
|
397
|
+
'Total:' + g.days.length,
|
|
398
|
+
'', '',
|
|
399
|
+
g.days.reduce((a, b) => a + (b.distanceIn ? b.distanceIn : 0), 0).toLocaleString(lang, { maximumFractionDigits: 2 }),
|
|
400
|
+
'',
|
|
401
|
+
g.days.reduce((a, b) => a + (b.distanceOut ? b.distanceOut : 0), 0).toLocaleString(lang, { maximumFractionDigits: 2 })
|
|
472
402
|
]
|
|
473
|
-
data
|
|
403
|
+
addTable(doc, headers, data, footer, style, space + 40, {
|
|
404
|
+
3: { halign: 'right' },
|
|
405
|
+
4: { halign: 'right' },
|
|
406
|
+
5: { halign: 'right' },
|
|
407
|
+
6: { halign: 'right' }
|
|
408
|
+
})
|
|
474
409
|
})
|
|
475
|
-
|
|
410
|
+
} else {
|
|
411
|
+
const data = []
|
|
412
|
+
space = reportHeader(index === 0, doc, translations, d, lang, timezone, userData)
|
|
413
|
+
d.geofences.forEach(a => {
|
|
476
414
|
const temp = [
|
|
477
415
|
geofenceEnter(userData.user, a),
|
|
478
416
|
geofenceExit(userData.user, a),
|
|
479
417
|
a.stopped ? translations.report.yes : translations.report.no,
|
|
480
|
-
|
|
481
|
-
a.distanceIn
|
|
482
|
-
a.distanceOut
|
|
418
|
+
convertMS(a.totalInTime, true),
|
|
419
|
+
a.distanceIn ? a.distanceIn.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
420
|
+
a.distanceOut ? a.distanceOut.toLocaleString(lang, { maximumFractionDigits: 2 }) : 0,
|
|
483
421
|
a.geofenceName,
|
|
484
422
|
a.driverName
|
|
485
423
|
]
|
|
486
424
|
data.push(temp)
|
|
487
425
|
})
|
|
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
|
-
})
|
|
426
|
+
const footer = ['Total:' + d.geofences.length]
|
|
427
|
+
addTable(doc, headers, data, footer, style, space + 35, {
|
|
428
|
+
3: { halign: 'right' },
|
|
429
|
+
4: { halign: 'right' },
|
|
430
|
+
5: { halign: 'right' }
|
|
431
|
+
})
|
|
432
|
+
}
|
|
524
433
|
})
|
|
525
|
-
|
|
526
434
|
return doc
|
|
527
435
|
}
|
|
528
436
|
}
|
|
@@ -538,21 +446,22 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
538
446
|
}
|
|
539
447
|
const headers = userData.groupByDay
|
|
540
448
|
? [
|
|
449
|
+
{ label: translations.report.geofence, value: 'zone' },
|
|
541
450
|
{ label: translations.report.vehicle, value: 'name' },
|
|
542
451
|
{ label: translations.report.date, value: 'date' },
|
|
543
452
|
{ label: translations.report.firstIn, value: 'firstIn' },
|
|
544
453
|
{ label: translations.report.lastOut, value: 'lastOut' },
|
|
545
454
|
{ label: translations.report.distanceIn || 'Kms Adentro', value: 'distanceIn' },
|
|
546
|
-
{ label: translations.report.timeIn, value: '
|
|
455
|
+
{ label: translations.report.timeIn, value: 'totalInTime' },
|
|
547
456
|
{ label: translations.report.distanceOut || 'Kms Afuera', value: 'distanceOut' },
|
|
548
|
-
{ label: translations.report.timeOut, value: '
|
|
457
|
+
{ label: translations.report.timeOut, value: 'totalOutTime' }
|
|
549
458
|
]
|
|
550
459
|
: [
|
|
551
460
|
{ label: translations.report.vehicle, value: 'name' },
|
|
552
461
|
{ label: translations.report.enter, value: 'enter' },
|
|
553
462
|
{ label: translations.report.exit, value: 'exit' },
|
|
554
463
|
{ label: translations.report.stopped, value: 'stopped' },
|
|
555
|
-
{ label: translations.report.duration, value: '
|
|
464
|
+
{ label: translations.report.duration, value: 'totalInTime' },
|
|
556
465
|
{ label: translations.report.distanceIn || 'Kms Adentro', value: 'distanceIn' },
|
|
557
466
|
{ label: translations.report.distanceOut || 'Kms Afuera', value: 'distanceOut' },
|
|
558
467
|
{ label: translations.report.geofence, value: 'zone' },
|
|
@@ -561,33 +470,20 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
561
470
|
let data = []
|
|
562
471
|
if (reportData.devices) {
|
|
563
472
|
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
|
-
}
|
|
473
|
+
if (userData.groupByDay) {
|
|
474
|
+
d.geofences.forEach(g => {
|
|
475
|
+
data = data.concat([{ zone: g.geofenceName }])
|
|
476
|
+
data = data.concat(g.days.map(a => {
|
|
477
|
+
return getColumns(d, a, userData, translations)
|
|
478
|
+
}))
|
|
479
|
+
data = data.concat([{}])
|
|
480
|
+
})
|
|
481
|
+
} else {
|
|
482
|
+
data = data.concat(d.geofences.map(a => {
|
|
483
|
+
return getColumns(d, a, userData, translations)
|
|
590
484
|
}))
|
|
485
|
+
data = data.concat([{}])
|
|
486
|
+
}
|
|
591
487
|
})
|
|
592
488
|
return {
|
|
593
489
|
headers,
|
|
@@ -597,6 +493,46 @@ function exportZoneReportToExcel (userData, reportData) {
|
|
|
597
493
|
}
|
|
598
494
|
}
|
|
599
495
|
|
|
496
|
+
function reportHeader (first, doc, translations, device, lang, timezone, userData, geofence) {
|
|
497
|
+
const name = deviceName(device.device)
|
|
498
|
+
const group = userData.groups.find(g => device.device.groupId === g.id)
|
|
499
|
+
|
|
500
|
+
const space = first ? 8 : 0
|
|
501
|
+
if (!first) {
|
|
502
|
+
doc.addPage()
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
doc.setFontSize(13)
|
|
506
|
+
doc.text(name, 20, space + 20)
|
|
507
|
+
doc.setFontSize(11)
|
|
508
|
+
doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space + 20)
|
|
509
|
+
doc.text(convertToLocaleString(device.from, lang, timezone) + ' - ' + convertToLocaleString(device.to, lang, timezone), 20, space + 25)
|
|
510
|
+
if (userData.groupByDay) {
|
|
511
|
+
doc.text(translations.report.geofence + ': ' + geofence.geofenceName, 20, space + 30)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return space
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function getColumns (device, data, userData, translations) {
|
|
518
|
+
return {
|
|
519
|
+
...data,
|
|
520
|
+
name: device.device.name,
|
|
521
|
+
enter: geofenceEnter(userData.user, data),
|
|
522
|
+
exit: geofenceExit(userData.user, data),
|
|
523
|
+
stopped: data.stopped ? translations.report.yes : translations.report.no,
|
|
524
|
+
date: convertToLocaleDateString(data.date, userData.user.attributes.lang, userData.user.attributes.timezone),
|
|
525
|
+
firstIn: data.firstIn ? convertToLocaleTimeString(data.firstIn, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
|
|
526
|
+
lastOut: data.lastOut ? convertToLocaleTimeString(data.lastOut, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
|
|
527
|
+
distanceIn: data.distanceIn ? data.distanceIn.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }) : 0,
|
|
528
|
+
distanceOut: data.distanceOut ? data.distanceOut.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }) : 0,
|
|
529
|
+
totalInTime: convertMS(data.totalInTime, !userData.groupByDay),
|
|
530
|
+
totalOutTime: convertMS(data.totalOutTime, !userData.groupByDay),
|
|
531
|
+
zone: data.geofenceName,
|
|
532
|
+
driver: data.driverName
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
600
536
|
function deviceName (device) {
|
|
601
537
|
return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
|
|
602
538
|
}
|