fleetmap-reports 1.0.392 → 1.0.399

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.
@@ -1,177 +1,179 @@
1
- const helpers = require("turf")
2
- const automaticReports = require("./automaticReports")
3
- const {devicesToProcess} = require("./util/device");
1
+ const helpers = require('@turf/helpers')
2
+ const automaticReports = require('./automaticReports')
3
+ const { devicesToProcess } = require('./util/device')
4
+ const distance = require('@turf/distance')
4
5
 
5
6
  const positionsToCheck = 15
6
7
 
7
- async function createRefuelingReport(from, to, userData, traccar) {
8
- console.log('Create RefuelingReport')
8
+ async function createRefuelingReport (from, to, userData, traccar) {
9
+ console.log('Create RefuelingReport')
9
10
 
10
- const reportData = []
11
+ const reportData = []
11
12
 
12
- const allData = {
13
- devices: [],
14
- from: from,
15
- to: to
16
- }
13
+ const allData = {
14
+ devices: [],
15
+ from,
16
+ to
17
+ }
17
18
 
18
- const devices = devicesToProcess(userData).filter(d => automaticReports.deviceWithFuelInfo(d))
19
+ const devices = devicesToProcess(userData).filter(d => automaticReports.deviceWithFuelInfo(d))
19
20
 
20
- console.log('Devices:'+devices.length)
21
+ console.log('Devices:' + devices.length)
21
22
 
22
- const arrayOfArrays = automaticReports.sliceArray(devices)
23
- let data = []
24
- for (const a of arrayOfArrays) {
25
- const response = await traccar.reports.reportsRouteGet(from, to, a.map(d => d.id))
26
- data = data.concat(response.data)
27
- }
23
+ const arrayOfArrays = automaticReports.sliceArray(devices)
24
+ let data = []
25
+ for (const a of arrayOfArrays) {
26
+ const response = await traccar.reports.reportsRouteGet(from, to, a.map(d => d.id))
27
+ data = data.concat(response.data)
28
+ }
28
29
 
29
- console.log('Locations:'+data.length)
30
+ console.log('Locations:' + data.length)
30
31
 
31
- if(data.length === 0) {
32
- return reportData
33
- }
32
+ if (data.length === 0) {
33
+ return reportData
34
+ }
35
+
36
+ allData.totalDevices = 0
37
+ allData.totalRefueling = 0
38
+ allData.totalRefuelingLiters = 0
39
+
40
+ for (const d of devices) {
41
+ const positions = data.filter(t => t.deviceId === d.id)
42
+
43
+ if (positions.length > 0) {
44
+ const refuelingPositions = await this.calculateRefuelingPositions(userData, d, { route: positions })
45
+
46
+ if (userData.drivers.length > 0) {
47
+ refuelingPositions.forEach(p => {
48
+ const geofence = findNearestPOI(p.position, userData.geofences)
49
+ if (geofence) {
50
+ p.position.geofenceName = geofence.name
51
+ }
52
+ const driver = userData.drivers.find(d => d.uniqueId === p.position.attributes.driverUniqueId)
53
+ if (driver) {
54
+ p.position.driverName = driver.name
55
+ }
56
+ })
57
+ }
34
58
 
35
- allData.totalDevices = 0
36
- allData.totalRefueling = 0
37
- allData.totalRefuelingLiters = 0
38
-
39
- for (const d of devices) {
40
- const positions = data.filter(t => t.deviceId===d.id)
41
-
42
- if(positions.length > 0) {
43
- const refuelingPositions = await this.calculateRefuelingPositions(userData, d, {route: positions})
44
-
45
- if (userData.drivers.length > 0) {
46
- refuelingPositions.forEach(p => {
47
- const geofence = findNearestPOI(p.position, userData.geofences)
48
- if(geofence) {
49
- p.position.geofenceName = geofence.name
50
- }
51
- const driver = userData.drivers.find(d => d.uniqueId === p.position.attributes.driverUniqueId)
52
- if (driver) {
53
- p.position.driverName = driver.name
54
- }
55
- })
56
- }
57
-
58
- if (refuelingPositions.length > 0) {
59
- allData.devices.push({
60
- device: d,
61
- refuelings: refuelingPositions,
62
- })
63
- allData.totalDevices = allData.totalDevices+1
64
- allData.totalRefueling = allData.totalRefueling + refuelingPositions.length
65
- allData.totalRefuelingLiters = allData.totalRefuelingLiters + refuelingPositions.reduce((a, b) => a + b.diff, 0)
66
- }
67
- }
59
+ if (refuelingPositions.length > 0) {
60
+ allData.devices.push({
61
+ device: d,
62
+ refuelings: refuelingPositions
63
+ })
64
+ allData.totalDevices = allData.totalDevices + 1
65
+ allData.totalRefueling = allData.totalRefueling + refuelingPositions.length
66
+ allData.totalRefuelingLiters = allData.totalRefuelingLiters + refuelingPositions.reduce((a, b) => a + b.diff, 0)
67
+ }
68
68
  }
69
+ }
69
70
 
70
- reportData.push(allData)
71
+ reportData.push(allData)
71
72
 
72
- return reportData
73
+ return reportData
73
74
  }
74
75
 
75
- function findNearestPOI(position, geofences) {
76
- if (geofences.length === 0) { return null }
76
+ function findNearestPOI (position, geofences) {
77
+ if (geofences.length === 0) { return null }
77
78
 
78
- if (!position) { return null }
79
+ if (!position) { return null }
79
80
 
80
- const a = geofences.map(g => {
81
- if (g.area) {
82
- const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
83
- const coord = str.trim().split(' ')
84
- return {
85
- id: g.id,
86
- distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), position.longitude, position.latitude))
87
- }
88
- }
89
- return {
90
- id: g.id,
91
- distance: Number.MAX_SAFE_INTEGER
92
- }
93
- }).filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
81
+ const a = geofences.map(g => {
82
+ if (g.area && g.area.startsWith('CIRCLE (')) {
83
+ console.log('->' + g.area)
84
+ const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
94
85
 
95
- if (a.length > 0) {
96
- return a[0]
86
+ const coord = str.trim().split(' ')
87
+ return {
88
+ id: g.id,
89
+ distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), position.longitude, position.latitude))
90
+ }
97
91
  }
92
+ return {
93
+ id: g.id,
94
+ distance: Number.MAX_SAFE_INTEGER
95
+ }
96
+ }).filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
98
97
 
99
- return null
100
- }
101
-
102
- function coordsDistance(lon1, lat1, lon2, lat2) {
103
- const from = helpers.point([lon1, lat1])
104
- const to = helpers.point([lon2, lat2])
98
+ if (a.length > 0) {
99
+ return a[0]
100
+ }
105
101
 
106
- return (helpers.distance(from, to) * 1000)
102
+ return null
107
103
  }
108
104
 
109
- async function calculateRefuelingPositions(userData, d, data) {
110
- const refuelingPositions = []
111
-
112
- if(userData.withOdooServices && d.attributes.odooId) {
113
- console.log(data.fuelServices)
114
- data.fuelServices.forEach(s => {
115
- const serviceDate = new Date(s.date)
116
- serviceDate.setHours(23, 59, 59, 59)
105
+ function coordsDistance (lon1, lat1, lon2, lat2) {
106
+ const from = helpers.point([lon1, lat1])
107
+ const to = helpers.point([lon2, lat2])
117
108
 
118
- const routeBeforeService = data.route.filter(r => new Date(r.fixTime).getTime() < serviceDate.getTime())
109
+ return distance.default(from, to) * 1000
110
+ }
119
111
 
120
- const quantity = s.notes.split(':')[1].replace(',', '.') || 0
112
+ async function calculateRefuelingPositions (userData, d, data) {
113
+ const refuelingPositions = []
114
+
115
+ if (userData.withOdooServices && d.attributes.odooId) {
116
+ console.log(data.fuelServices)
117
+ data.fuelServices.forEach(s => {
118
+ const serviceDate = new Date(s.date)
119
+ serviceDate.setHours(23, 59, 59, 59)
120
+
121
+ const routeBeforeService = data.route.filter(r => new Date(r.fixTime).getTime() < serviceDate.getTime())
122
+
123
+ const quantity = s.notes.split(':')[1].replace(',', '.') || 0
124
+
125
+ if (routeBeforeService.length) {
126
+ refuelingPositions.push({ date: s.date, diff: Number.parseFloat(quantity), cost: s.amount })
127
+ }
128
+ })
129
+ } else {
130
+ let refuelingActivated = false
131
+ let currentValue = null
132
+ let positionsChecked = 0
133
+ let lastRefuelingIndex = 0
134
+ data.route.forEach(function (element, index, array) {
135
+ if (!element.attributes.ignition && refuelingActivated && !currentValue) {
136
+ // Ignition is off and Refueling is Active and there is no current value
137
+
138
+ // Get 5 position before the ignition off to calculate the current value of the fuel tank level
139
+ // lastRefuelingIndex is used to avoid re-analyzing positions prior to a refueling
140
+ const before = (index > 5 ? array.slice((index - 6 < lastRefuelingIndex ? lastRefuelingIndex : index - 6), index - 1) : array.slice(0, index - 1)).filter(b => b.attributes.ignition && b.attributes.fuel)
141
+ currentValue = Math.round(before.reduce((a, b) => a + b.attributes.fuel, 0) / before.length)
142
+
143
+ positionsChecked = 0
144
+ }
145
+
146
+ if (element.attributes.ignition && refuelingActivated && currentValue) {
147
+ // Ignition is on and Refueling is Active and there is a current value
148
+ // Calculate the value of the fuel tank level after turning the ignition back on
149
+ const after = (array.length > index + 5 ? array.slice(index, index + 1) : array.slice(index)).filter(b => b.attributes.ignition && b.attributes.fuel)
150
+ const newValue = Math.round(after.reduce((a, b) => a + b.attributes.fuel, 0) / after.length)
151
+
152
+ const diff = automaticReports.calculateFuelDiff(currentValue, newValue, d)
153
+ if (diff > 20) {
154
+ // New refueling detected
155
+ const value = Math.round(diff * d.attributes.fuel_tank_capacity / 100)
156
+ refuelingPositions.push({ position: element, date: element.fixTime, diff: value })
157
+ lastRefuelingIndex = index
158
+ positionsChecked = positionsToCheck + 1 // to reset values
159
+ }
121
160
 
122
- if (routeBeforeService.length) {
123
- refuelingPositions.push({date: s.date, diff: Number.parseFloat(quantity), cost: s.amount})
124
- }
125
- })
126
- } else {
127
- let refuelingActivated = false
128
- let currentValue = null
129
- let positionsChecked = 0
130
- let lastRefuelingIndex = 0
131
- data.route.forEach(function (element, index, array) {
132
- if (!element.attributes.ignition && refuelingActivated && !currentValue) {
133
- //Ignition is off and Refueling is Active and there is no current value
134
-
135
- //Get 5 position before the ignition off to calculate the current value of the fuel tank level
136
- //lastRefuelingIndex is used to avoid re-analyzing positions prior to a refueling
137
- const before = (index > 5 ? array.slice((index - 6 < lastRefuelingIndex ? lastRefuelingIndex : index - 6), index - 1) : array.slice(0, index - 1)).filter(b => b.attributes.ignition && b.attributes.fuel)
138
- currentValue = Math.round(before.reduce((a, b) => a + b.attributes.fuel, 0) / before.length)
139
-
140
- positionsChecked = 0
141
- }
142
-
143
- if (element.attributes.ignition && refuelingActivated && currentValue) {
144
- //Ignition is on and Refueling is Active and there is a current value
145
- //Calculate the value of the fuel tank level after turning the ignition back on
146
- const after = (array.length > index + 5 ? array.slice(index, index + 1) : array.slice(index)).filter(b => b.attributes.ignition && b.attributes.fuel)
147
- const newValue = Math.round(after.reduce((a, b) => a + b.attributes.fuel, 0) / after.length)
148
-
149
- const diff = automaticReports.calculateFuelDiff(currentValue, newValue, d)
150
- if (diff > 20) {
151
- //New refueling detected
152
- const value = Math.round(diff * d.attributes.fuel_tank_capacity / 100)
153
- refuelingPositions.push({position: element, date: element.fixTime, diff: value})
154
- lastRefuelingIndex = index
155
- positionsChecked = positionsToCheck + 1 // to reset values
156
- }
157
-
158
- if (positionsChecked > positionsToCheck) {
159
- refuelingActivated = false
160
- currentValue = null
161
- positionsChecked = 0
162
- } else {
163
- positionsChecked++
164
- }
165
- }
166
-
167
- if (element.attributes.ignition && !refuelingActivated) {
168
- refuelingActivated = true
169
- }
170
- })
171
- }
172
- return refuelingPositions
161
+ if (positionsChecked > positionsToCheck) {
162
+ refuelingActivated = false
163
+ currentValue = null
164
+ positionsChecked = 0
165
+ } else {
166
+ positionsChecked++
167
+ }
168
+ }
169
+
170
+ if (element.attributes.ignition && !refuelingActivated) {
171
+ refuelingActivated = true
172
+ }
173
+ })
174
+ }
175
+ return refuelingPositions
173
176
  }
174
177
 
175
-
176
- exports.createRefuelingReport = createRefuelingReport;
178
+ exports.createRefuelingReport = createRefuelingReport
177
179
  exports.calculateRefuelingPositions = calculateRefuelingPositions