fleetmap-reports 1.0.429 → 1.0.432
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/lang/enGB.js +2 -1
- package/lang/esCL.js +1 -0
- package/lang/ptBR.js +2 -1
- package/lang/ptPT.js +3 -2
- package/package.json +1 -1
- package/src/fuelconsumption-report.js +137 -88
- package/src/fueldrop-report.js +119 -75
- package/src/idle-report.js +5 -0
- package/src/index.js +164 -141
- package/src/refueling-report.js +45 -0
- package/src/speeding-report.js +32 -29
- package/src/trip-report.js +7 -6
package/lang/enGB.js
CHANGED
|
@@ -223,6 +223,7 @@ module.exports = {
|
|
|
223
223
|
engineHours: 'Use (H:m)',
|
|
224
224
|
driverHours: 'Driving Time (H:m)',
|
|
225
225
|
refueling: 'Refueling',
|
|
226
|
+
fueldrop: 'Fuel Drop (L)',
|
|
226
227
|
totalRefueled: 'Total Refueled',
|
|
227
228
|
totalFuelDrops: 'Total Fuel Drops',
|
|
228
229
|
totalFuelDropLiters: 'Total Fuel Lost',
|
|
@@ -276,4 +277,4 @@ module.exports = {
|
|
|
276
277
|
in: 'in',
|
|
277
278
|
fuelDropInfo: 'Fuel drop greater than '
|
|
278
279
|
}
|
|
279
|
-
}
|
|
280
|
+
}
|
package/lang/esCL.js
CHANGED
|
@@ -216,6 +216,7 @@ module.exports = {
|
|
|
216
216
|
engineHours: 'Utilización (HH:mm)',
|
|
217
217
|
driverHours: 'Tiempo de Conducción (H:m)',
|
|
218
218
|
refueling: 'Cargas',
|
|
219
|
+
fueldrop: 'Combustível Perdido (L)',
|
|
219
220
|
totalRefueled: 'Total Cargado',
|
|
220
221
|
totalFuelDrops: 'Total Fuel Drops',
|
|
221
222
|
totalFuelDropLiters: 'Total Fuel Lost',
|
package/lang/ptBR.js
CHANGED
|
@@ -212,6 +212,7 @@ module.exports = {
|
|
|
212
212
|
engineHours: 'Utilização (H:m)',
|
|
213
213
|
driverHours: 'Tempo de Condução (H:m)',
|
|
214
214
|
refueling: 'Abastecimentos',
|
|
215
|
+
fueldrop: 'Combustível Perdido (L)',
|
|
215
216
|
totalRefueled: 'Total Abastecido',
|
|
216
217
|
totalFuelDrops: 'Total de Ocorrências',
|
|
217
218
|
totalFuelDropLiters: 'Combustível Perdido',
|
|
@@ -265,4 +266,4 @@ module.exports = {
|
|
|
265
266
|
in: 'em',
|
|
266
267
|
fuelDropInfo: 'Perda de combustível superior a '
|
|
267
268
|
}
|
|
268
|
-
}
|
|
269
|
+
}
|
package/lang/ptPT.js
CHANGED
|
@@ -219,6 +219,7 @@ module.exports = {
|
|
|
219
219
|
engineHours: 'Utilização (H:m)',
|
|
220
220
|
driverHours: 'Tempo de Condução (H:m)',
|
|
221
221
|
refueling: 'Abastecimentos',
|
|
222
|
+
fueldrop: 'Combustível Perdido (L)',
|
|
222
223
|
totalRefueled: 'Total Abastecido',
|
|
223
224
|
totalFuelDrops: 'Total de Ocorrências',
|
|
224
225
|
totalFuelDropLiters: 'Combustível Perdido',
|
|
@@ -251,7 +252,7 @@ module.exports = {
|
|
|
251
252
|
unsubscribeSpeedingReport: 'Se não deseja receber estes emails por favor aceda a %url% e remova a opção "Relatório de excesso de velocidade" nas definições na secção "Relatórios".',
|
|
252
253
|
unsubscribeZoneReport: 'Se não deseja receber estes emails por favor aceda a %url% e remova a opção "Relatório de zonas" nas definições na secção "Relatórios".',
|
|
253
254
|
unsubscribeRefuelingReport: 'Se não deseja receber estes emails por favor aceda a %url% e remova a opção "Relatório de abastecimentos" nas definições na secção "Relatórios".',
|
|
254
|
-
unsubscribeFuelDropReport: 'Se não deseja receber estes emails por favor aceda a %url% e remova a opção "Relatório de perdas de combustível" nas definições na secção "Relatórios".'
|
|
255
|
+
unsubscribeFuelDropReport: 'Se não deseja receber estes emails por favor aceda a %url% e remova a opção "Relatório de perdas de combustível" nas definições na secção "Relatórios".'
|
|
255
256
|
},
|
|
256
257
|
layout: {
|
|
257
258
|
deviceOnline: 'Dispositivo Online',
|
|
@@ -274,4 +275,4 @@ module.exports = {
|
|
|
274
275
|
in: 'em',
|
|
275
276
|
fuelDropInfo: 'Perda de combustível superior a '
|
|
276
277
|
}
|
|
277
|
-
}
|
|
278
|
+
}
|
package/package.json
CHANGED
|
@@ -1,109 +1,158 @@
|
|
|
1
|
-
const automaticReports = require(
|
|
2
|
-
const refuelingReport = require(
|
|
3
|
-
const traccarHelper = require(
|
|
4
|
-
const odoo = require(
|
|
5
|
-
const {devicesToProcess} = require(
|
|
1
|
+
const automaticReports = require('./automaticReports')
|
|
2
|
+
const refuelingReport = require('./refueling-report')
|
|
3
|
+
const traccarHelper = require('./util/traccar')
|
|
4
|
+
const odoo = require('./util/odoo')
|
|
5
|
+
const { devicesToProcess } = require('./util/device')
|
|
6
|
+
const messages = require('../lang')
|
|
6
7
|
|
|
8
|
+
async function createFuelConsumptionReport (from, to, userData, traccar) {
|
|
9
|
+
console.log('Create FuelConsumption Report')
|
|
7
10
|
|
|
11
|
+
const reportData = []
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
const allData = {
|
|
14
|
+
devices: [],
|
|
15
|
+
from,
|
|
16
|
+
to
|
|
17
|
+
}
|
|
11
18
|
|
|
12
|
-
|
|
19
|
+
const devices = devicesToProcess(userData)
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
to: to
|
|
18
|
-
}
|
|
21
|
+
const allInOne = await traccarHelper.getAllInOne(traccar, from, to, devices, true, true, false, false)
|
|
22
|
+
const tripsData = allInOne.trips
|
|
23
|
+
const routeData = allInOne.route
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
const fuelServicesData = []
|
|
26
|
+
if (userData.withOdooServices) {
|
|
27
|
+
fuelServicesData.push(...(await odoo.getOdooFuelServices(traccar, from, to)))
|
|
28
|
+
}
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
if (tripsData.length === 0) {
|
|
31
|
+
return reportData
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
allData.totalDevices = 0
|
|
35
|
+
|
|
36
|
+
for (const d of devices) {
|
|
37
|
+
const trips = tripsData.filter(t => t.deviceId === d.id)
|
|
38
|
+
const route = routeData.filter(r => r.deviceId === d.id)
|
|
39
|
+
const deviceFuelServices = fuelServicesData.filter(f => d.attributes.odooId === f.vehicle_id[0])
|
|
40
|
+
|
|
41
|
+
if (trips.length > 0) {
|
|
42
|
+
const refuelingPositions = await refuelingReport.calculateRefuelingPositions(userData, d, { route, trips, fuelServices: deviceFuelServices })
|
|
43
|
+
const groupedRefuelingsByDay = refuelingPositions.reduce(
|
|
44
|
+
(entryMap, e) => entryMap.set(e.date.substring(0, 10), [...entryMap.get(e.date.substring(0, 10)) || [], e]),
|
|
45
|
+
new Map()
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
trips.forEach(t => {
|
|
49
|
+
t.startDate = t.startTime.substring(0, 10)
|
|
50
|
+
})
|
|
51
|
+
const groupedTripsByDay = trips.reduce(
|
|
52
|
+
(entryMap, e) => entryMap.set(e.startDate, [...entryMap.get(e.startDate) || [], e]),
|
|
53
|
+
new Map()
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const days = []
|
|
57
|
+
const keys = Array.from(groupedTripsByDay.keys())
|
|
58
|
+
const odooAvgConsumption = userData.withOdooServices ? calculateAvgConsumption(refuelingPositions, trips) : 0
|
|
59
|
+
|
|
60
|
+
keys.forEach(day => {
|
|
61
|
+
const dayTrips = groupedTripsByDay.get(day)
|
|
62
|
+
const dayRefueling = groupedRefuelingsByDay.get(day)
|
|
63
|
+
const distance = dayTrips.reduce((a, b) => a + b.distance, 0)
|
|
64
|
+
const spentFuel = calculateConsumption(userData, d, day, odooAvgConsumption, { trips: dayTrips, route })
|
|
65
|
+
|
|
66
|
+
const dataRow = {
|
|
67
|
+
date: day,
|
|
68
|
+
distance,
|
|
69
|
+
spentFuel,
|
|
70
|
+
avgConsumption: userData.withOdooServices ? odooAvgConsumption : distance > 0 && spentFuel > 0 ? Math.round(spentFuel * 100 / (distance / 1000)) : 0,
|
|
71
|
+
endOdometer: dayTrips.slice(-1)[0].endOdometer,
|
|
72
|
+
duration: dayTrips.reduce((a, b) => a + b.duration, 0),
|
|
73
|
+
refueling: (dayRefueling && dayRefueling.length > 0) ? dayRefueling.reduce((a, b) => a + b.diff, 0) : 0
|
|
74
|
+
}
|
|
25
75
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
fuelServicesData.push(...(await odoo.getOdooFuelServices(traccar, from, to)))
|
|
29
|
-
}
|
|
76
|
+
days.push(dataRow)
|
|
77
|
+
})
|
|
30
78
|
|
|
31
|
-
|
|
32
|
-
|
|
79
|
+
if (days.length > 0) {
|
|
80
|
+
allData.devices.push({
|
|
81
|
+
device: d,
|
|
82
|
+
days
|
|
83
|
+
})
|
|
84
|
+
allData.totalDevices = allData.totalDevices + 1
|
|
85
|
+
}
|
|
33
86
|
}
|
|
87
|
+
}
|
|
34
88
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for (const d of devices) {
|
|
38
|
-
const trips = tripsData.filter(t => t.deviceId===d.id)
|
|
39
|
-
const route = routeData.filter(r => r.deviceId===d.id)
|
|
40
|
-
const deviceFuelServices = fuelServicesData.filter(f => d.attributes.odooId === f.vehicle_id[0])
|
|
41
|
-
|
|
42
|
-
if(trips.length > 0) {
|
|
43
|
-
const refuelingPositions = await refuelingReport.calculateRefuelingPositions(userData, d, {route: route, trips: trips, fuelServices: deviceFuelServices})
|
|
44
|
-
const groupedRefuelingsByDay = refuelingPositions.reduce(
|
|
45
|
-
(entryMap, e) => entryMap.set(e.date.substring(0, 10), [...entryMap.get(e.date.substring(0, 10))||[], e]),
|
|
46
|
-
new Map()
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
trips.forEach(t => t.startDate = t.startTime.substring(0, 10))
|
|
50
|
-
const groupedTripsByDay = trips.reduce(
|
|
51
|
-
(entryMap, e) => entryMap.set(e.startDate, [...entryMap.get(e.startDate)||[], e]),
|
|
52
|
-
new Map()
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
const days = []
|
|
56
|
-
const keys = Array.from(groupedTripsByDay.keys())
|
|
57
|
-
const odooAvgConsumption = userData.withOdooServices ? calculateAvgConsumption(refuelingPositions, trips) : 0
|
|
58
|
-
|
|
59
|
-
keys.forEach(day => {
|
|
60
|
-
const dayTrips = groupedTripsByDay.get(day)
|
|
61
|
-
const dayRefueling = groupedRefuelingsByDay.get(day)
|
|
62
|
-
const distance = dayTrips.reduce((a, b) => a + b.distance, 0)
|
|
63
|
-
const spentFuel = calculateConsumption(userData, d, day, odooAvgConsumption, { trips: dayTrips, route: route })
|
|
64
|
-
|
|
65
|
-
const dataRow = {
|
|
66
|
-
date: day,
|
|
67
|
-
distance: distance,
|
|
68
|
-
spentFuel: spentFuel,
|
|
69
|
-
avgConsumption: userData.withOdooServices ? odooAvgConsumption : distance > 0 && spentFuel > 0 ? Math.round(spentFuel * 100 / (distance / 1000)) : 0,
|
|
70
|
-
endOdometer: dayTrips.slice(-1)[0].endOdometer,
|
|
71
|
-
duration: dayTrips.reduce((a, b) => a + b.duration, 0),
|
|
72
|
-
refueling: (dayRefueling && dayRefueling.length > 0) ? dayRefueling.reduce((a, b) => a + b.diff, 0) : 0,
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
days.push(dataRow)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
if (days.length > 0) {
|
|
79
|
-
allData.devices.push({
|
|
80
|
-
device: d,
|
|
81
|
-
days: days
|
|
82
|
-
})
|
|
83
|
-
allData.totalDevices = allData.totalDevices+1
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
89
|
+
reportData.push(allData)
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
return reportData
|
|
92
|
+
}
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
function calculateAvgConsumption (refuelingPositions, trips) {
|
|
95
|
+
const odooTotalfuel = refuelingPositions.reduce((a, b) => a + b.diff, 0)
|
|
96
|
+
const totalKms = trips.reduce((a, b) => a + b.distance, 0)
|
|
97
|
+
return Math.round(odooTotalfuel * 100 / (totalKms / 1000))
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
function calculateConsumption (userData, d, day, avgConsumption, data) {
|
|
101
|
+
if (d.attributes.xpert) {
|
|
102
|
+
return automaticReports.calculateXpertSpentFuel(day, data.route)
|
|
103
|
+
}
|
|
104
|
+
if (userData.withOdooServices) {
|
|
105
|
+
return Math.round((avgConsumption * (data.trips.reduce((a, b) => a + b.distance, 0) / 1000)) / 100)
|
|
106
|
+
}
|
|
107
|
+
return automaticReports.calculateSpentFuel(data.trips.reduce((a, b) => a + b.spentFuel, 0), d)
|
|
97
108
|
}
|
|
98
109
|
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
function exportFuelConsumptionReportToExcel (userData, reportData) {
|
|
111
|
+
const lang = userData.user.attributes.lang
|
|
112
|
+
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
113
|
+
|
|
114
|
+
const settings = {
|
|
115
|
+
sheetName: 'FuelConsumptionReport', // The name of the sheet
|
|
116
|
+
fileName: 'FuelConsumptionReport' // The name of the spreadsheet
|
|
117
|
+
}
|
|
118
|
+
const headers = [
|
|
119
|
+
{ label: translations.report.name, value: 'name' },
|
|
120
|
+
{ label: translations.report.date, value: 'date' },
|
|
121
|
+
{ label: translations.report.kms, value: 'kms' },
|
|
122
|
+
{ label: translations.report.consumption, value: 'consumption' },
|
|
123
|
+
{ label: translations.report.avg_consumption, value: 'avg_consumption' },
|
|
124
|
+
{ label: translations.report.duration, value: 'duration' },
|
|
125
|
+
{ label: translations.report.accumulated_kms, value: 'accumulated_kms' },
|
|
126
|
+
{ label: translations.report.refueling, value: 'refueling' }
|
|
127
|
+
]
|
|
128
|
+
let data = []
|
|
129
|
+
if (reportData.devices) {
|
|
130
|
+
reportData.devices.forEach((d) => {
|
|
131
|
+
data = data.concat(d.days.map((r) => {
|
|
132
|
+
return {
|
|
133
|
+
name: d.device.name,
|
|
134
|
+
date: r.date,
|
|
135
|
+
kms: (r.distance / 1000).toFixed(2),
|
|
136
|
+
consumption: r.spentFuel > 0 ? r.spentFuel : 0,
|
|
137
|
+
avg_consumption: r.avgConsumption,
|
|
138
|
+
duration: new Date(r.duration).toLocaleTimeString(),
|
|
139
|
+
accumulated_kms: (r.endOdometer / 1000).toFixed(2),
|
|
140
|
+
refueling: r.refueling
|
|
141
|
+
}
|
|
142
|
+
}))
|
|
143
|
+
})
|
|
144
|
+
return {
|
|
145
|
+
headers,
|
|
146
|
+
data,
|
|
147
|
+
settings
|
|
105
148
|
}
|
|
106
|
-
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function exportFuelConsumptionReportToPDF (userData, reportData) {
|
|
153
|
+
console.log('Export to PDF')
|
|
107
154
|
}
|
|
108
155
|
|
|
109
156
|
exports.createFuelConsumptionReport = createFuelConsumptionReport
|
|
157
|
+
exports.exportFuelConsumptionReportToPDF = exportFuelConsumptionReportToPDF
|
|
158
|
+
exports.exportFuelConsumptionReportToExcel = exportFuelConsumptionReportToExcel
|
package/src/fueldrop-report.js
CHANGED
|
@@ -1,92 +1,136 @@
|
|
|
1
|
-
const automaticReports = require(
|
|
2
|
-
const {devicesToProcess} = require(
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
const automaticReports = require('./automaticReports')
|
|
2
|
+
const { devicesToProcess } = require('./util/device')
|
|
3
|
+
const messages = require('../lang')
|
|
4
|
+
|
|
5
|
+
function calculateFuelDrop (position, positions) {
|
|
6
|
+
const index = positions.indexOf(position)
|
|
7
|
+
if (index > 0) {
|
|
8
|
+
let backIndex = 1
|
|
9
|
+
while ((backIndex < 10) && index - backIndex >= 0) {
|
|
10
|
+
const positionBefore = positions[index - backIndex]
|
|
11
|
+
const diff = positionBefore.attributes.fuel - position.attributes.fuel
|
|
12
|
+
if (diff > 0) {
|
|
13
|
+
return diff
|
|
14
|
+
}
|
|
15
|
+
backIndex++
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
}
|
|
18
|
+
return 0
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
async function createFuelDropReport (from, to, userData, traccar) {
|
|
22
|
+
console.log('Create FuelDropReport')
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
console.log('Create FuelDropReport')
|
|
23
|
-
|
|
24
|
-
const reportData = []
|
|
24
|
+
const reportData = []
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const allData = {
|
|
27
|
+
devices: [],
|
|
28
|
+
from,
|
|
29
|
+
to
|
|
30
|
+
}
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
const devices = devicesToProcess(userData)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
const arrayOfArrays = automaticReports.sliceArray(devices)
|
|
35
|
+
let data = []
|
|
36
|
+
const types = ['deviceFuelDrop']
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
for (const a of arrayOfArrays) {
|
|
39
|
+
const response = await traccar.reports.reportsEventsGet(from, to, a.map(d => d.id), null, types)
|
|
40
|
+
data = data.concat(response.data)
|
|
41
|
+
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
console.log('FuelDrop Alerts:' + data.length)
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
//Filter wrong fuel drop values
|
|
72
|
-
const filteredAlerts = alerts.filter(a => a.fuelDropLiters < d.attributes.fuel_tank_capacity && a.fuelDropLiters > 0)
|
|
73
|
-
|
|
74
|
-
if(filteredAlerts.length > 0) {
|
|
75
|
-
allData.devices.push({
|
|
76
|
-
device: d,
|
|
77
|
-
alerts: filteredAlerts
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
allData.totalDevices = allData.totalDevices + 1
|
|
81
|
-
allData.totalFuelDrops = allData.totalFuelDrops + filteredAlerts.length
|
|
82
|
-
allData.totalFuelDropLiters = allData.totalFuelDropLiters + filteredAlerts.reduce((a, b) => a + b.fuelDropLiters, 0)
|
|
83
|
-
}
|
|
45
|
+
if (data.length === 0) {
|
|
46
|
+
return reportData
|
|
47
|
+
}
|
|
48
|
+
allData.totalDevices = 0
|
|
49
|
+
allData.totalFuelDrops = 0
|
|
50
|
+
allData.totalFuelDropLiters = 0
|
|
51
|
+
|
|
52
|
+
for (const d of devices) {
|
|
53
|
+
const alerts = data.filter(t => t.deviceId === d.id)
|
|
54
|
+
|
|
55
|
+
if (alerts.length > 0) {
|
|
56
|
+
const response = await traccar.reports.reportsRouteGet(from, to, [d.id])
|
|
57
|
+
const positions = response.data
|
|
58
|
+
|
|
59
|
+
for (const a of alerts) {
|
|
60
|
+
a.fuelDropLiters = 0
|
|
61
|
+
if (a.positionId > 0) {
|
|
62
|
+
const position = positions.find(p => p.id === a.positionId)
|
|
63
|
+
if (position) {
|
|
64
|
+
a.position = position
|
|
65
|
+
const diff = calculateFuelDrop(position, positions)
|
|
66
|
+
a.fuelDropLiters = Math.round(diff * d.attributes.fuel_tank_capacity / 100)
|
|
67
|
+
}
|
|
84
68
|
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Filter wrong fuel drop values
|
|
72
|
+
const filteredAlerts = alerts.filter(a => a.fuelDropLiters < d.attributes.fuel_tank_capacity && a.fuelDropLiters > 0)
|
|
73
|
+
|
|
74
|
+
if (filteredAlerts.length > 0) {
|
|
75
|
+
allData.devices.push({
|
|
76
|
+
device: d,
|
|
77
|
+
alerts: filteredAlerts
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
allData.totalDevices = allData.totalDevices + 1
|
|
81
|
+
allData.totalFuelDrops = allData.totalFuelDrops + filteredAlerts.length
|
|
82
|
+
allData.totalFuelDropLiters = allData.totalFuelDropLiters + filteredAlerts.reduce((a, b) => a + b.fuelDropLiters, 0)
|
|
83
|
+
}
|
|
85
84
|
}
|
|
85
|
+
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
reportData.push(allData)
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
return reportData
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function exportFuelDropReportToExcel (userData, reportData) {
|
|
93
|
+
console.log('Export to Excel')
|
|
94
|
+
const lang = userData.user.attributes.lang
|
|
95
|
+
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
96
|
+
|
|
97
|
+
const settings = {
|
|
98
|
+
sheetName: 'FuelDropReport', // The name of the sheet
|
|
99
|
+
fileName: 'FuelDropReport' // The name of the spreadsheet
|
|
100
|
+
}
|
|
101
|
+
const headers = [
|
|
102
|
+
{ label: translations.report.name, value: 'name' },
|
|
103
|
+
{ label: translations.report.driver, value: 'driver' },
|
|
104
|
+
{ label: translations.report.date, value: 'fixTime' },
|
|
105
|
+
{ label: translations.report.address, value: 'address' },
|
|
106
|
+
{ label: translations.report.fueldrop, value: 'fuelDropLiters' }
|
|
107
|
+
]
|
|
108
|
+
let data = []
|
|
109
|
+
if (reportData.devices) {
|
|
110
|
+
reportData.devices.forEach(d => {
|
|
111
|
+
data = data.concat(d.alerts.map(r => {
|
|
112
|
+
return {
|
|
113
|
+
driver: r.driverName,
|
|
114
|
+
fuelDropLiters: r.fuelDropLiters,
|
|
115
|
+
fixTime: new Date(r.position.fixTime).toLocaleString(),
|
|
116
|
+
name: d.device.name,
|
|
117
|
+
address: r.geofenceName || r.position.address
|
|
118
|
+
}
|
|
119
|
+
}))
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
headers,
|
|
125
|
+
data,
|
|
126
|
+
settings
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function exportFuelDropReportToPDF (userData, reportData) {
|
|
131
|
+
console.log('Export to PDF')
|
|
90
132
|
}
|
|
91
133
|
|
|
92
134
|
exports.createFuelDropReport = createFuelDropReport
|
|
135
|
+
exports.exportFuelDropReportToPDF = exportFuelDropReportToPDF
|
|
136
|
+
exports.exportFuelDropReportToExcel = exportFuelDropReportToExcel
|
package/src/idle-report.js
CHANGED
|
@@ -162,6 +162,11 @@ function processDevices (from, to, devices, routes, userData) {
|
|
|
162
162
|
const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
|
|
163
163
|
|
|
164
164
|
if (filteredEvents.length) {
|
|
165
|
+
filteredEvents.forEach(e => {
|
|
166
|
+
const driver = userData.drivers.find(d => d.id === e.position.attributes.driverUniqueId)
|
|
167
|
+
e.driver = driver ? driver.name : ''
|
|
168
|
+
})
|
|
169
|
+
|
|
165
170
|
const deviceData = {
|
|
166
171
|
device: d,
|
|
167
172
|
idleEvents: filteredEvents
|
package/src/index.js
CHANGED
|
@@ -1,143 +1,166 @@
|
|
|
1
|
-
function Reports(config, axios, cookieJar) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
1
|
+
function Reports (config, axios, cookieJar) {
|
|
2
|
+
const { ReportsApi, PositionsApi, SessionApi, DevicesApi, GroupsApi, DriversApi, GeofencesApi } = require('traccar-api')
|
|
3
|
+
this.traccar = {
|
|
4
|
+
reports: new ReportsApi(config, null, axios),
|
|
5
|
+
positions: new PositionsApi(config, null, axios),
|
|
6
|
+
session: new SessionApi(config, null, axios),
|
|
7
|
+
devices: new DevicesApi(config, null, axios),
|
|
8
|
+
groups: new GroupsApi(config, null, axios),
|
|
9
|
+
drivers: new DriversApi(config, null, axios),
|
|
10
|
+
geofences: new GeofencesApi(config, null, axios),
|
|
11
|
+
axios: axios || require('axios').create({ ...config.baseOptions, baseURL: config.basePath }),
|
|
12
|
+
cookieJar
|
|
13
|
+
}
|
|
14
|
+
this.getUserData = async () => {
|
|
15
|
+
return {
|
|
16
|
+
user: await this.traccar.session.sessionGet().then(d => d.data),
|
|
17
|
+
devices: await this.traccar.devices.devicesGet().then(d => d.data),
|
|
18
|
+
groups: await this.traccar.groups.groupsGet().then(d => d.data),
|
|
19
|
+
drivers: await this.traccar.drivers.driversGet().then(d => d.data),
|
|
20
|
+
geofences: await this.traccar.geofences.geofencesGet().then(d => d.data),
|
|
21
|
+
byGroup: false
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
this.speedingReport = (from, to, userData) => {
|
|
25
|
+
return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.speedingReportToPDF = (userData, reportData) => {
|
|
29
|
+
return require('./speeding-report').exportSpeedingReportToPDF(userData, reportData)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.speedingReportToExcel = (userData, reportData) => {
|
|
33
|
+
return require('./speeding-report').exportSpeedingReportToExcel(userData, reportData)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.tripReport = (from, to, userData) => {
|
|
37
|
+
return require('./trip-report').createTripReport(from, to, userData, this.traccar)
|
|
38
|
+
}
|
|
39
|
+
this.tripReportToPDF = (userData, reportData) => {
|
|
40
|
+
return require('./trip-report').exportTripReportToPDF(userData, reportData)
|
|
41
|
+
}
|
|
42
|
+
this.tripReportToExcel = (userData, reportData) => {
|
|
43
|
+
return require('./trip-report').exportTripReportToExcel(userData, reportData)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.zoneReport = (from, to, userData) => {
|
|
47
|
+
return require('./zone-report').createZoneReport(from, to, userData, this.traccar)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.zoneReportToPDF = (userData, reportData) => {
|
|
51
|
+
return require('./zone-report').exportZoneReportToPDF(userData, reportData)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.zoneReportToExcel = (userData, reportData) => {
|
|
55
|
+
return require('./zone-report').exportZoneReportToExcel(userData, reportData)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.refuelingReport = (from, to, userData) => {
|
|
59
|
+
return require('./refueling-report').createRefuelingReport(from, to, userData, this.traccar)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.refuelingReportToPDF = (userData, reportData) => {
|
|
63
|
+
return require('./refueling-report').exportRefuelingReportToPDF(userData, reportData)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.refuelingReportToExcel = (userData, reportData) => {
|
|
67
|
+
return require('./refueling-report').exportRefuelingReportToExcel(userData, reportData)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.fuelDropReport = (from, to, userData) => {
|
|
71
|
+
return require('./fueldrop-report').createFuelDropReport(from, to, userData, this.traccar)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.fuelDropReportToExcel = (userData, reportData) => {
|
|
75
|
+
return require('./fueldrop-report').exportFuelDropReportToExcel(userData, reportData)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.fuelDropReportToPDF = (userData, reportData) => {
|
|
79
|
+
return require('./fueldrop-report').exportFuelDropReportToPDF(userData, reportData)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.eventsReport = (from, to, userData) => {
|
|
83
|
+
return require('./events-report').createEventsReport(from, to, userData, this.traccar)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.eventsReportToPDF = (userData, reportData) => {
|
|
87
|
+
return require('./events-report').exportSpeedingReportToPDF(userData, reportData)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.eventsReportToExcel = (userData, reportData) => {
|
|
91
|
+
return require('./events-report').exportSpeedingReportToExcel(userData, reportData)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.fuelConsumptionReport = (from, to, userData) => {
|
|
95
|
+
return require('./fuelconsumption-report').createFuelConsumptionReport(from, to, userData, this.traccar)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.fuelConsumptionReportToPDF = (userData, reportData) => {
|
|
99
|
+
return require('./fuelconsumption-report').exportFuelConsumptionReportToPDF(userData, reportData)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.fuelConsumptionReportToExcel = (userData, reportData) => {
|
|
103
|
+
return require('./fuelconsumption-report').exportFuelConsumptionReportToExcel(userData, reportData)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.locationReport = (from, to, userData) => {
|
|
107
|
+
return require('./location-report').createLocationReport(from, to, userData, this.traccar)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.locationReportToPDF = (userData, reportData) => {
|
|
111
|
+
return require('./location-report').exportLocationReportToPDF(userData, reportData)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.locationReportToExcel = (userData, reportData) => {
|
|
115
|
+
return require('./location-report').exportLocationReportToExcel(userData, reportData)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.activityReport = (from, to, userData) => {
|
|
119
|
+
return require('./activity-report').createActivityReport(from, to, userData, this.traccar)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.activityReportToPDF = (userData, reportData) => {
|
|
123
|
+
return require('./activity-report').exportActivityReportToPDF(userData, reportData)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.activityReportToExcel = (userData, reportData) => {
|
|
127
|
+
return require('./activity-report').exportActivityReportToExcel(userData, reportData)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.kmsReport = (from, to, userData) => {
|
|
131
|
+
return require('./kms-report').createKmsReport(from, to, userData, this.traccar)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
this.kmsReportToPDF = (userData, reportData) => {
|
|
135
|
+
return require('./kms-report').exportKmsReportToPDF(userData, reportData)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this.reportToWord = require('./word').reportToWord
|
|
139
|
+
|
|
140
|
+
this.kmsReportToExcel = (userData, reportData) => {
|
|
141
|
+
return require('./kms-report').exportKmsReportToExcel(userData, reportData)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this.vistaWasteActivityReport = (from, to, userData) => {
|
|
145
|
+
return require('./custom/vistawasteActivity-report').createVistaWasteActivityReport(from, to, userData, this.traccar)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.vistaWasteActivityReportToPDF = (userData, reportData) => {
|
|
149
|
+
return require('./custom/vistawasteActivity-report').exportVistaWasteActivityReportToPDF(userData, reportData)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.vistaWasteActivityReportToExcel = (userData, reportData) => {
|
|
153
|
+
return require('./custom/vistawasteActivity-report').exportVistaWasteActivityReportToExcel(userData, reportData)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.idleReport = (from, to, userData) => {
|
|
157
|
+
return require('./idle-report').createIdleReport(from, to, userData, this.traccar)
|
|
158
|
+
}
|
|
159
|
+
this.idleReportToPDF = (userData, reportData) => {
|
|
160
|
+
return require('./idle-report').exportIdleReportToPDF(userData, reportData)
|
|
161
|
+
}
|
|
162
|
+
this.idleReportToExcel = (userData, reportData) => {
|
|
163
|
+
return require('./idle-report').exportIdleReportToExcel(userData, reportData)
|
|
164
|
+
}
|
|
141
165
|
}
|
|
142
166
|
module.exports = Reports
|
|
143
|
-
|
package/src/refueling-report.js
CHANGED
|
@@ -2,6 +2,7 @@ const helpers = require('@turf/helpers')
|
|
|
2
2
|
const automaticReports = require('./automaticReports')
|
|
3
3
|
const { devicesToProcess } = require('./util/device')
|
|
4
4
|
const distance = require('@turf/distance')
|
|
5
|
+
const messages = require('../lang')
|
|
5
6
|
|
|
6
7
|
const positionsToCheck = 15
|
|
7
8
|
|
|
@@ -175,5 +176,49 @@ async function calculateRefuelingPositions (userData, d, data) {
|
|
|
175
176
|
return refuelingPositions
|
|
176
177
|
}
|
|
177
178
|
|
|
179
|
+
function exportRefuelingReportToExcel (userData, reportData) {
|
|
180
|
+
console.log('Export to Excel')
|
|
181
|
+
const lang = userData.user.attributes.lang
|
|
182
|
+
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
183
|
+
|
|
184
|
+
const settings = {
|
|
185
|
+
sheetName: 'RefuelingReport', // The name of the sheet
|
|
186
|
+
fileName: 'RefuelingReport' // The name of the spreadsheet
|
|
187
|
+
}
|
|
188
|
+
const headers = [
|
|
189
|
+
{ label: translations.report.name, value: 'name' },
|
|
190
|
+
{ label: translations.report.driver, value: 'driver' },
|
|
191
|
+
{ label: translations.report.date, value: 'fixTime' },
|
|
192
|
+
{ label: translations.report.address, value: 'address' },
|
|
193
|
+
{ label: translations.report.refueling, value: 'diff' }
|
|
194
|
+
]
|
|
195
|
+
let data = []
|
|
196
|
+
if (reportData.devices) {
|
|
197
|
+
reportData.devices.forEach(d => {
|
|
198
|
+
data = data.concat(d.refuelings.map(r => {
|
|
199
|
+
return {
|
|
200
|
+
driver: r.driverName,
|
|
201
|
+
diff: r.diff,
|
|
202
|
+
fixTime: new Date(r.position.fixTime).toLocaleString(),
|
|
203
|
+
name: d.device.name,
|
|
204
|
+
address: r.geofenceName || r.position.address
|
|
205
|
+
}
|
|
206
|
+
}))
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
headers,
|
|
212
|
+
data,
|
|
213
|
+
settings
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function exportRefuelingReportToPDF (userData, reportData) {
|
|
218
|
+
console.log('Export to PDF')
|
|
219
|
+
}
|
|
220
|
+
|
|
178
221
|
exports.createRefuelingReport = createRefuelingReport
|
|
179
222
|
exports.calculateRefuelingPositions = calculateRefuelingPositions
|
|
223
|
+
exports.exportRefuelingReportToPDF = exportRefuelingReportToPDF
|
|
224
|
+
exports.exportRefuelingReportToExcel = exportRefuelingReportToExcel
|
package/src/speeding-report.js
CHANGED
|
@@ -276,42 +276,45 @@ async function getCustomSpeedLimitEvents (devices, routes, customSpeed) {
|
|
|
276
276
|
async function getHereEvents (devices, routes, threshold) {
|
|
277
277
|
console.log('here speed limit events')
|
|
278
278
|
const events = []
|
|
279
|
-
|
|
279
|
+
const promises = devices.map(d => new Promise((resolve) => {
|
|
280
280
|
const positions = routes.filter(p => p.deviceId === d.id)
|
|
281
281
|
if (!positions.length) {
|
|
282
282
|
console.log('no positions on device', d.name)
|
|
283
|
-
|
|
283
|
+
resolve()
|
|
284
284
|
}
|
|
285
285
|
let hereAlerts = null
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
})
|
|
298
|
-
if (!hereAlerts.length) {
|
|
299
|
-
console.log('empty array after filter on device', d.name)
|
|
300
|
-
continue
|
|
301
|
-
}
|
|
302
|
-
const reduced = hereAlerts.length < 2
|
|
303
|
-
? hereAlerts
|
|
304
|
-
: hereAlerts.reduce((acc, cur, idx, src) => {
|
|
305
|
-
if (idx === 1) {
|
|
306
|
-
return [cur]
|
|
307
|
-
}
|
|
308
|
-
if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
|
|
309
|
-
return acc.concat(cur)
|
|
286
|
+
here.routeMatch(positions).then(results => {
|
|
287
|
+
hereAlerts = results.filter(r => r.currentSpeedKmh > (parseInt(r.speedLimit) + threshold)).map(r => {
|
|
288
|
+
const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
|
|
289
|
+
return {
|
|
290
|
+
...r,
|
|
291
|
+
roadSpeedLimit: r.speedLimit,
|
|
292
|
+
deviceId: d.id,
|
|
293
|
+
position,
|
|
294
|
+
positionId: position && position.id,
|
|
295
|
+
attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
|
|
310
296
|
}
|
|
311
|
-
return acc
|
|
312
297
|
})
|
|
313
|
-
|
|
314
|
-
|
|
298
|
+
if (!hereAlerts.length) {
|
|
299
|
+
console.log('empty array after filter on device', d.name)
|
|
300
|
+
resolve()
|
|
301
|
+
}
|
|
302
|
+
const reduced = hereAlerts.length < 2
|
|
303
|
+
? hereAlerts
|
|
304
|
+
: hereAlerts.reduce((acc, cur, idx, src) => {
|
|
305
|
+
if (idx === 1) {
|
|
306
|
+
return [cur]
|
|
307
|
+
}
|
|
308
|
+
if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
|
|
309
|
+
return acc.concat(cur)
|
|
310
|
+
}
|
|
311
|
+
return acc
|
|
312
|
+
})
|
|
313
|
+
events.push(...reduced)
|
|
314
|
+
resolve()
|
|
315
|
+
})
|
|
316
|
+
}))
|
|
317
|
+
await Promise.all(promises)
|
|
315
318
|
return events
|
|
316
319
|
}
|
|
317
320
|
|
package/src/trip-report.js
CHANGED
|
@@ -358,7 +358,7 @@ function exportTripReportToExcel (userData, reportData) {
|
|
|
358
358
|
}
|
|
359
359
|
const headers = userData.byDriver
|
|
360
360
|
? [
|
|
361
|
-
{ label: translations.report.driver, value: '
|
|
361
|
+
{ label: translations.report.driver, value: 'name' },
|
|
362
362
|
{ label: translations.report.date, value: 'date' },
|
|
363
363
|
{ label: translations.report.start, value: 'start' },
|
|
364
364
|
{ label: translations.report.end, value: 'end' },
|
|
@@ -369,7 +369,7 @@ function exportTripReportToExcel (userData, reportData) {
|
|
|
369
369
|
{ label: translations.report.distance, value: 'distance' },
|
|
370
370
|
{ label: translations.report.avgSpeed, value: 'averageSpeed' },
|
|
371
371
|
{ label: translations.report.maxSpeed, value: 'maxSpeed' },
|
|
372
|
-
{ label: translations.report.vehicle, value: '
|
|
372
|
+
{ label: translations.report.vehicle, value: 'subname' }
|
|
373
373
|
]
|
|
374
374
|
: [
|
|
375
375
|
{ label: translations.report.vehicle, value: 'name' },
|
|
@@ -383,7 +383,7 @@ function exportTripReportToExcel (userData, reportData) {
|
|
|
383
383
|
{ label: translations.report.distance, value: 'distance' },
|
|
384
384
|
{ label: translations.report.avgSpeed, value: 'averageSpeed' },
|
|
385
385
|
{ label: translations.report.maxSpeed, value: 'maxSpeed' },
|
|
386
|
-
{ label: translations.report.driver, value: '
|
|
386
|
+
{ label: translations.report.driver, value: 'subname' }
|
|
387
387
|
]
|
|
388
388
|
let data = []
|
|
389
389
|
if (tripsData) {
|
|
@@ -391,7 +391,7 @@ function exportTripReportToExcel (userData, reportData) {
|
|
|
391
391
|
data = data.concat([{}])
|
|
392
392
|
data = data.concat(d.trips.map(a => {
|
|
393
393
|
return {
|
|
394
|
-
name: a.deviceName,
|
|
394
|
+
name: userData.byDriver ? getDriverName(userData.drivers, a.driverUniqueId) : a.deviceName,
|
|
395
395
|
date: getTripDate(userData.user, a),
|
|
396
396
|
start: getTripStart(userData.user, a),
|
|
397
397
|
end: getTripEnd(userData.user, a),
|
|
@@ -402,17 +402,18 @@ function exportTripReportToExcel (userData, reportData) {
|
|
|
402
402
|
distance: Number(a.totalKms.toFixed(2)),
|
|
403
403
|
averageSpeed: Math.round(a.averageSpeed * 1.85200),
|
|
404
404
|
maxSpeed: Math.round(a.maxSpeed * 1.85200),
|
|
405
|
-
|
|
405
|
+
subname: userData.byDriver ? a.deviceName : getDriverName(userData.drivers, a.driverUniqueId)
|
|
406
406
|
}
|
|
407
407
|
}))
|
|
408
408
|
// Totals
|
|
409
409
|
data = data.concat([{
|
|
410
|
+
name: d.trips.length,
|
|
410
411
|
tripTime: convertMS(d.trips.reduce((a, b) => a + b.duration, 0)),
|
|
411
412
|
idleTime: convertMS(d.trips.reduce((a, b) => a + b.stopEngineHours, 0)),
|
|
412
413
|
stopTime: convertMS(d.trips.reduce((a, b) => a + b.stopDuration, 0)),
|
|
413
414
|
distance: getSumTotalKms(userData.user, d.trips),
|
|
414
415
|
averageSpeed: getSumAvgSpeed(d.trips),
|
|
415
|
-
maxSpeed: getMaxSpeed(
|
|
416
|
+
maxSpeed: getMaxSpeed(d.trips)
|
|
416
417
|
}])
|
|
417
418
|
data = data.concat([{}])
|
|
418
419
|
})
|