fleetmap-reports 1.0.274 → 1.0.278
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/codeStyles/Project.xml +7 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- 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/activity-report.js +14 -44
- package/src/here.js +0 -1
- package/src/idle-report.js +285 -0
- package/src/index.js +10 -0
- package/src/index.test.js +3 -43
- package/src/kms-report.js +9 -33
- package/src/speeding-report.js +8 -4
- package/src/util/pdfDocument.js +4 -0
- package/.idea/runConfigurations.xml +0 -10
- package/.idea/workspace.xml +0 -471
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
package/src/activity-report.js
CHANGED
|
@@ -9,6 +9,7 @@ const {getStyle} = require("./reportStyle")
|
|
|
9
9
|
const {getUserPartner} = require("fleetmap-partners")
|
|
10
10
|
const traccar = require("./util/traccar")
|
|
11
11
|
const {createKmsReport} = require("./kms-report");
|
|
12
|
+
const {isInsideTimetable} = require("./util/trips");
|
|
12
13
|
|
|
13
14
|
let traccarInstance
|
|
14
15
|
let userData
|
|
@@ -214,50 +215,19 @@ function processDrivers(from, to, drivers, data) {
|
|
|
214
215
|
if(userData.groupByDay) {
|
|
215
216
|
const dates = getDates(from, to)
|
|
216
217
|
for(const date of dates){
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
} else {
|
|
231
|
-
if((date.getDay() === 0 && userData.weekDays.sunday) ||
|
|
232
|
-
(date.getDay() === 1 && userData.weekDays.monday) ||
|
|
233
|
-
(date.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
234
|
-
(date.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
235
|
-
(date.getDay() === 4 && userData.weekDays.thursday) ||
|
|
236
|
-
(date.getDay() === 5 && userData.weekDays.friday) ||
|
|
237
|
-
(date.getDay() === 6 && userData.weekDays.saturday)) {
|
|
238
|
-
|
|
239
|
-
const fromByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
|
|
240
|
-
const toByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
|
|
241
|
-
|
|
242
|
-
const tripsByDay = trips.filter(t => new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
|
|
243
|
-
|
|
244
|
-
driverData.summary.push({
|
|
245
|
-
date: date,
|
|
246
|
-
distance: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0),
|
|
247
|
-
engineHours: tripsByDay.reduce((a, b) => a + b.duration, 0),
|
|
248
|
-
maxSpeed: tripsByDay.reduce((a, b) => Math.max(a, b.maxSpeed), 0),
|
|
249
|
-
averageSpeed: tripsByDay.length > 0 ? Math.round(tripsByDay.reduce((a, b) => a + b.averageSpeed, 0) / tripsByDay.length) : 0,
|
|
250
|
-
})
|
|
251
|
-
}else {
|
|
252
|
-
driverData.summary.push({
|
|
253
|
-
date: date,
|
|
254
|
-
distance: 0,
|
|
255
|
-
engineHours: 0,
|
|
256
|
-
maxSpeed: 0,
|
|
257
|
-
averageSpeed: 0,
|
|
258
|
-
})
|
|
259
|
-
}
|
|
260
|
-
}
|
|
218
|
+
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
219
|
+
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
220
|
+
|
|
221
|
+
const tripsByDay = trips.filter(t => (new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
|
|
222
|
+
&& (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
|
|
223
|
+
|
|
224
|
+
driverData.summary.push({
|
|
225
|
+
date: date,
|
|
226
|
+
distance: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0),
|
|
227
|
+
engineHours: tripsByDay.reduce((a, b) => a + b.duration, 0),
|
|
228
|
+
maxSpeed: tripsByDay.reduce((a, b) => Math.max(a, b.maxSpeed), 0),
|
|
229
|
+
averageSpeed: tripsByDay.length > 0 ? Math.round(tripsByDay.reduce((a, b) => a + b.averageSpeed, 0) / tripsByDay.length) : 0,
|
|
230
|
+
})
|
|
261
231
|
}
|
|
262
232
|
} else {
|
|
263
233
|
driverData.summary.push({
|
package/src/here.js
CHANGED
|
@@ -100,7 +100,6 @@ exports.routeMatch = async (rows) => {
|
|
|
100
100
|
const csv = generateCSV(rows)
|
|
101
101
|
const response = await axios.post(calcRoute, csv, { headers: { 'Content-Type': 'application/binary' }})
|
|
102
102
|
const hereData = response.data
|
|
103
|
-
console.dir(hereData, {depth: null})
|
|
104
103
|
const route = hereData.response.route[0]
|
|
105
104
|
const results = []
|
|
106
105
|
const wayPoints = route.waypoint
|
|
@@ -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/index.test.js
CHANGED
|
@@ -1,60 +1,20 @@
|
|
|
1
1
|
const {getReports} = require("./tests");
|
|
2
2
|
|
|
3
|
-
describe('
|
|
3
|
+
describe('speedingReport', function() {
|
|
4
4
|
this.timeout(500000)
|
|
5
5
|
it('test speeding', async () => {
|
|
6
6
|
const report = await getReports()
|
|
7
7
|
const userData = await report.getUserData()
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
await report.speedingReport(new Date(2021, 2, 30, 0, 0, 0, 0),
|
|
10
10
|
new Date(2021, 2, 30, 23, 59, 59, 0),
|
|
11
11
|
userData)
|
|
12
|
-
|
|
13
|
-
console.log(reportData)
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
it('test trip report', async () => {
|
|
17
|
-
const report = await getReports()
|
|
18
|
-
const userData = await report.getUserData()
|
|
19
|
-
userData.byGroup = true
|
|
20
|
-
const reportData = await report.tripReport(new Date(2021, 2, 30, 0, 0, 0, 0),
|
|
21
|
-
new Date(2021, 2, 30, 23, 59, 59, 0),
|
|
22
|
-
userData)
|
|
23
|
-
|
|
24
|
-
console.log(reportData)
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
it('test event report', async () => {
|
|
28
|
-
const report = await getReports()
|
|
29
|
-
const userData = await report.getUserData()
|
|
30
|
-
userData.eventTypes = []
|
|
31
|
-
const reportData = await report.eventsReport(new Date(2021, 10, 20, 0, 0, 0, 0),
|
|
32
|
-
new Date(2021, 10, 30, 23, 59, 59, 0),
|
|
33
|
-
userData)
|
|
34
|
-
|
|
35
|
-
console.log(reportData)
|
|
36
|
-
|
|
37
12
|
})
|
|
38
13
|
it('test kmsReport by day', async () => {
|
|
39
14
|
const reports = await getReports()
|
|
40
15
|
const userData = await reports.getUserData()
|
|
41
16
|
userData.groupByDay = true
|
|
42
|
-
|
|
43
|
-
userData)
|
|
44
|
-
|
|
45
|
-
console.log(reportData)
|
|
46
|
-
|
|
47
|
-
await reports.kmsReportToPDF(userData, reportData[0])
|
|
48
|
-
})
|
|
49
|
-
it('test locationReport by day', async () => {
|
|
50
|
-
const reports = await getReports()
|
|
51
|
-
const userData = await reports.getUserData()
|
|
52
|
-
userData.groupByDay = true
|
|
53
|
-
const reportData = await reports.locations(new Date(2021, 10, 1), new Date(2021, 10, 3),
|
|
17
|
+
await reports.kmsReport(new Date(2021, 9), new Date(2021, 10),
|
|
54
18
|
userData)
|
|
55
|
-
|
|
56
|
-
console.log(reportData)
|
|
57
|
-
|
|
58
|
-
await reports.kmsReportToPDF(userData, reportData[0])
|
|
59
19
|
})
|
|
60
20
|
})
|
package/src/kms-report.js
CHANGED
|
@@ -8,6 +8,7 @@ const traccar = require("./util/traccar");
|
|
|
8
8
|
const {getDates} = require("./util/utils");
|
|
9
9
|
const trips = require("./util/trips");
|
|
10
10
|
const drivers = require("./util/driver");
|
|
11
|
+
const {isInsideTimetable} = require("./util/trips");
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
let traccarInstance
|
|
@@ -124,41 +125,16 @@ function processDrivers(from, to, drivers, data) {
|
|
|
124
125
|
driverData.days = []
|
|
125
126
|
const dates = getDates(from, to)
|
|
126
127
|
for(const date of dates){
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
128
|
+
const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
|
|
129
|
+
const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
const tripsByDay = trips.filter(t => (new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
|
|
132
|
+
&& (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else {
|
|
138
|
-
if((date.getDay() === 0 && userData.weekDays.sunday) ||
|
|
139
|
-
(date.getDay() === 1 && userData.weekDays.monday) ||
|
|
140
|
-
(date.getDay() === 2 && userData.weekDays.tuesday) ||
|
|
141
|
-
(date.getDay() === 3 && userData.weekDays.wednesday) ||
|
|
142
|
-
(date.getDay() === 4 && userData.weekDays.thursday) ||
|
|
143
|
-
(date.getDay() === 5 && userData.weekDays.friday) ||
|
|
144
|
-
(date.getDay() === 6 && userData.weekDays.saturday)) {
|
|
145
|
-
|
|
146
|
-
const fromByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
|
|
147
|
-
const toByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
|
|
148
|
-
|
|
149
|
-
const tripsByDay = trips.filter(t => new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
|
|
150
|
-
|
|
151
|
-
driverData.days.push({
|
|
152
|
-
date: date,
|
|
153
|
-
kms: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0)
|
|
154
|
-
})
|
|
155
|
-
}else {
|
|
156
|
-
driverData.days.push({
|
|
157
|
-
date: date,
|
|
158
|
-
kms: 0
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
}
|
|
134
|
+
driverData.days.push({
|
|
135
|
+
date: date,
|
|
136
|
+
kms: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0)
|
|
137
|
+
})
|
|
162
138
|
}
|
|
163
139
|
} else {
|
|
164
140
|
driverData.summary = {
|
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')
|
|
@@ -205,7 +205,7 @@ async function findEventsPosition(from, to, devices, events, routes){
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
async function getCustomSpeedLimitEvents(devices, routes){
|
|
208
|
-
console.log('
|
|
208
|
+
console.log('custom speed limit events')
|
|
209
209
|
const events = []
|
|
210
210
|
const maxSpeed = userData.customSpeed / 1.85200
|
|
211
211
|
|
|
@@ -235,7 +235,7 @@ async function getCustomSpeedLimitEvents(devices, routes){
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
async function getHereEvents(devices, routes, threshold){
|
|
238
|
-
console.log('
|
|
238
|
+
console.log('here speed limit events')
|
|
239
239
|
const events = []
|
|
240
240
|
for (const d of devices) {
|
|
241
241
|
const positions = routes.filter(p => p.deviceId === d.id)
|
|
@@ -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,
|