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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/zone-report.js +173 -228
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.678",
3
+ "version": "1.0.680",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -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.groupByDay
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 (zoneInOutData.length > 0) {
104
- const result = userData.onlyWithStop ? zoneInOutData.filter(d => d.stopped) : zoneInOutData
100
+ if (userData.groupByDay) {
101
+ const dates = getDates(from, to)
105
102
 
106
- if (userData.groupByDay) {
107
- const dates = getDates(from, to)
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 zoneInOutDayData = result.filter(z => (!z.inTime || (new Date(z.inTime.fixTime) < toByDay)) &&
115
- (!z.outTime || (new Date(z.outTime.fixTime) > fromByDay)))
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.totalTime || 0), 0) : 0
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) > new Date(zoneInOutDayData[0].inTime.fixTime)) &&
136
- new Date(p.fixTime) < fromByDay)
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
- new Date(p.fixTime).getTime() >= fromByDay.getTime()
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) < outTime && new Date(p.fixTime) > toByDay)
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) > new Date(zoneInOutDayData[zoneInOutDayData.length - 1].outTime.fixTime).getTime() &&
156
- new Date(p.fixTime) < toByDay.getTime())
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
- timeOut: (24 * 60 * 60 * 1000) - timeIn
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
- days: dataByDay
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 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
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() < getNextIn(outDate, alerts, a.geofenceId, deviceRoute)
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 = moment(a.position.fixTime).diff(moment(zoneInData[a.geofenceId].position.fixTime), 'seconds')
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
- totalTime: totalInTime,
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
- const data = []
447
- const name = deviceName(d.device)
448
- const group = userData.groups.find(g => d.device.groupId === g.id)
449
-
450
- let space = 0
451
- if (!first) {
452
- doc.addPage()
453
- } else {
454
- first = false
455
- space = 10
456
- }
457
- doc.setFontSize(13)
458
- doc.text(name, 20, space + 20)
459
- doc.setFontSize(11)
460
- doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space + 20)
461
- doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space + 25)
462
- userData.groupByDay
463
- ? d.days.forEach(a => {
464
- const temp = [
465
- convertToLocaleDateString(a.date, userData.user.attributes.lang, userData.user.attributes.timezone),
466
- a.firstIn ? convertToLocaleTimeString(a.firstIn, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
467
- a.lastOut ? convertToLocaleTimeString(a.lastOut, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
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.push(temp)
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
- : d.geofences.forEach(a => {
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
- a.totalTime ? convertMS(a.totalTime * 1000, true) : '',
481
- a.distanceIn && a.distanceIn.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }),
482
- a.distanceOut && a.distanceOut.toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }),
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
- const footValues = userData.groupByDay
490
- ? [
491
- 'Total:' + d.days.length,
492
- '', '',
493
- d.days.reduce((a, b) => a + b.distanceIn, 0).toLocaleString(userData.user.attributes.lang, { maximumFractionDigits: 2 }),
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: 'timeIn' },
464
+ { label: translations.report.timeIn, value: 'totalInTime' },
547
465
  { label: translations.report.distanceOut || 'Kms Afuera', value: 'distanceOut' },
548
- { label: translations.report.timeOut, value: 'timeOut' }
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: 'duration' },
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
- data = userData.groupByDay
565
- ? data.concat(d.days.map(a => {
566
- return {
567
- name: d.device.name,
568
- date: convertToLocaleDateString(a.date, userData.user.attributes.lang, userData.user.attributes.timezone),
569
- firstIn: a.firstIn ? convertToLocaleTimeString(a.firstIn, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
570
- lastOut: a.lastOut ? convertToLocaleTimeString(a.lastOut, userData.user.attributes.lang, userData.user.attributes.timezone) : '-',
571
- distanceIn: a.distanceIn && a.distanceIn.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
572
- distanceOut: a.distanceOut && a.distanceOut.toLocaleString(this.user.attributes.lang, { maximumFractionDigits: 2 }),
573
- timeIn: convertMS(a.timeIn),
574
- timeOut: convertMS(a.timeOut)
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
  }