fleetmap-reports 2.0.358 → 2.0.360

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 (82) hide show
  1. package/package.json +1 -1
  2. package/src/partnerReports/driverranking-report.js +39 -7
  3. package/src/util/utils.js +3 -0
  4. package/.claude/worktrees/eager-stonebraker-c08ac7/.eslintrc.js +0 -15
  5. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/enGB.js +0 -309
  6. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/esCL.js +0 -297
  7. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/frFR.json +0 -324
  8. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/index.js +0 -35
  9. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptBR.js +0 -301
  10. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptPT.js +0 -310
  11. package/.claude/worktrees/eager-stonebraker-c08ac7/package-lock.json +0 -11944
  12. package/.claude/worktrees/eager-stonebraker-c08ac7/package.json +0 -45
  13. package/.claude/worktrees/eager-stonebraker-c08ac7/src/activity-report.js +0 -822
  14. package/.claude/worktrees/eager-stonebraker-c08ac7/src/automaticReports.js +0 -34
  15. package/.claude/worktrees/eager-stonebraker-c08ac7/src/carbone/index.js +0 -13
  16. package/.claude/worktrees/eager-stonebraker-c08ac7/src/custom/vistawasteActivity-report.js +0 -544
  17. package/.claude/worktrees/eager-stonebraker-c08ac7/src/events-report.js +0 -360
  18. package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-consumption-report.js +0 -296
  19. package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-drop-report.js +0 -128
  20. package/.claude/worktrees/eager-stonebraker-c08ac7/src/here.js +0 -172
  21. package/.claude/worktrees/eager-stonebraker-c08ac7/src/idle-report.js +0 -403
  22. package/.claude/worktrees/eager-stonebraker-c08ac7/src/index.js +0 -244
  23. package/.claude/worktrees/eager-stonebraker-c08ac7/src/kms-report.js +0 -549
  24. package/.claude/worktrees/eager-stonebraker-c08ac7/src/location-report.js +0 -496
  25. package/.claude/worktrees/eager-stonebraker-c08ac7/src/machines-report.js +0 -278
  26. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/afriquia.js +0 -129
  27. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/dailyuse-report.js +0 -80
  28. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/delayedstart-report.js +0 -223
  29. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/driverranking-report.js +0 -328
  30. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/gpsjump-report.js +0 -61
  31. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/performance-report.js +0 -359
  32. package/.claude/worktrees/eager-stonebraker-c08ac7/src/refueling-report.js +0 -345
  33. package/.claude/worktrees/eager-stonebraker-c08ac7/src/reportStyle.js +0 -34
  34. package/.claude/worktrees/eager-stonebraker-c08ac7/src/sensor-report.js +0 -447
  35. package/.claude/worktrees/eager-stonebraker-c08ac7/src/speeding-report.js +0 -663
  36. package/.claude/worktrees/eager-stonebraker-c08ac7/src/stop-report.js +0 -242
  37. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ActivityReportTemplate.mjml +0 -51
  38. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EmptyReportTemplate.mjml +0 -25
  39. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EventsReportTemplate.mjml +0 -75
  40. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/FuelDropReportTemplate.mjml +0 -60
  41. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/IdleReportTemplate.mjml +0 -54
  42. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportGroupByDayTemplate.mjml +0 -43
  43. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportTemplate.mjml +0 -44
  44. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/LocationReportTemplate.mjml +0 -37
  45. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/RefuelingReportTemplate.mjml +0 -60
  46. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SensorReportTemplate.mjml +0 -23
  47. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SpeedingReportTemplate.mjml +0 -80
  48. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/TripReportTemplate.mjml +0 -97
  49. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ZoneReportTemplate.mjml +0 -52
  50. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/report.mjml +0 -96
  51. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/activity.test.js +0 -99
  52. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/carbone.test.js +0 -20
  53. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/events.test.js +0 -30
  54. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/fuel.test.js +0 -35
  55. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/idle.test.js +0 -16
  56. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.js +0 -24
  57. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.test.js +0 -203
  58. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/kms.test.js +0 -74
  59. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/performance.test.js +0 -36
  60. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/positions.test.js +0 -67
  61. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/speeding.test.js +0 -120
  62. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/translations.test.js +0 -21
  63. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/trips.test.js +0 -140
  64. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/zones.test.js +0 -162
  65. package/.claude/worktrees/eager-stonebraker-c08ac7/src/trip-report.js +0 -641
  66. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/device.js +0 -13
  67. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/driver.js +0 -90
  68. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/fuel.js +0 -102
  69. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/geofence.js +0 -52
  70. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/odoo.js +0 -18
  71. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/parallel.js +0 -64
  72. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/pdfDocument.js +0 -140
  73. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/route.js +0 -78
  74. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/timetable.js +0 -30
  75. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.js +0 -213
  76. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.worker.js +0 -49
  77. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/trips.js +0 -270
  78. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/utils.js +0 -358
  79. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/worker.js +0 -14
  80. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/xpert.js +0 -58
  81. package/.claude/worktrees/eager-stonebraker-c08ac7/src/word/index.js +0 -95
  82. package/.claude/worktrees/eager-stonebraker-c08ac7/src/zone-report.js +0 -904
@@ -1,822 +0,0 @@
1
- const automaticReports = require('./automaticReports')
2
- const {
3
- convertMS, getDates, getTranslations, weekDaySelected, convertToLocaleString, isClientSide,
4
- getLanguage, executeServerSide
5
- } = require('./util/utils')
6
- const jsPDF = require('jspdf')
7
- require('jspdf-autotable')
8
- const {
9
- headerFromUser, addTable,
10
- pdfPageByDay
11
- } = require('./util/pdfDocument')
12
- const { getStyle } = require('./reportStyle')
13
- const { getUserPartner } = require('fleetmap-partners')
14
- const traccar = require('./util/traccar')
15
- const { isInsideTimetable, isPartialInsideTimetable, calculateTrip, getDataByDay, getKms, calculateMultiDayTrips } = require('./util/trips')
16
- const { devicesToProcess } = require('./util/device')
17
- const { getDriverData } = require('./util/driver')
18
- const { calculateConsumption } = require('./util/fuel')
19
- const { getSummaryByDay } = require('./util/traccar')
20
-
21
- const fileName = 'ActivityReport'
22
-
23
- async function createActivityReport (from, to, userData, traccarInstance) {
24
- console.log('Create ActivityReport')
25
- const reportData = []
26
-
27
- if (userData.byDriver) {
28
- const allData = await createActivityReportByDriver(from, to, userData, traccarInstance)
29
- reportData.push(allData)
30
- } else if (userData.byGroup) {
31
- const allData = await createActivityReportByGroup(from, to, userData, traccarInstance)
32
- reportData.push(...allData)
33
- } else {
34
- const allData = await createActivityReportByDevice(from, to, userData, traccarInstance)
35
- reportData.push(allData)
36
- }
37
-
38
- return reportData
39
- }
40
-
41
- async function createActivityReportByGroup (from, to, userData, traccarInstance) {
42
- console.log('ByGroup')
43
- const reportData = []
44
- for (const g of userData.groups) {
45
- const devices = userData.devices.filter(d => d.groupId === g.id)
46
- console.log(g.name + ' devices:' + devices.length)
47
- if (devices.length > 0) {
48
- const groupData = {
49
- devices: [],
50
- group: g,
51
- xpert: devices.filter(d => d.attributes.xpert).length > 0,
52
- from,
53
- to
54
- }
55
-
56
- const response = await traccarInstance.reports.reportsSummaryGet(from, to, null, [g.id])
57
- const summary = response.data
58
-
59
- const responseTrips = await traccarInstance.reports.reportsTripsGet(from, to, null, [g.id])
60
- const trips = responseTrips.data
61
-
62
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
63
-
64
- if (summary.length > 0) {
65
- groupData.devices = await processDevices(from, to, devices, { summary, trips }, userData, traccarInstance)
66
-
67
- reportData.push(groupData)
68
- }
69
- }
70
- }
71
-
72
- const withoutGroupDevices = await createActivityReportByDevice(from, to, userData, traccarInstance)
73
- reportData.push(withoutGroupDevices)
74
-
75
- return reportData
76
- }
77
-
78
- async function createActivityReportByDevice (from, to, userData, traccarInstance) {
79
- console.log('createActivityReportByDevice')
80
- const allDevices = devicesToProcess(userData)
81
-
82
- const allData = {
83
- devices: [],
84
- xpert: allDevices.filter(d => d.attributes.xpert).length > 0,
85
- from,
86
- to
87
- }
88
-
89
- if (isClientSide() && allDevices.length > 20) {
90
- const sliced = automaticReports.sliceArray(allDevices, 10)
91
- await executeServerSide('activity-report', sliced, from, to, userData, allDevices.length, traccarInstance, 5).then(devices => {
92
- allData.devices = devices
93
- })
94
- } else {
95
- let summaryByDay = []
96
- if (userData.allWeek && userData.groupByDay) {
97
- const dates = getDates(from, to, userData.user.attributes.timezone || getUserPartner(userData.user).timezone)
98
- summaryByDay = await getSummaryByDay(dates, userData, traccarInstance, allDevices, true, from, to)
99
- }
100
-
101
- let deviceCount = 0
102
- const sliced = automaticReports.sliceArray(allDevices, 20)
103
- for (const devices of sliced) {
104
- const needRoute = userData.groupByDay || !userData.allWeek
105
- const {
106
- trips,
107
- route,
108
- summary
109
- } = await traccar.getAllInOne(traccarInstance, from, to, devices, needRoute, true, false, !userData.groupByDay, deviceCount, allDevices.length, 10)
110
-
111
- // Process report data
112
- if (summary.length || trips.length) {
113
- allData.devices = allData.devices.concat(await processDevices(from, to, devices, { summaryByDay, summary, trips, route }, userData, traccarInstance))
114
- }
115
- deviceCount += devices.length
116
- }
117
- }
118
-
119
- return allData
120
- }
121
-
122
- async function createActivityReportByDriver (from, to, userData, traccarInstance) {
123
- console.log('createActivityReportByDriver')
124
- const allDevices = await traccarInstance.devices.devicesGet().then(d => d.data)
125
-
126
- const allData = {
127
- drivers: [],
128
- from,
129
- to
130
- }
131
- const driversData = new Map()
132
-
133
- let deviceCount = 0
134
- const sliced = automaticReports.sliceArray(allDevices, 10)
135
- for (const devices of sliced) {
136
- const data = await traccar.getAllInOne(traccarInstance, from, to, devices, true, true, false, false, deviceCount, allDevices.length)
137
-
138
- for (const d of userData.drivers) {
139
- const { trips, route } = await getDriverData(d, data, userData)
140
- let driverData = driversData.get(d.id)
141
- if (!driverData) {
142
- driverData = { trips: [], route: [] }
143
- driversData.set(d.id, driverData)
144
- }
145
- driverData.trips = driverData.trips.concat(...(trips || []))
146
- driverData.route = driverData.route.concat(...(route || []))
147
- }
148
-
149
- deviceCount += devices.length
150
- }
151
-
152
- allData.drivers = processDrivers(from, to, userData.drivers, driversData, userData)
153
-
154
- return allData
155
- }
156
-
157
- async function processDevices (from, to, devices, data, userData, traccarInstance) {
158
- const devicesResult = []
159
-
160
- for (const d of devices) {
161
- const deviceTrips = data.trips.filter(t => t.deviceId === d.id)
162
- const deviceRoute = data.route.filter(t => t.deviceId === d.id)
163
-
164
- let uncompletedTripRoute = []
165
- if (deviceRoute.length && deviceTrips.length && deviceRoute[deviceRoute.length - 1].attributes.ignition) {
166
- uncompletedTripRoute = deviceRoute.filter(p => p.attributes.ignition && new Date(p.fixTime).getTime() > new Date(deviceTrips[deviceTrips.length - 1].endTime).getTime())
167
- if (uncompletedTripRoute.length) {
168
- deviceTrips.push(calculateTrip(d, uncompletedTripRoute))
169
- }
170
- }
171
-
172
- const summary = []
173
- if (userData.groupByDay) {
174
- const trips = []
175
- for (const t of deviceTrips) {
176
- if (userData.allWeek || !userData.weekDays) {
177
- trips.push(t)
178
- continue
179
- }
180
- if (isInsideTimetable(t, userData)) {
181
- trips.push(t)
182
- continue
183
- }
184
- if (await isPartialInsideTimetable(d, t, userData, deviceRoute)) {
185
- trips.push(t)
186
- }
187
- }
188
- const dates = getDates(from, to, userData.user.attributes.timezone || getUserPartner(userData.user).timezone)
189
- for (const date of dates) {
190
- const { tripsByDay, routeByDay } = await getDataByDay(d, date, { trips, route: deviceRoute }, userData, traccarInstance)
191
- const distance = getKms(tripsByDay)
192
- if (!userData.allWeek && userData.weekDays && userData.dayHours) {
193
- if (weekDaySelected(date, userData.weekDays)) {
194
- summary.push({
195
- date,
196
- deviceId: d.id,
197
- averageSpeed: distance > 0 ? ((tripsByDay.reduce((a, b) => a + (b.averageSpeed * b.distance), 0)) / distance) : 0,
198
- distance,
199
- engineHours: tripsByDay.reduce((a, b) => a + b.duration, 0),
200
- maxSpeed: tripsByDay.reduce((a, b) => {
201
- return a > b.maxSpeed ? a : b.maxSpeed
202
- }, 0),
203
- endOdometer: 0,
204
- startOdometer: 0,
205
- startTime: tripsByDay.length && tripsByDay[0].startTime,
206
- startAddress: tripsByDay.length && tripsByDay[0].startAddress,
207
- endTime: tripsByDay.length && tripsByDay[tripsByDay.length - 1].endTime,
208
- endAddress: tripsByDay.length && tripsByDay[tripsByDay.length - 1].endAddress,
209
- startTimeIsOut: tripsByDay.some(t => t.startTimeIsOut),
210
- endTimeIsOut: tripsByDay.some(t => t.endTimeIsOut)
211
- })
212
- }
213
- } else {
214
- const summaryByDay = data.summaryByDay.find(a => a.date.getTime() === date.getTime())
215
- const summaryByDevice = summaryByDay.summary.find(a => a.deviceId === d.id)
216
-
217
- const summaryCurrentDay = { date, deviceId: d.id }
218
- summaryCurrentDay.engineHours = tripsByDay.reduce((a, b) => a + b.duration, 0)
219
- summaryCurrentDay.distance = summaryByDevice.distance
220
- summaryCurrentDay.averageSpeed = distance > 0 ? ((tripsByDay.reduce((a, b) => a + (b.averageSpeed * b.distance), 0)) / distance) : 0
221
- summaryCurrentDay.maxSpeed = tripsByDay.reduce((a, b) => { return a > b.maxSpeed ? a : b.maxSpeed }, 0)
222
- summaryCurrentDay.convertedSpentFuel = calculateConsumption(d, { route: routeByDay })
223
- summaryCurrentDay.startTime = tripsByDay.length && tripsByDay[0].startTime
224
- summaryCurrentDay.startAddress = tripsByDay.length && tripsByDay[0].startAddress
225
- summaryCurrentDay.endTime = tripsByDay.length && tripsByDay[tripsByDay.length - 1].endTime
226
- summaryCurrentDay.endAddress = tripsByDay.length && tripsByDay[tripsByDay.length - 1].endAddress
227
- summaryCurrentDay.startOdometer = summaryByDevice.startOdometer
228
- summaryCurrentDay.endOdometer = summaryByDevice.endOdometer
229
- summaryCurrentDay.startTimeIsOut = tripsByDay.some(t => t.startTimeIsOut)
230
- summaryCurrentDay.endTimeIsOut = tripsByDay.some(t => t.endTimeIsOut)
231
- summary.push(summaryCurrentDay)
232
- }
233
- }
234
- } else {
235
- if (!userData.allWeek && userData.weekDays && userData.dayHours) {
236
- const trips = deviceTrips.filter(t => userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData) || isPartialInsideTimetable(d, t, userData, deviceRoute))
237
- const distance = getKms(trips)
238
- summary.push({
239
- deviceId: d.id,
240
- averageSpeed: distance > 0 ? ((trips.reduce((a, b) => a + (b.averageSpeed * b.distance), 0)) / distance) : 0,
241
- distance,
242
- engineHours: trips.reduce((a, b) => a + b.duration, 0),
243
- maxSpeed: trips.reduce((a, b) => {
244
- return a > b.maxSpeed ? a : b.maxSpeed
245
- }, 0),
246
- startOdometer: trips.length ? trips[0].startOdometer : 0,
247
- endOdometer: trips.length ? trips[trips.length - 1].endOdometer : 0,
248
- startTime: trips.length && trips[0].startTime,
249
- startAddress: trips.length && trips[0].startAddress,
250
- endTime: trips.length && trips[trips.length - 1].endTime,
251
- endAddress: trips.length && trips[trips.length - 1].endAddress
252
- })
253
- } else {
254
- summary.push(...data.summary.filter(s => s.deviceId === d.id))
255
-
256
- if (summary.length) {
257
- summary.forEach(s => {
258
- s.engineHours = deviceTrips.reduce((a, b) => a + b.duration, 0)
259
- s.convertedSpentFuel = calculateConsumption(d, { route: deviceRoute, summary: s })
260
- s.startTime = deviceTrips.length && deviceTrips[0].startTime
261
- s.startAddress = deviceTrips.length && deviceTrips[0].startAddress
262
- s.endTime = deviceTrips.length && deviceTrips[deviceTrips.length - 1].endTime
263
- s.endAddress = deviceTrips.length && deviceTrips[deviceTrips.length - 1].endAddress
264
- })
265
- }
266
- }
267
- }
268
-
269
- const deviceData = {
270
- device: d,
271
- summary
272
- }
273
-
274
- if ((deviceData.summary.length && deviceData.summary.some(s => s.startTime)) || !userData.onlyWithActivity) {
275
- devicesResult.push(deviceData)
276
- }
277
- }
278
-
279
- return devicesResult
280
- }
281
-
282
- function processDrivers (from, to, drivers, driversData, userData) {
283
- const driversResult = []
284
- drivers.forEach(d => {
285
- const { trips, route } = driversData.get(d.id)
286
- trips.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime())
287
- if (trips.length > 0) {
288
- const driverData = {
289
- driver: d,
290
- summary: []
291
- }
292
- if (userData.groupByDay) {
293
- const dates = getDates(from, to)
294
- for (const date of dates) {
295
- const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
296
- const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
297
-
298
- const tripsByDay = trips.filter(t => (new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay) &&
299
- (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData) || isPartialInsideTimetable(undefined, t, userData, route)))
300
-
301
- calculateMultiDayTrips(trips, route, tripsByDay, fromByDay, toByDay, userData.devices)
302
-
303
- driverData.summary.push({
304
- date,
305
- distance: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0),
306
- engineHours: tripsByDay.reduce((a, b) => a + b.duration, 0),
307
- maxSpeed: tripsByDay.reduce((a, b) => Math.max(a, b.maxSpeed), 0),
308
- averageSpeed: tripsByDay.length ? Math.round(tripsByDay.reduce((a, b) => a + b.averageSpeed, 0) / tripsByDay.length) : 0,
309
- startTime: tripsByDay.length && tripsByDay[0].startTime,
310
- startAddress: tripsByDay.length && tripsByDay[0].startAddress,
311
- endTime: tripsByDay.length && tripsByDay[tripsByDay.length - 1].endTime,
312
- endAddress: tripsByDay.length && tripsByDay[tripsByDay.length - 1].endAddress
313
- })
314
- }
315
- } else {
316
- driverData.summary.push({
317
- distance: trips.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0),
318
- engineHours: trips.reduce((a, b) => a + b.duration, 0),
319
- maxSpeed: trips.reduce((a, b) => Math.max(a, b.maxSpeed), 0),
320
- averageSpeed: Math.round(trips.reduce((a, b) => a + b.averageSpeed, 0) / trips.length),
321
- startTime: trips.length && trips[0].startTime,
322
- startAddress: trips.length && trips[0].startAddress,
323
- endTime: trips.length && trips[trips.length - 1].endTime,
324
- endAddress: trips.length && trips[trips.length - 1].endAddress
325
- })
326
- }
327
- driversResult.push(driverData)
328
- }
329
- })
330
-
331
- return driversResult
332
- }
333
-
334
- async function exportActivityReportToPDF (userData, reportData) {
335
- console.log('Export to PDF')
336
- const translations = getTranslations(userData)
337
-
338
- if (reportData.devices || reportData.drivers) {
339
- // eslint-disable-next-line new-cap
340
- const doc = new jsPDF.jsPDF('l')
341
- await headerFromUser(doc, translations.report.titleActivityReport, userData.user)
342
-
343
- if (userData.groupByDay && userData.byDriver) {
344
- exportActivityReportToPDFDriverGroupByDay(doc, translations, reportData, userData)
345
- } else if (userData.groupByDay) {
346
- exportActivityReportToPDFVehicleGroupByDay(doc, translations, reportData, userData)
347
- } else if (userData.byDriver) {
348
- exportActivityReportToPDFDriver(doc, translations, reportData, userData)
349
- } else {
350
- exportActivityReportToPDFVehicle(doc, translations, reportData, userData)
351
- }
352
-
353
- return doc
354
- }
355
- }
356
-
357
- function exportActivityReportToPDFDriver (doc, translations, reportData, userData) {
358
- const timezone = userData.user.attributes.timezone
359
- const lang = getLanguage(userData)
360
-
361
- const headers = [translations.report.driver,
362
- translations.report.start,
363
- translations.report.end,
364
- translations.report.distance,
365
- translations.report.speed + ' ' + translations.report.avgSpeed + ' (Km/h)',
366
- translations.report.speed + ' ' + translations.report.maxSpeed + ' (Km/h)',
367
- translations.report.driverHours]
368
-
369
- doc.setFontSize(10)
370
- doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, 30)
371
-
372
- const data = []
373
- reportData.drivers.forEach(d => {
374
- const temp = [
375
- d.driver.name,
376
- d.summary[0].startTime ? new Date(d.summary[0].startTime).toLocaleString() : '',
377
- d.summary[0].endTime ? new Date(d.summary[0].endTime).toLocaleString() : '',
378
- Number((d.summary[0].distance / 1000).toFixed(1)),
379
- Math.round(d.summary[0].averageSpeed * 1.85200),
380
- Math.round(d.summary[0].maxSpeed * 1.85200),
381
- convertMS(d.summary[0].engineHours)
382
- ]
383
- data.push(temp)
384
- })
385
-
386
- const footValues = ['Total:' + reportData.drivers.length,
387
- '', '',
388
- (reportData.drivers.reduce((a, b) => a + b.summary[0].distance, 0) / 1000).toFixed(0),
389
- getSumAvgSpeed(reportData.drivers, userData),
390
- getSumMaxSpeed(reportData.drivers, userData),
391
- convertMS(reportData.drivers.reduce((a, b) => a + b.summary[0].engineHours, 0))]
392
-
393
- const style = getStyle(getUserPartner(userData.user))
394
- addTable(doc, headers, data, footValues, style, 35)
395
- }
396
-
397
- function exportActivityReportToPDFVehicle (doc, translations, reportData, userData) {
398
- const timezone = userData.user.attributes.timezone
399
- const lang = getLanguage(userData)
400
-
401
- const headers = [translations.report.vehicle,
402
- translations.report.group,
403
- translations.report.start,
404
- translations.report.end,
405
- translations.report.distance,
406
- translations.report.start + ' ' + translations.report.odometer,
407
- translations.report.end + ' ' + translations.report.odometer,
408
- translations.report.avgSpeed + ' (Km/h)',
409
- translations.report.maxSpeed + ' (Km/h)',
410
- translations.report.engineHours,
411
- translations.report.spentFuel]
412
-
413
- doc.setFontSize(10)
414
- doc.text(convertToLocaleString(reportData.from, lang, timezone, userData.user) + ' - ' + convertToLocaleString(reportData.to, lang, timezone, userData.user), 20, 30)
415
-
416
- const data = []
417
- reportData.devices.forEach(d => {
418
- const group = userData.groups.find(g => d.device.groupId === g.id)
419
-
420
- if (d.summary) {
421
- const temp = [
422
- d.device.name,
423
- group ? group.name : '',
424
- d.summary[0].startTime ? new Date(d.summary[0].startTime).toLocaleString() : '',
425
- d.summary[0].endTime ? new Date(d.summary[0].endTime).toLocaleString() : '',
426
- Number((d.summary[0].distance / 1000).toFixed(1)),
427
- Number((d.summary[0].startOdometer / 1000).toFixed(1)),
428
- Number((d.summary[0].endOdometer / 1000).toFixed(1)),
429
- Math.round(d.summary[0].averageSpeed * 1.85200),
430
- Math.round(d.summary[0].maxSpeed * 1.85200),
431
- convertMS(d.summary[0].engineHours),
432
- Math.round(d.summary[0].convertedSpentFuel >= 0 ? d.summary[0].convertedSpentFuel : 0)
433
- ]
434
- data.push(temp)
435
- }
436
- })
437
-
438
- const footValues = ['Total:' + reportData.devices.length,
439
- '', '', '',
440
- (reportData.devices.reduce((a, b) => a + b.summary[0].distance, 0) / 1000).toFixed(0),
441
- '', '',
442
- getSumAvgSpeed(reportData.devices, userData),
443
- getSumMaxSpeed(reportData.devices, userData),
444
- convertMS(reportData.devices.reduce((a, b) => a + b.summary[0].engineHours, 0)),
445
- Math.round(getSumSpentFuel(reportData.devices, userData))]
446
-
447
- const style = getStyle(getUserPartner(userData.user))
448
- addTable(doc, headers, data, footValues, style, 35)
449
- }
450
-
451
- function exportActivityReportToPDFVehicleGroupByDay (doc, translations, reportData, userData) {
452
- const headers = [translations.report.date,
453
- translations.report.start,
454
- translations.report.end,
455
- translations.report.distance,
456
- translations.report.start + ' ' + translations.report.odometer,
457
- translations.report.end + ' ' + translations.report.odometer,
458
- translations.report.avgSpeed + ' (Km/h)',
459
- translations.report.maxSpeed + ' (Km/h)',
460
- translations.report.engineHours,
461
- translations.report.spentFuel]
462
-
463
- const weekDays = [
464
- translations.report.sunday,
465
- translations.report.monday,
466
- translations.report.tuesday,
467
- translations.report.wednesday,
468
- translations.report.thursday,
469
- translations.report.friday,
470
- translations.report.saturday
471
- ]
472
-
473
- reportData.devices.forEach(function (d, index) {
474
- pdfPageByDay(userData, d, index, doc, translations, reportData)
475
-
476
- const data = []
477
- d.summary.forEach(s => {
478
- const temp = [
479
- new Date(s.date).toLocaleDateString() + ' - ' + weekDays[new Date(s.date).getDay()],
480
- s.startTime ? new Date(s.startTime).toLocaleTimeString() : '',
481
- s.endTime ? new Date(s.endTime).toLocaleTimeString() : '',
482
- Number((s.distance / 1000).toFixed(1)),
483
- Number((s.startOdometer / 1000).toFixed(1)),
484
- Number((s.endOdometer / 1000).toFixed(1)),
485
- Math.round(s.averageSpeed * 1.85200),
486
- Math.round(s.maxSpeed * 1.85200),
487
- convertMS(s.engineHours),
488
- Math.round(s.convertedSpentFuel >= 0 ? s.convertedSpentFuel : 0)
489
- ]
490
-
491
- data.push(temp)
492
- })
493
-
494
- const footValues = ['Total:' + d.summary.length,
495
- '', '',
496
- (d.summary.reduce((a, b) => a + b.distance, 0) / 1000).toFixed(0),
497
- '', '',
498
- getSumAvgSpeed(d.summary, userData),
499
- getSumMaxSpeed(d.summary, userData),
500
- convertMS(d.summary.reduce((a, b) => a + b.engineHours, 0)),
501
- Math.round(getSumSpentFuel(d.summary, userData))]
502
-
503
- const style = getStyle(getUserPartner(userData.user))
504
- addTable(doc, headers, data, footValues, style, 40)
505
- })
506
- }
507
-
508
- function exportActivityReportToExcelVehicleGroupByDay (settings, translations, reportData, userData) {
509
- const headers = [{ label: translations.report.vehicle, value: 'name' },
510
- { label: translations.report.group, value: 'group' },
511
- { label: translations.report.date, value: 'date' },
512
- { label: translations.report.weekDay, value: 'weekday' },
513
- { label: translations.report.start, value: 'start' },
514
- { label: translations.report.end, value: 'end' },
515
- { label: translations.report.distance, value: 'distance' },
516
- { label: translations.report.start + ' ' + translations.report.odometer, value: 'startOdometer' },
517
- { label: translations.report.end + ' ' + translations.report.odometer, value: 'endOdometer' },
518
- { label: translations.report.speed + ' ' + translations.report.avgSpeed + ' (Km/h)', value: 'avgSpeed' },
519
- { label: translations.report.speed + ' ' + translations.report.maxSpeed + ' (Km/h)', value: 'maxSpeed' },
520
- { label: translations.report.engineHours, value: 'engineHours' },
521
- { label: translations.report.spentFuel, value: 'spentFuel' }]
522
-
523
- const weekDays = [
524
- translations.report.sunday,
525
- translations.report.monday,
526
- translations.report.tuesday,
527
- translations.report.wednesday,
528
- translations.report.thursday,
529
- translations.report.friday,
530
- translations.report.saturday
531
- ]
532
-
533
- let data = []
534
- if (reportData.devices) {
535
- reportData.devices.forEach(d => {
536
- const group = userData.groups.find(g => d.device.groupId === g.id)
537
-
538
- data = data.concat([{}])
539
- data = data.concat(d.summary.map(s => {
540
- return {
541
- name: d.device.name,
542
- group: group ? group.name : '',
543
- date: new Date(s.date).toLocaleDateString(),
544
- weekday: weekDays[new Date(s.date).getDay()],
545
- start: s.startTime ? new Date(s.startTime).toLocaleTimeString() : '',
546
- end: s.endTime ? new Date(s.endTime).toLocaleTimeString() : '',
547
- distance: Number((s.distance / 1000).toFixed(0)),
548
- startOdometer: Number((s.startOdometer / 1000).toFixed(0)),
549
- endOdometer: Number((s.endOdometer / 1000).toFixed(0)),
550
- avgSpeed: Math.round(s.averageSpeed * 1.85200),
551
- maxSpeed: Math.round(s.maxSpeed * 1.85200),
552
- engineHours: convertMS(s.engineHours),
553
- spentFuel: Math.round(s.convertedSpentFuel >= 0 ? s.convertedSpentFuel : 0)
554
- }
555
- }))
556
- })
557
- return {
558
- headers,
559
- data,
560
- settings
561
- }
562
- }
563
- }
564
-
565
- function exportActivityReportToPDFDriverGroupByDay (doc, translations, reportData, userData) {
566
- const headers = [translations.report.date,
567
- translations.report.start,
568
- translations.report.end,
569
- translations.report.distance,
570
- translations.report.avgSpeed + ' (Km/h)',
571
- translations.report.maxSpeed + ' (Km/h)',
572
- translations.report.engineHours]
573
-
574
- const weekDays = [
575
- translations.report.sunday,
576
- translations.report.monday,
577
- translations.report.tuesday,
578
- translations.report.wednesday,
579
- translations.report.thursday,
580
- translations.report.friday,
581
- translations.report.saturday
582
- ]
583
-
584
- reportData.drivers.forEach(function (d, index) {
585
- const name = d.driver.name
586
- const group = userData.groups.find(g => g.drivers.includes(d.id))
587
-
588
- const space = index === 0 ? 8 : 0
589
- if (index) {
590
- doc.addPage()
591
- }
592
-
593
- doc.setFontSize(13)
594
- doc.text(name, 20, space + 20)
595
- doc.setFontSize(11)
596
- doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
597
- doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
598
-
599
- if (!userData.allWeek && userData.weekDays) {
600
- doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '') +
601
- (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '') +
602
- (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '') +
603
- (userData.weekDays.thursday ? ' ' + translations.report.thursday + ',' : '') +
604
- (userData.weekDays.friday ? ' ' + translations.report.friday + ',' : '') +
605
- (userData.weekDays.saturday ? ' ' + translations.report.saturday + ',' : '') +
606
- (userData.weekDays.sunday ? ' ' + translations.report.sunday + ',' : '') +
607
- ' das ' +
608
- userData.dayHours.startTime + ' - ' + userData.dayHours.endTime, 20, space + 30)
609
- }
610
-
611
- const data = []
612
- d.summary.forEach(s => {
613
- const temp = [
614
- new Date(s.date).toLocaleDateString() + ' - ' + weekDays[new Date(s.date).getDay()],
615
- s.startTime ? new Date(s.startTime).toLocaleTimeString() : '',
616
- s.endTime ? new Date(s.endTime).toLocaleTimeString() : '',
617
- Number((s.distance / 1000).toFixed(1)),
618
- Math.round(s.averageSpeed * 1.85200),
619
- Math.round(s.maxSpeed * 1.85200),
620
- convertMS(s.engineHours)
621
- ]
622
-
623
- data.push(temp)
624
- })
625
-
626
- const footValues = ['Total:' + d.summary.length,
627
- '', '',
628
- (d.summary.reduce((a, b) => a + b.distance, 0) / 1000).toFixed(0),
629
- getSumAvgSpeed(d.summary, userData),
630
- getSumMaxSpeed(d.summary, userData),
631
- convertMS(d.summary.reduce((a, b) => a + b.engineHours, 0))]
632
-
633
- const style = getStyle(getUserPartner(userData.user))
634
- addTable(doc, headers, data, footValues, style, 40)
635
- })
636
- }
637
-
638
- function exportActivityReportToExcelDriverGroupByDay (settings, translations, reportData, userData) {
639
- const headers = [{ label: translations.report.driver, value: 'name' },
640
- { label: translations.report.group, value: 'group' },
641
- { label: translations.report.date, value: 'date' },
642
- { label: translations.report.weekDay, value: 'weekday' },
643
- { label: translations.report.start, value: 'start' },
644
- { label: translations.report.end, value: 'end' },
645
- { label: translations.report.distance, value: 'distance' },
646
- { label: translations.report.speed + ' ' + translations.report.avgSpeed + ' (Km/h)', value: 'avgSpeed' },
647
- { label: translations.report.speed + ' ' + translations.report.maxSpeed + ' (Km/h)', value: 'maxSpeed' },
648
- { label: translations.report.engineHours, value: 'engineHours' }]
649
-
650
- const weekDays = [
651
- translations.report.sunday,
652
- translations.report.monday,
653
- translations.report.tuesday,
654
- translations.report.wednesday,
655
- translations.report.thursday,
656
- translations.report.friday,
657
- translations.report.saturday
658
- ]
659
-
660
- let data = []
661
- if (reportData.drivers) {
662
- reportData.drivers.forEach(d => {
663
- const group = userData.groups.find(g => g.drivers.includes(d.id))
664
-
665
- data = data.concat([{}])
666
- data = data.concat(d.summary.map(s => {
667
- return {
668
- name: d.driver.name,
669
- group: group ? group.name : '',
670
- date: new Date(s.date).toLocaleDateString(),
671
- weekday: weekDays[new Date(s.date).getDay()],
672
- start: s.startTime ? new Date(s.startTime).toLocaleTimeString() : '',
673
- end: s.endTime ? new Date(s.endTime).toLocaleTimeString() : '',
674
- distance: Number((s.distance / 1000).toFixed(0)),
675
- avgSpeed: Math.round(s.averageSpeed * 1.85200),
676
- maxSpeed: Math.round(s.maxSpeed * 1.85200),
677
- engineHours: convertMS(s.engineHours)
678
- }
679
- }))
680
- })
681
- return {
682
- headers,
683
- data,
684
- settings
685
- }
686
- }
687
- }
688
-
689
- function exportActivityReportToExcelDriver (settings, translations, reportData) {
690
- const headers = [{ label: translations.report.driver, value: 'driver' },
691
- { label: translations.report.start, value: 'start' },
692
- { label: translations.report.end, value: 'end' },
693
- { label: translations.report.distance, value: 'distance' },
694
- { label: translations.report.speed + ' ' + translations.report.avgSpeed + ' (Km/h)', value: 'avgSpeed' },
695
- { label: translations.report.speed + ' ' + translations.report.maxSpeed + ' (Km/h)', value: 'maxSpeed' },
696
- { label: translations.report.driverHours, value: 'engineHours' }]
697
-
698
- let data = []
699
- if (reportData.drivers) {
700
- reportData.drivers.forEach(d => {
701
- data = data.concat([{
702
- driver: d.driver.name,
703
- start: d.summary[0].startTime ? new Date(d.summary[0].startTime).toLocaleString() : '',
704
- end: d.summary[0].endTime ? new Date(d.summary[0].endTime).toLocaleString() : '',
705
- distance: Number((d.summary[0].distance / 1000).toFixed(0)),
706
- avgSpeed: Math.round(d.summary[0].averageSpeed * 1.85200),
707
- maxSpeed: Math.round(d.summary[0].maxSpeed * 1.85200),
708
- engineHours: convertMS(d.summary[0].engineHours)
709
- }])
710
- })
711
- return {
712
- headers,
713
- data,
714
- settings
715
- }
716
- }
717
- }
718
-
719
- function exportActivityReportToExcelVehicle (settings, translations, reportData, userData) {
720
- const headers = [{ label: translations.report.vehicle, value: 'name' },
721
- { label: translations.report.group, value: 'group' },
722
- { label: translations.report.start, value: 'start' },
723
- { label: translations.report.end, value: 'end' },
724
- { label: translations.report.distance, value: 'distance' },
725
- { label: translations.report.start + ' ' + translations.report.odometer, value: 'startOdometer' },
726
- { label: translations.report.end + ' ' + translations.report.odometer, value: 'endOdometer' },
727
- { label: translations.report.speed + ' ' + translations.report.avgSpeed + ' (Km/h)', value: 'avgSpeed' },
728
- { label: translations.report.speed + ' ' + translations.report.maxSpeed + ' (Km/h)', value: 'maxSpeed' },
729
- { label: translations.report.engineHours, value: 'engineHours' },
730
- { label: translations.report.spentFuel, value: 'spentFuel' }]
731
-
732
- if (reportData.devices) {
733
- let data = []
734
- reportData.devices.forEach(d => {
735
- const group = userData.groups.find(g => d.device.groupId === g.id)
736
-
737
- if (d.summary) {
738
- data = data.concat([{
739
- name: d.device.name,
740
- group: group ? group.name : '',
741
- start: d.summary[0].startTime ? new Date(d.summary[0].startTime).toLocaleString() : '',
742
- end: d.summary[0].endTime ? new Date(d.summary[0].endTime).toLocaleString() : '',
743
- distance: Number((d.summary[0].distance / 1000).toFixed(0)),
744
- startOdometer: Number((d.summary[0].startOdometer / 1000).toFixed(0)),
745
- endOdometer: Number((d.summary[0].endOdometer / 1000).toFixed(0)),
746
- avgSpeed: Math.round(d.summary[0].averageSpeed * 1.85200),
747
- maxSpeed: Math.round(d.summary[0].maxSpeed * 1.85200),
748
- engineHours: convertMS(d.summary[0].engineHours),
749
- spentFuel: Math.round(d.summary[0].convertedSpentFuel >= 0 ? d.summary[0].convertedSpentFuel : 0)
750
- }])
751
- }
752
- })
753
- return {
754
- headers,
755
- data,
756
- settings
757
- }
758
- }
759
- }
760
-
761
- function exportActivityReportToExcel (userData, reportData) {
762
- console.log('Export to Excel')
763
- const translations = getTranslations(userData)
764
-
765
- const settings = {
766
- sheetName: translations.report.titleActivityReport, // The name of the sheet
767
- fileName // The name of the spreadsheet
768
- }
769
-
770
- if (userData.groupByDay && userData.byDriver) {
771
- return exportActivityReportToExcelDriverGroupByDay(settings, translations, reportData, userData)
772
- } else if (userData.groupByDay) {
773
- return exportActivityReportToExcelVehicleGroupByDay(settings, translations, reportData, userData)
774
- } else if (userData.byDriver) {
775
- return exportActivityReportToExcelDriver(settings, translations, reportData, userData)
776
- } else {
777
- return exportActivityReportToExcelVehicle(settings, translations, reportData, userData)
778
- }
779
- }
780
-
781
- function getSumAvgSpeed (data, userData) {
782
- const values = data.map(item => {
783
- if (userData.groupByDay) {
784
- return Math.round(item.averageSpeed * 1.85200)
785
- } else {
786
- return Math.round(item.summary[0].averageSpeed * 1.85200)
787
- }
788
- }).filter(v => v !== 0)
789
- return Math.round((values.reduce((a, b) => a + b, 0)) / values.length)
790
- }
791
-
792
- function getSumMaxSpeed (data, userData) {
793
- const values = data.map(item => {
794
- if (userData.groupByDay) {
795
- return item.maxSpeed
796
- } else {
797
- return item.summary[0].maxSpeed
798
- }
799
- })
800
- const max = values.reduce(function (a, b) {
801
- return Math.max(a, b)
802
- })
803
- return Math.round(max * 1.85200)
804
- }
805
-
806
- function getSumSpentFuel (data, userData) {
807
- const values = data.map(item => {
808
- if (userData.groupByDay) {
809
- return item.convertedSpentFuel >= 0 ? item.convertedSpentFuel : 0
810
- } else {
811
- return item.summary[0].convertedSpentFuel >= 0 ? item.summary[0].convertedSpentFuel : 0
812
- }
813
- })
814
- return values.reduce((a, b) => a + b, 0)
815
- }
816
-
817
- exports.createActivityReport = createActivityReport
818
- exports.exportActivityReportToPDF = exportActivityReportToPDF
819
- exports.exportActivityReportToExcel = exportActivityReportToExcel
820
- exports.create = createActivityReport
821
- exports.exportToPDF = exportActivityReportToPDF
822
- exports.exportToExcel = exportActivityReportToExcel