fleetmap-reports 1.0.249 → 1.0.250
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 +15 -6
- package/package.json +1 -1
- package/src/index.js +2 -2
- package/src/speeding-report.js +105 -40
package/.idea/workspace.xml
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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="
|
|
4
|
+
<list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="kms report - show every selected day">
|
|
5
5
|
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
6
|
+
<change beforePath="$PROJECT_DIR$/src/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.js" afterDir="false" />
|
|
6
7
|
<change beforePath="$PROJECT_DIR$/src/index.test.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.test.js" afterDir="false" />
|
|
7
|
-
<change beforePath="$PROJECT_DIR$/src/
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/src/util/utils.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/util/utils.js" afterDir="false" />
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/src/speeding-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/speeding-report.js" afterDir="false" />
|
|
9
9
|
</list>
|
|
10
10
|
<option name="SHOW_DIALOG" value="false" />
|
|
11
11
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -195,7 +195,8 @@
|
|
|
195
195
|
<workItem from="1638888787940" duration="19894000" />
|
|
196
196
|
<workItem from="1639074912454" duration="257000" />
|
|
197
197
|
<workItem from="1639090037682" duration="2514000" />
|
|
198
|
-
<workItem from="1639135460686" duration="
|
|
198
|
+
<workItem from="1639135460686" duration="3092000" />
|
|
199
|
+
<workItem from="1639151097761" duration="12693000" />
|
|
199
200
|
</task>
|
|
200
201
|
<task id="LOCAL-00001" summary="Fix getStyle">
|
|
201
202
|
<created>1636983717385</created>
|
|
@@ -267,7 +268,14 @@
|
|
|
267
268
|
<option name="project" value="LOCAL" />
|
|
268
269
|
<updated>1639057192382</updated>
|
|
269
270
|
</task>
|
|
270
|
-
<
|
|
271
|
+
<task id="LOCAL-00011" summary="kms report - show every selected day">
|
|
272
|
+
<created>1639139696407</created>
|
|
273
|
+
<option name="number" value="00011" />
|
|
274
|
+
<option name="presentableId" value="LOCAL-00011" />
|
|
275
|
+
<option name="project" value="LOCAL" />
|
|
276
|
+
<updated>1639139696408</updated>
|
|
277
|
+
</task>
|
|
278
|
+
<option name="localTasksCounter" value="12" />
|
|
271
279
|
<servers />
|
|
272
280
|
</component>
|
|
273
281
|
<component name="TypeScriptGeneratedFilesManager">
|
|
@@ -296,6 +304,7 @@
|
|
|
296
304
|
<MESSAGE value="fix speeding report" />
|
|
297
305
|
<MESSAGE value="refactor speeding and trip report" />
|
|
298
306
|
<MESSAGE value="Kms report with time period" />
|
|
299
|
-
<
|
|
307
|
+
<MESSAGE value="kms report - show every selected day" />
|
|
308
|
+
<option name="LAST_COMMIT_MESSAGE" value="kms report - show every selected day" />
|
|
300
309
|
</component>
|
|
301
310
|
</project>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -19,8 +19,8 @@ function Reports(config, axios) {
|
|
|
19
19
|
byGroup: false
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
this.speedingReport = (from, to, userData
|
|
23
|
-
return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar
|
|
22
|
+
this.speedingReport = (from, to, userData) => {
|
|
23
|
+
return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
this.speedingReportToPDF = (userData, reportData) => {
|
package/src/speeding-report.js
CHANGED
|
@@ -13,16 +13,18 @@ const {getUserPartner} = require("fleetmap-partners");
|
|
|
13
13
|
const traccar = require("./util/traccar");
|
|
14
14
|
|
|
15
15
|
let traccarInstance
|
|
16
|
+
let userData
|
|
16
17
|
|
|
17
18
|
const fileName = 'SpeedingReport'
|
|
18
19
|
|
|
19
|
-
async function createSpeedingReport(from, to,
|
|
20
|
+
async function createSpeedingReport(from, to, reportUserData, traccar) {
|
|
20
21
|
traccarInstance = traccar
|
|
21
|
-
|
|
22
|
+
userData = reportUserData
|
|
23
|
+
console.log('createSpeedingReport', from, to, userData, traccar)
|
|
22
24
|
const reportData = []
|
|
23
25
|
|
|
24
26
|
if(userData.byDriver){
|
|
25
|
-
const allData = await createSpeedingReportByDriver(from, to
|
|
27
|
+
const allData = await createSpeedingReportByDriver(from, to)
|
|
26
28
|
reportData.push(allData)
|
|
27
29
|
}
|
|
28
30
|
else if(userData.byGroup){
|
|
@@ -37,48 +39,50 @@ async function createSpeedingReport(from, to, userData, traccar, roadSpeedLimits
|
|
|
37
39
|
xpert: devices.filter(d => d.attributes.xpert).length > 0
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
+
const eventTypes = ['deviceOverspeed']
|
|
43
|
+
const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
|
|
44
|
+
const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, devices)
|
|
42
45
|
|
|
43
46
|
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
44
47
|
|
|
45
|
-
if (
|
|
46
|
-
groupData.devices = await processDevices(from, to, devices,
|
|
48
|
+
if (events.length > 0) {
|
|
49
|
+
groupData.devices = await processDevices(from, to, devices, events, routes)
|
|
47
50
|
reportData.push(groupData)
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
const withoutGroupData = await createSpeedingReportByDevice(from, to
|
|
55
|
+
const withoutGroupData = await createSpeedingReportByDevice(from, to)
|
|
53
56
|
reportData.push(withoutGroupData)
|
|
54
57
|
} else {
|
|
55
|
-
const allData = await createSpeedingReportByDevice(from, to
|
|
58
|
+
const allData = await createSpeedingReportByDevice(from, to)
|
|
56
59
|
reportData.push(allData)
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
return reportData
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
async function createSpeedingReportByDevice(from, to
|
|
65
|
+
async function createSpeedingReportByDevice(from, to) {
|
|
63
66
|
const groupIds = userData.groups.map(g => g.id)
|
|
64
67
|
const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
|
|
65
68
|
|
|
66
69
|
withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
67
70
|
|
|
68
|
-
const
|
|
69
|
-
const
|
|
71
|
+
const eventTypes = ['deviceOverspeed']
|
|
72
|
+
const events = await traccar.getEvents(traccarInstance, from, to, withoutGroupDevices, eventTypes)
|
|
73
|
+
const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, withoutGroupDevices)
|
|
70
74
|
|
|
71
75
|
const allData = { devices: [] }
|
|
72
76
|
|
|
73
|
-
if(
|
|
74
|
-
allData.devices = await processDevices(from, to, withoutGroupDevices,
|
|
77
|
+
if(events.length > 0 || userData.roadSpeedLimits) {
|
|
78
|
+
allData.devices = await processDevices(from, to, withoutGroupDevices, events, routes)
|
|
75
79
|
allData.xpert = withoutGroupDevices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
return allData
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
async function createSpeedingReportByDriver(from, to
|
|
85
|
+
async function createSpeedingReportByDriver(from, to) {
|
|
82
86
|
const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
|
|
83
87
|
console.log('Devices with driver',deviceIds.length)
|
|
84
88
|
|
|
@@ -93,18 +97,18 @@ async function createSpeedingReportByDriver(from, to, userData) {
|
|
|
93
97
|
}
|
|
94
98
|
console.log(eventsData.length)
|
|
95
99
|
|
|
96
|
-
await getEventsPosition(from , to, userData.devices,
|
|
97
|
-
allData.drivers = await processDrivers(from, to,
|
|
100
|
+
await getEventsPosition(from , to, userData.devices, eventsData)
|
|
101
|
+
allData.drivers = await processDrivers(from, to, eventsData)
|
|
98
102
|
console.log(allData.drivers.length)
|
|
99
103
|
return allData
|
|
100
104
|
}
|
|
101
105
|
|
|
102
|
-
async function processDrivers(from, to,
|
|
106
|
+
async function processDrivers(from, to, data) {
|
|
103
107
|
console.log(data)
|
|
104
108
|
const driversResult = []
|
|
105
109
|
const alertsWithPosition = data.filter(a => a.position)
|
|
106
110
|
|
|
107
|
-
drivers.forEach(d => {
|
|
111
|
+
userData.drivers.forEach(d => {
|
|
108
112
|
const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
|
|
109
113
|
|
|
110
114
|
if (alerts.length > 0) {
|
|
@@ -124,34 +128,70 @@ async function processDrivers(from, to, drivers, data) {
|
|
|
124
128
|
return driversResult
|
|
125
129
|
}
|
|
126
130
|
|
|
127
|
-
async function processDevices(from, to, devices,
|
|
131
|
+
async function processDevices(from, to, devices, events, routes) {
|
|
128
132
|
const devicesResult = []
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
if(userData.useVehicleSpeedLimit) {
|
|
135
|
+
await getEventsPosition(from, to, devices, events)
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
console.log(events)
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
for (const d of devices) {
|
|
140
|
+
const deviceEvents = events.filter(t => t.deviceId === d.id)
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
if (deviceEvents.length > 0) {
|
|
143
|
+
const alertsWithPosition = deviceEvents.filter(a => a.position).sort((a, b) => a.positionId - b.positionId)
|
|
144
|
+
devicesResult.push({
|
|
145
|
+
device: d,
|
|
146
|
+
from: from,
|
|
147
|
+
to: to,
|
|
148
|
+
alerts: alertsWithPosition,
|
|
149
|
+
maxSpeed: alertsWithPosition.reduce((a, b) => {
|
|
150
|
+
return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
|
|
151
|
+
}, 0),
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
for (const d of devices) {
|
|
157
|
+
const positions = routes.filter(t => t.deviceId === d.id)
|
|
158
|
+
const maxSpeed = userData.customSpeed / 1.85200
|
|
159
|
+
|
|
160
|
+
const alerts = []
|
|
161
|
+
for(let pIndex = 0; pIndex < positions.length ; pIndex++){
|
|
162
|
+
const position = positions[pIndex]
|
|
163
|
+
if(position.speed > maxSpeed){
|
|
164
|
+
const alert = {
|
|
165
|
+
position: position,
|
|
166
|
+
attributes: {
|
|
167
|
+
speedLimit: maxSpeed,
|
|
168
|
+
speed: position.speed
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
pIndex = calculateEventData(positions, pIndex, alert)
|
|
173
|
+
|
|
174
|
+
alerts.push(alert)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if(alerts.length > 0){
|
|
178
|
+
devicesResult.push({
|
|
179
|
+
device: d,
|
|
180
|
+
from: from,
|
|
181
|
+
to: to,
|
|
182
|
+
alerts: alerts,
|
|
183
|
+
maxSpeed: alerts.reduce((a, b) => {
|
|
184
|
+
return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
|
|
185
|
+
}, 0),
|
|
186
|
+
})
|
|
187
|
+
}
|
|
148
188
|
}
|
|
149
189
|
}
|
|
150
190
|
|
|
151
191
|
return devicesResult
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
async function getEventsPosition(from, to, devices,
|
|
194
|
+
async function getEventsPosition(from, to, devices, events){
|
|
155
195
|
|
|
156
196
|
const deviceIds = [...new Set(events.map(e => e.deviceId))]
|
|
157
197
|
const routeData = await traccar.getRoute(traccarInstance, from, to, deviceIds.map(id => { return { id: id } } ))
|
|
@@ -161,10 +201,10 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
161
201
|
for (const d of devices) {
|
|
162
202
|
let alerts = events.filter(t => t.deviceId === d.id)
|
|
163
203
|
|
|
164
|
-
if (alerts.length > 0 || roadSpeedLimits) {
|
|
204
|
+
if (alerts.length > 0 || userData.roadSpeedLimits) {
|
|
165
205
|
const positions = routeData.filter(p => p.deviceId === d.id)
|
|
166
206
|
|
|
167
|
-
if (roadSpeedLimits && positions.length) {
|
|
207
|
+
if (userData.roadSpeedLimits && positions.length) {
|
|
168
208
|
try {
|
|
169
209
|
const results = await here.routeMatch(positions)
|
|
170
210
|
const hereAlerts = results.map(r => {
|
|
@@ -202,7 +242,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
202
242
|
let geofence = null
|
|
203
243
|
|
|
204
244
|
if (a.geofenceId) {
|
|
205
|
-
geofence = geofences.find(g => g.id === a.geofenceId)
|
|
245
|
+
geofence = userData.geofences.find(g => g.id === a.geofenceId)
|
|
206
246
|
if (geofence) {
|
|
207
247
|
a.geofenceName = geofence.name + ' (' + Math.round(a.attributes.speedLimit * 1.85200) + ' Km/h)'
|
|
208
248
|
}
|
|
@@ -230,7 +270,7 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
if (a.position.attributes.driverUniqueId) {
|
|
233
|
-
const driver = drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
|
|
273
|
+
const driver = userData.drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
|
|
234
274
|
a.driver = driver && driver.name
|
|
235
275
|
}
|
|
236
276
|
|
|
@@ -243,6 +283,31 @@ async function getEventsPosition(from, to, devices, geofences, drivers, events,
|
|
|
243
283
|
}
|
|
244
284
|
}
|
|
245
285
|
|
|
286
|
+
function calculateEventData(positions, pIndex, a, geofence){
|
|
287
|
+
let endEventPosition = a.position
|
|
288
|
+
let maxSpeed = a.position.speed
|
|
289
|
+
let dist = 0
|
|
290
|
+
while (pIndex + 1 < positions.length) {
|
|
291
|
+
pIndex++
|
|
292
|
+
|
|
293
|
+
dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
|
|
294
|
+
point([positions[pIndex].longitude, positions[pIndex].latitude]))
|
|
295
|
+
endEventPosition = positions[pIndex]
|
|
296
|
+
if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
|
|
297
|
+
a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
|
|
298
|
+
a.attributes.maxSpeed = maxSpeed
|
|
299
|
+
a.distance = dist
|
|
300
|
+
break
|
|
301
|
+
} else {
|
|
302
|
+
if (maxSpeed < endEventPosition.speed) {
|
|
303
|
+
maxSpeed = endEventPosition.speed
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return pIndex
|
|
309
|
+
}
|
|
310
|
+
|
|
246
311
|
function isOutsideGeofence(geofence, endEventPosition) {
|
|
247
312
|
const v = turf.feature(turf.flip(parse(geofence.area)))
|
|
248
313
|
const point = turf.point([endEventPosition.longitude, endEventPosition.latitude])
|