fleetmap-reports 1.0.275 → 1.0.276
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/.idea/workspace.xml +23 -9
- package/lang/enGB.js +1 -0
- package/lang/esCL.js +1 -0
- package/lang/ptBR.js +1 -0
- package/lang/ptPT.js +1 -0
- package/package.json +1 -1
- package/src/idle-report.js +285 -0
- package/src/index.js +10 -0
- package/src/speeding-report.js +6 -2
- package/src/util/pdfDocument.js +4 -0
package/.idea/workspace.xml
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<project version="4">
|
|
3
3
|
<component name="ChangeListManager">
|
|
4
|
-
<list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="
|
|
5
|
-
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
6
|
-
<change beforePath="$PROJECT_DIR$/src/activity-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/activity-report.js" afterDir="false" />
|
|
4
|
+
<list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="Add idle report">
|
|
7
5
|
<change beforePath="$PROJECT_DIR$/src/index.test.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.test.js" afterDir="false" />
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/src/
|
|
6
|
+
<change beforePath="$PROJECT_DIR$/src/speeding-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/speeding-report.js" afterDir="false" />
|
|
9
7
|
</list>
|
|
10
8
|
<option name="SHOW_DIALOG" value="false" />
|
|
11
9
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -233,7 +231,9 @@
|
|
|
233
231
|
<workItem from="1641921254910" duration="614000" />
|
|
234
232
|
<workItem from="1641991863387" duration="626000" />
|
|
235
233
|
<workItem from="1641992769870" duration="96000" />
|
|
236
|
-
<workItem from="1641992912450" duration="
|
|
234
|
+
<workItem from="1641992912450" duration="1734000" />
|
|
235
|
+
<workItem from="1642001918030" duration="2950000" />
|
|
236
|
+
<workItem from="1642028703547" duration="8996000" />
|
|
237
237
|
</task>
|
|
238
238
|
<task id="LOCAL-00001" summary="Fix getStyle">
|
|
239
239
|
<created>1636983717385</created>
|
|
@@ -424,7 +424,21 @@
|
|
|
424
424
|
<option name="project" value="LOCAL" />
|
|
425
425
|
<updated>1641912050985</updated>
|
|
426
426
|
</task>
|
|
427
|
-
<
|
|
427
|
+
<task id="LOCAL-00028" summary="Fix activity and kms report by driver inside a time period">
|
|
428
|
+
<created>1641994017219</created>
|
|
429
|
+
<option name="number" value="00028" />
|
|
430
|
+
<option name="presentableId" value="LOCAL-00028" />
|
|
431
|
+
<option name="project" value="LOCAL" />
|
|
432
|
+
<updated>1641994017220</updated>
|
|
433
|
+
</task>
|
|
434
|
+
<task id="LOCAL-00029" summary="Add idle report">
|
|
435
|
+
<created>1642039915131</created>
|
|
436
|
+
<option name="number" value="00029" />
|
|
437
|
+
<option name="presentableId" value="LOCAL-00029" />
|
|
438
|
+
<option name="project" value="LOCAL" />
|
|
439
|
+
<updated>1642039915132</updated>
|
|
440
|
+
</task>
|
|
441
|
+
<option name="localTasksCounter" value="30" />
|
|
428
442
|
<servers />
|
|
429
443
|
</component>
|
|
430
444
|
<component name="TypeScriptGeneratedFilesManager">
|
|
@@ -454,8 +468,6 @@
|
|
|
454
468
|
<option name="oldMeFiltersMigrated" value="true" />
|
|
455
469
|
</component>
|
|
456
470
|
<component name="VcsManagerConfiguration">
|
|
457
|
-
<MESSAGE value="Fix getStyle in all reports" />
|
|
458
|
-
<MESSAGE value="try catch on pdf addImage" />
|
|
459
471
|
<MESSAGE value="Kms report grouped by day" />
|
|
460
472
|
<MESSAGE value="Fix pdf logo" />
|
|
461
473
|
<MESSAGE value="kms report with parallel requests" />
|
|
@@ -479,6 +491,8 @@
|
|
|
479
491
|
<MESSAGE value="fix trip report" />
|
|
480
492
|
<MESSAGE value="fix kms report by group" />
|
|
481
493
|
<MESSAGE value="fix convert date to localeString" />
|
|
482
|
-
<
|
|
494
|
+
<MESSAGE value="Fix activity and kms report by driver inside a time period" />
|
|
495
|
+
<MESSAGE value="Add idle report" />
|
|
496
|
+
<option name="LAST_COMMIT_MESSAGE" value="Add idle report" />
|
|
483
497
|
</component>
|
|
484
498
|
</project>
|
package/lang/enGB.js
CHANGED
package/lang/esCL.js
CHANGED
|
@@ -176,6 +176,7 @@ module.exports = {
|
|
|
176
176
|
titleEventsReport: 'Informe de Eventos',
|
|
177
177
|
titleActivityReport: 'Activity Report',
|
|
178
178
|
titleKmsReport: 'Informe de Kms',
|
|
179
|
+
titleIdleReport: 'Relatórios de Ralenti',
|
|
179
180
|
from: 'De',
|
|
180
181
|
to: 'a',
|
|
181
182
|
headerStartAddress: 'Lugar de início',
|
package/lang/ptBR.js
CHANGED
|
@@ -172,6 +172,7 @@ module.exports = {
|
|
|
172
172
|
titleEventsReport: 'Relatório de Eventos',
|
|
173
173
|
titleActivityReport: 'Relatório de Actividade',
|
|
174
174
|
titleKmsReport: 'Relatórios de Kms',
|
|
175
|
+
titleIdleReport: 'Relatórios de Ralenti',
|
|
175
176
|
from: 'De',
|
|
176
177
|
to: 'a',
|
|
177
178
|
headerStartAddress: 'Local de início',
|
package/lang/ptPT.js
CHANGED
|
@@ -178,6 +178,7 @@ module.exports = {
|
|
|
178
178
|
titleEventsReport: 'Relatório de Eventos',
|
|
179
179
|
titleActivityReport: 'Relatório de Actividade',
|
|
180
180
|
titleKmsReport: 'Relatórios de Kms',
|
|
181
|
+
titleIdleReport: 'Relatórios de Ralenti',
|
|
181
182
|
from: 'De',
|
|
182
183
|
to: 'a',
|
|
183
184
|
headerStartAddress: 'Local de início',
|
package/package.json
CHANGED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
const traccar = require("./util/traccar");
|
|
2
|
+
const messages = require("../lang");
|
|
3
|
+
const jsPDF = require("jspdf");
|
|
4
|
+
const {headerFromUser, AmiriRegular} = require("./util/pdfDocument");
|
|
5
|
+
const {convertToLocaleString, convertMS} = require("./util/utils");
|
|
6
|
+
const {getStyle} = require("./reportStyle");
|
|
7
|
+
const {getUserPartner} = require("fleetmap-partners");
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
let traccarInstance
|
|
11
|
+
let userData
|
|
12
|
+
|
|
13
|
+
const fileName = 'IdleReport'
|
|
14
|
+
|
|
15
|
+
async function createIdleReport(from, to, reportUserData, traccar) {
|
|
16
|
+
console.log('Create IdleReport')
|
|
17
|
+
userData = reportUserData
|
|
18
|
+
traccarInstance = traccar
|
|
19
|
+
const reportData = []
|
|
20
|
+
|
|
21
|
+
if (userData.byGroup) {
|
|
22
|
+
console.log("ByGroup")
|
|
23
|
+
const allData = await createTripReportByGroup(from, to)
|
|
24
|
+
reportData.push(...allData)
|
|
25
|
+
} else {
|
|
26
|
+
console.log("ByDevice")
|
|
27
|
+
const report = await createTripReportByDevice(from, to)
|
|
28
|
+
reportData.push(report)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return reportData
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function createTripReportByGroup(from, to) {
|
|
35
|
+
const reportData = []
|
|
36
|
+
for (const g of userData.groups) {
|
|
37
|
+
const devices = userData.devices.filter(d => d.groupId === g.id)
|
|
38
|
+
console.log(g.name + ' devices:' + devices.length)
|
|
39
|
+
if(devices.length > 0) {
|
|
40
|
+
const groupData = {
|
|
41
|
+
devices: [],
|
|
42
|
+
group: g,
|
|
43
|
+
from: from,
|
|
44
|
+
to: to
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const response = await traccarInstance.reports.reportsRouteGet(from, to, null, [g.id])
|
|
48
|
+
const routes = response.data
|
|
49
|
+
|
|
50
|
+
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
51
|
+
|
|
52
|
+
if (routes.length > 0) {
|
|
53
|
+
console.log('Routes:' + routes.length)
|
|
54
|
+
groupData.devices = processDevices(from, to, devices, routes)
|
|
55
|
+
|
|
56
|
+
reportData.push(groupData)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const groupIds = userData.groups.map(g => g.id)
|
|
62
|
+
const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
|
|
63
|
+
|
|
64
|
+
const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
|
|
65
|
+
reportData.push(allData)
|
|
66
|
+
|
|
67
|
+
return reportData
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function createTripReportByDevice(from, to) {
|
|
71
|
+
const devices = userData.devices
|
|
72
|
+
const allData = {
|
|
73
|
+
devices: [],
|
|
74
|
+
from: from,
|
|
75
|
+
to: to
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
79
|
+
|
|
80
|
+
const devicesToSlice = devices.slice()
|
|
81
|
+
const route = await traccar.getRoute(traccarInstance, from, to, devicesToSlice)
|
|
82
|
+
|
|
83
|
+
console.log('Route:' + route.length)
|
|
84
|
+
|
|
85
|
+
if (route.length > 0) {
|
|
86
|
+
allData.devices = processDevices(from, to, devices, route)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return allData
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function processDevices(from, to, devices, routes) {
|
|
93
|
+
const devicesResult = []
|
|
94
|
+
|
|
95
|
+
devices.forEach(d => {
|
|
96
|
+
const route = routes.filter(p => p.deviceId === d.id)
|
|
97
|
+
|
|
98
|
+
const idleEvents = []
|
|
99
|
+
let inIdle = false
|
|
100
|
+
route.forEach(p => {
|
|
101
|
+
if(p.attributes.ignition && p.speed === 0){
|
|
102
|
+
if(!inIdle) {
|
|
103
|
+
const idleEvent = {
|
|
104
|
+
position: p,
|
|
105
|
+
idleTime: 0
|
|
106
|
+
}
|
|
107
|
+
idleEvents.push(idleEvent)
|
|
108
|
+
inIdle = true
|
|
109
|
+
}
|
|
110
|
+
} else if(inIdle) {
|
|
111
|
+
const currentIdleEvent = idleEvents[idleEvents.length-1]
|
|
112
|
+
currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
|
|
113
|
+
inIdle = false
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
if(idleEvents.length) {
|
|
118
|
+
const deviceData = {
|
|
119
|
+
device: d,
|
|
120
|
+
idleEvents: idleEvents
|
|
121
|
+
}
|
|
122
|
+
devicesResult.push(deviceData)
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return devicesResult
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function exportIdleReportToPDF(userData, reportData) {
|
|
130
|
+
console.log('Export to PDF')
|
|
131
|
+
|
|
132
|
+
const lang = userData.user.attributes.lang
|
|
133
|
+
const timezone = userData.user.attributes.timezone
|
|
134
|
+
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
135
|
+
|
|
136
|
+
const idleData = userData.byDriver ? reportData.drivers : reportData.devices
|
|
137
|
+
|
|
138
|
+
const headers = [
|
|
139
|
+
translations.report.date,
|
|
140
|
+
translations.report.address,
|
|
141
|
+
translations.report.duration
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
if (userData.byDriver) {
|
|
145
|
+
headers.push(translations.report.vehicle)
|
|
146
|
+
} else {
|
|
147
|
+
headers.push(translations.report.driver)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (idleData) {
|
|
151
|
+
let first = true
|
|
152
|
+
const doc = new jsPDF.jsPDF('l');
|
|
153
|
+
await headerFromUser(doc, translations.report.titleIdleReport, userData.user)
|
|
154
|
+
|
|
155
|
+
idleData.forEach(d => {
|
|
156
|
+
try {
|
|
157
|
+
let data = []
|
|
158
|
+
|
|
159
|
+
const name = userData.byDriver ? d.driver.name : deviceName(d.device)
|
|
160
|
+
const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
|
|
161
|
+
|
|
162
|
+
let space = 0
|
|
163
|
+
if(!first) {
|
|
164
|
+
doc.addPage()
|
|
165
|
+
} else {
|
|
166
|
+
first = false
|
|
167
|
+
space = 10
|
|
168
|
+
}
|
|
169
|
+
doc.setFontSize(13)
|
|
170
|
+
doc.text(name, 20, space+20 )
|
|
171
|
+
doc.setFontSize(11)
|
|
172
|
+
doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
|
|
173
|
+
doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, space+25 )
|
|
174
|
+
|
|
175
|
+
d.idleEvents.map(a => {
|
|
176
|
+
const temp = [
|
|
177
|
+
getIdleEventDate(a, userData.user),
|
|
178
|
+
a.position.address,
|
|
179
|
+
convertMS(a.idleTime, true),
|
|
180
|
+
userData.byDriver ? a.deviceName : a.driver
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
data.push(temp)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const footValues = [
|
|
187
|
+
'Total:' + d.idleEvents.length,
|
|
188
|
+
'',
|
|
189
|
+
convertMS(d.idleEvents.reduce((a, b) => a + b.idleTime, 0), true)
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
if(userData.roadSpeedLimits){
|
|
193
|
+
footValues.splice(2, 0, '')
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
|
|
197
|
+
doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
|
|
198
|
+
|
|
199
|
+
const style = getStyle(getUserPartner(userData.user))
|
|
200
|
+
doc.autoTable({
|
|
201
|
+
head: [headers],
|
|
202
|
+
body: data,
|
|
203
|
+
foot: [footValues],
|
|
204
|
+
showFoot: 'lastPage',
|
|
205
|
+
headStyles: {
|
|
206
|
+
fillColor: style.pdfHeaderColor,
|
|
207
|
+
textColor: style.pdfHeaderTextColor,
|
|
208
|
+
fontSize: 10
|
|
209
|
+
},
|
|
210
|
+
bodyStyles: {
|
|
211
|
+
fillColor: style.pdfBodyColor,
|
|
212
|
+
textColor: style.pdfBodyTextColor,
|
|
213
|
+
fontSize: 8,
|
|
214
|
+
font: timezone === 'Asia/Qatar' ? "Amiri" : ''
|
|
215
|
+
|
|
216
|
+
},
|
|
217
|
+
footStyles: {
|
|
218
|
+
fillColor: style.pdfFooterColor,
|
|
219
|
+
textColor: style.pdfFooterTextColor,
|
|
220
|
+
fontSize: 9
|
|
221
|
+
},
|
|
222
|
+
startY: space+35 });
|
|
223
|
+
} catch (e) {
|
|
224
|
+
console.error(e, 'moving on...')
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
return doc
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function exportIdleReportToExcel(userData, reportData) {
|
|
233
|
+
console.log('Export to Excel')
|
|
234
|
+
|
|
235
|
+
const lang = userData.user.attributes.lang
|
|
236
|
+
const translations = messages[lang] ? messages[lang] : messages['en-GB']
|
|
237
|
+
|
|
238
|
+
const idleData = userData.byDriver ? reportData.drivers : reportData.devices
|
|
239
|
+
|
|
240
|
+
const settings = {
|
|
241
|
+
sheetName: translations.report.titleIdleReport.substring(0, 31), // The name of the sheet
|
|
242
|
+
fileName: fileName, // The name of the spreadsheet
|
|
243
|
+
}
|
|
244
|
+
const headers = [
|
|
245
|
+
userData.byDriver ? {label: translations.report.driver, value:'driver'} : {label: translations.report.vehicle, value:'name'},
|
|
246
|
+
{label: translations.report.date, value:'fixTime'},
|
|
247
|
+
{label: translations.report.address, value:'address'},
|
|
248
|
+
{label: translations.report.duration, value:'duration'},
|
|
249
|
+
userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
let data = []
|
|
253
|
+
if (idleData) {
|
|
254
|
+
idleData.forEach(d => {
|
|
255
|
+
data = data.concat([{}])
|
|
256
|
+
data = data.concat(d.idleEvents.map(a => {
|
|
257
|
+
return {
|
|
258
|
+
driver: userData.byDriver ? d.driver.name : a.driver,
|
|
259
|
+
duration: convertMS(a.idleTime, true),
|
|
260
|
+
fixTime: getIdleEventDate(a, userData.user),
|
|
261
|
+
name: userData.byDriver ? a.deviceName : d.device.name,
|
|
262
|
+
address: a.position.address + (a.geofenceName ? ' - ' + a.geofenceName : '')
|
|
263
|
+
}
|
|
264
|
+
}))
|
|
265
|
+
})
|
|
266
|
+
console.log(data)
|
|
267
|
+
return {
|
|
268
|
+
headers,
|
|
269
|
+
data,
|
|
270
|
+
settings
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function deviceName(device){
|
|
276
|
+
return device.name + (device.attributes.license_plate ? ', ' +device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function getIdleEventDate(row, user) {
|
|
280
|
+
return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
exports.createIdleReport = createIdleReport;
|
|
284
|
+
exports.exportIdleReportToPDF = exportIdleReportToPDF;
|
|
285
|
+
exports.exportIdleReportToExcel = exportIdleReportToExcel;
|
package/src/index.js
CHANGED
|
@@ -124,6 +124,16 @@ function Reports(config, axios) {
|
|
|
124
124
|
this.vistaWasteActivityReportToExcel = (userData, reportData) => {
|
|
125
125
|
return require('./custom/vistawasteActivity-report').exportVistaWasteActivityReportToExcel(userData, reportData)
|
|
126
126
|
}
|
|
127
|
+
|
|
128
|
+
this.idleReport = (from, to, userData) => {
|
|
129
|
+
return require('./idle-report').createIdleReport(from, to, userData, this.traccar)
|
|
130
|
+
}
|
|
131
|
+
this.idleReportToPDF = (userData, reportData) => {
|
|
132
|
+
return require('./idle-report').exportIdleReportToPDF(userData, reportData)
|
|
133
|
+
}
|
|
134
|
+
this.idleReportToExcel = (userData, reportData) => {
|
|
135
|
+
return require('./idle-report').exportIdleReportToExcel(userData, reportData)
|
|
136
|
+
}
|
|
127
137
|
}
|
|
128
138
|
module.exports = Reports
|
|
129
139
|
|
package/src/speeding-report.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const messages = require('../lang')
|
|
2
2
|
const jsPDF = require('jspdf')
|
|
3
3
|
const {convertMS, convertToLocaleString} = require("./util/utils")
|
|
4
|
-
const {headerFromUser} = require("./util/pdfDocument")
|
|
4
|
+
const {headerFromUser, AmiriRegular} = require("./util/pdfDocument")
|
|
5
5
|
require('jspdf-autotable')
|
|
6
6
|
const { parse } = require('wkt')
|
|
7
7
|
const turf = require('turf')
|
|
@@ -394,6 +394,9 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
394
394
|
footValues.splice(2, 0, '')
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
+
doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
|
|
398
|
+
doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
|
|
399
|
+
|
|
397
400
|
const style = getStyle(getUserPartner(userData.user))
|
|
398
401
|
doc.autoTable({
|
|
399
402
|
head: [headers],
|
|
@@ -408,7 +411,8 @@ async function exportSpeedingReportToPDF(userData, reportData) {
|
|
|
408
411
|
bodyStyles: {
|
|
409
412
|
fillColor: style.pdfBodyColor,
|
|
410
413
|
textColor: style.pdfBodyTextColor,
|
|
411
|
-
fontSize: 8
|
|
414
|
+
fontSize: 8,
|
|
415
|
+
font: timezone === 'Asia/Qatar' ? "Amiri" : ''
|
|
412
416
|
},
|
|
413
417
|
footStyles: {
|
|
414
418
|
fillColor: style.pdfFooterColor,
|