fleetmap-reports 1.0.413 → 1.0.416

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/esCL.js CHANGED
@@ -101,7 +101,7 @@ module.exports = {
101
101
  alert_edit_cancel: 'Cancelar',
102
102
  alert_created: 'Alerta creada con éxito!',
103
103
  alert_updated: 'Alerta actualizada con éxito!',
104
- alert_add: 'Adicionar Alerta',
104
+ alert_add: 'Añadir Alerta',
105
105
  alert_edit: 'Editar Alerta',
106
106
  alert_delete: 'Apagar Alerta',
107
107
  alert_overspeed_warning: 'Vehículo sin velocidad máxima establecida',
@@ -268,4 +268,4 @@ module.exports = {
268
268
  in: 'en',
269
269
  fuelDropInfo: 'Fuel drop greater than '
270
270
  }
271
- };
271
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.413",
3
+ "version": "1.0.416",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -6,6 +6,7 @@ const { getUserPartner } = require('fleetmap-partners')
6
6
  const { devicesToProcess } = require('./util/device')
7
7
  const automaticReports = require('./automaticReports')
8
8
  const traccarHelper = require('./util/traccar')
9
+ const { getIdleEvents } = require('./util/route')
9
10
 
10
11
  const fileName = 'IdleReport'
11
12
 
@@ -41,7 +42,11 @@ async function createIdleReportByDriver (from, to, userData, traccarInstance) {
41
42
 
42
43
  const { route } = await traccarHelper.getAllInOne(traccarInstance, from, to, devices, true, false, false, false)
43
44
 
44
- return { drivers: processDrivers(from, to, userData, route) }
45
+ return {
46
+ drivers: processDrivers(from, to, userData, route),
47
+ from,
48
+ to
49
+ }
45
50
  }
46
51
 
47
52
  async function createIdleReportByGroup (from, to, userData, traccarInstance) {
@@ -107,17 +112,21 @@ async function createIdleReportByDevice (from, to, userData, traccarInstance) {
107
112
  function processDrivers (from, to, userData, routes) {
108
113
  const driversResult = []
109
114
  userData.drivers.forEach(d => {
110
- const route = routes.filter(p => p.attributes.driverUniqueId === d.uniqueId || !p.attributes.ignition)
115
+ const route = routes.filter(p => p.attributes.driverUniqueId === d.uniqueId)
111
116
 
112
- const idleEvents = getIdleEvents(route)
113
- console.log(idleEvents)
114
117
  if (route.length > 0) {
118
+ const idleEvents = getIdleEvents(routes, d)
115
119
  const filteredEvents = idleEvents.filter(e => userData.minimumIdleMinutes ? e.idleTime > userData.minimumIdleMinutes * 60 * 1000 : true)
116
120
 
117
121
  if (filteredEvents.length) {
122
+ filteredEvents.forEach(e => {
123
+ const device = userData.devices.find(d => d.id === e.position.deviceId)
124
+ e.deviceName = device ? device.name : ''
125
+ })
126
+
118
127
  const driverData = {
119
128
  driver: d,
120
- idleEvents: filteredEvents
129
+ idleEvents: filteredEvents.sort((a, b) => (new Date(a.position.fixTime) > new Date(b.position.fixTime)) ? 1 : -1)
121
130
  }
122
131
  driversResult.push(driverData)
123
132
  }
@@ -149,46 +158,6 @@ function processDevices (from, to, devices, routes, userData) {
149
158
  return devicesResult
150
159
  }
151
160
 
152
- function getIdleEvents (route) {
153
- const idleEvents = []
154
-
155
- const routeByDevice = route.reduce(function (a, x) {
156
- (a[x.deviceId] = a[x.deviceId] || []).push(x)
157
- return a
158
- }, {})
159
-
160
- Object.keys(routeByDevice).forEach(function (key) {
161
- let inIdle = false
162
- routeByDevice[key].forEach(p => {
163
- if (p.attributes.ignition && p.speed === 0) {
164
- if (!inIdle) {
165
- const idleEvent = {
166
- position: p,
167
- idleTime: 0
168
- }
169
- idleEvents.push(idleEvent)
170
- inIdle = true
171
- } else {
172
- if (!idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId) {
173
- idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId = p.attributes.driverUniqueId
174
- }
175
- if (p.attributes.idleTime) {
176
- idleEvents[idleEvents.length - 1].idleTime = p.attributes.idleTime
177
- }
178
- }
179
- } else if (inIdle) {
180
- const currentIdleEvent = idleEvents[idleEvents.length - 1]
181
- if (p.attributes.idleTime === undefined) {
182
- currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
183
- }
184
- inIdle = false
185
- }
186
- })
187
- })
188
-
189
- return idleEvents
190
- }
191
-
192
161
  async function exportIdleReportToPDF (userData, reportData) {
193
162
  console.log('Export to PDF')
194
163
 
package/src/index.test.js CHANGED
@@ -208,8 +208,8 @@ describe('Test_Reports', function () {
208
208
  assert.equal(data.length, 1)
209
209
  const driver = data[0].drivers.find(d => d.driver.id === 14020)
210
210
  const totalIdleTime = driver.idleEvents.reduce((a, b) => a + b.idleTime, 0)
211
- assert.equal(driver.idleEvents.length, 12) // Total Alerts
212
- assert.equal(totalIdleTime, 30785000) // Total Duration
211
+ assert.equal(driver.idleEvents.length, 1) // Total Alerts
212
+ assert.equal(totalIdleTime, 8267000) // Total Duration
213
213
  }, 20000)
214
214
  // eslint-disable-next-line no-undef
215
215
  it('Activity by device', async () => {
@@ -7,8 +7,9 @@ const { headerFromUser, addTable } = require('./util/pdfDocument')
7
7
  const { getStyle } = require('./reportStyle')
8
8
  const traccarHelper = require('./util/traccar')
9
9
  const trips = require('./util/trips')
10
- const { isInsideTimetable, addNearestPOIs, isPartialInsideTimetable, calculateTrip } = require('./util/trips')
10
+ const { isInsideTimetable, addNearestPOIs, isPartialInsideTimetable, calculateTrip, getTripIdleTime } = require('./util/trips')
11
11
  const { devicesToProcess } = require('./util/device')
12
+ const { getIdleEvents } = require('./util/route')
12
13
 
13
14
  const fileName = 'TripReport'
14
15
 
@@ -192,6 +193,13 @@ function processDrivers (from, to, userData, data) {
192
193
 
193
194
  trips.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime())
194
195
 
196
+ const idleEvents = getIdleEvents(data.route, d)
197
+
198
+ trips.forEach(function (trip, i) {
199
+ trip.stopEngineHours = getTripIdleTime(trip, idleEvents)
200
+ trip.stopDuration = i !== trips.length - 1 ? (new Date(trips[i + 1].startTime) - new Date(trip.endTime)) : 0
201
+ })
202
+
195
203
  addNearestPOIs(trips, userData)
196
204
 
197
205
  if (trips.length > 0) {
@@ -229,7 +237,9 @@ async function exportTripReportToPDF (userData, reportData) {
229
237
  ]
230
238
 
231
239
  if (userData.byDriver) {
232
- headers.push(translations.report.distance,
240
+ headers.push(translations.report.idleTime,
241
+ translations.report.stopTime,
242
+ translations.report.distance,
233
243
  translations.report.avgSpeed,
234
244
  translations.report.maxSpeed,
235
245
  translations.report.name)
@@ -276,7 +286,7 @@ async function exportTripReportToPDF (userData, reportData) {
276
286
  doc.text(translations.report.headerStartAddress + ': ' + d.trips[0].startAddress, 20, space + 35)
277
287
  }
278
288
 
279
- d.trips.map(a => {
289
+ d.trips.forEach(a => {
280
290
  const temp = [
281
291
  getTripDate(userData.user, a),
282
292
  getTripStart(userData.user, a),
@@ -285,18 +295,16 @@ async function exportTripReportToPDF (userData, reportData) {
285
295
  convertMS(a.duration)
286
296
  ]
287
297
 
298
+ temp.push(convertMS(a.stopEngineHours),
299
+ convertMS(a.stopDuration),
300
+ Intl.NumberFormat(userData.user.attributes.lang, { maximumFractionDigits: 2 }).format(a.totalKms),
301
+ Math.round(a.averageSpeed * 1.85200),
302
+ Math.round(a.maxSpeed * 1.85200))
303
+
288
304
  if (userData.byDriver) {
289
- temp.push(Intl.NumberFormat(userData.user.attributes.lang, { maximumFractionDigits: 2 }).format(a.totalKms),
290
- Math.round(a.averageSpeed * 1.85200),
291
- Math.round(a.maxSpeed * 1.85200),
292
- a.deviceName)
305
+ temp.push(a.deviceName)
293
306
  } else {
294
- temp.push(convertMS(a.stopEngineHours),
295
- convertMS(a.stopDuration),
296
- Intl.NumberFormat(userData.user.attributes.lang, { maximumFractionDigits: 2 }).format(a.totalKms),
297
- Math.round(a.averageSpeed * 1.85200),
298
- Math.round(a.maxSpeed * 1.85200),
299
- getDriverName(userData.drivers, a.driverUniqueId))
307
+ temp.push(getDriverName(userData.drivers, a.driverUniqueId))
300
308
  }
301
309
 
302
310
  data.push(temp)
@@ -307,17 +315,11 @@ async function exportTripReportToPDF (userData, reportData) {
307
315
  convertMS(d.trips.reduce((a, b) => a + b.duration, 0))
308
316
  ]
309
317
 
310
- if (userData.byDriver) {
311
- footValues.push(getSumTotalKms(userData.user, d.trips),
312
- getSumAvgSpeed(d.trips),
313
- getMaxSpeed(d.trips))
314
- } else {
315
- footValues.push(convertMS(d.trips.reduce((a, b) => a + b.stopEngineHours, 0)),
316
- convertMS(d.trips.reduce((a, b) => a + b.stopDuration, 0)),
317
- getSumTotalKms(userData.user, d.trips),
318
- getSumAvgSpeed(d.trips),
319
- getMaxSpeed(d.trips))
320
- }
318
+ footValues.push(convertMS(d.trips.reduce((a, b) => a + b.stopEngineHours, 0)),
319
+ convertMS(d.trips.reduce((a, b) => a + b.stopDuration, 0)),
320
+ getSumTotalKms(userData.user, d.trips),
321
+ getSumAvgSpeed(d.trips),
322
+ getMaxSpeed(d.trips))
321
323
 
322
324
  const style = getStyle(getUserPartner(userData.user))
323
325
  addTable(doc, headers, data, footValues, style, space + (userData.allWeek ? 40 : 45))
@@ -345,6 +347,8 @@ function exportTripReportToExcel (userData, reportData) {
345
347
  { label: translations.report.end, value: 'end' },
346
348
  { label: translations.report.endAddress, value: 'endAddress' },
347
349
  { label: translations.report.tripTime, value: 'tripTime' },
350
+ { label: translations.report.idleTime, value: 'idleTime' },
351
+ { label: translations.report.stopTime, value: 'stopTime' },
348
352
  { label: translations.report.distance, value: 'distance' },
349
353
  { label: translations.report.avgSpeed, value: 'averageSpeed' },
350
354
  { label: translations.report.maxSpeed, value: 'maxSpeed' },
@@ -0,0 +1,42 @@
1
+ function getIdleEvents (route, driver) {
2
+ const idleEvents = []
3
+
4
+ const routeByDevice = route.reduce(function (a, x) {
5
+ (a[x.deviceId] = a[x.deviceId] || []).push(x)
6
+ return a
7
+ }, {})
8
+
9
+ Object.keys(routeByDevice).forEach(function (key) {
10
+ let inIdle = false
11
+ routeByDevice[key].forEach(p => {
12
+ if (p.attributes.ignition && p.speed === 0 && (!driver || p.attributes.driverUniqueId === driver.uniqueId)) {
13
+ if (!inIdle) {
14
+ const idleEvent = {
15
+ position: p,
16
+ idleTime: 0
17
+ }
18
+ idleEvents.push(idleEvent)
19
+ inIdle = true
20
+ } else {
21
+ if (!idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId) {
22
+ idleEvents[idleEvents.length - 1].position.attributes.driverUniqueId = p.attributes.driverUniqueId
23
+ }
24
+
25
+ if (p.attributes.idleTime) {
26
+ idleEvents[idleEvents.length - 1].idleTime = p.attributes.idleTime
27
+ }
28
+ }
29
+ } else if (inIdle) {
30
+ const currentIdleEvent = idleEvents[idleEvents.length - 1]
31
+ if (p.attributes.idleTime === undefined) {
32
+ currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
33
+ }
34
+ inIdle = false
35
+ }
36
+ })
37
+ })
38
+
39
+ return idleEvents
40
+ }
41
+
42
+ exports.getIdleEvents = getIdleEvents
package/src/util/trips.js CHANGED
@@ -1,175 +1,178 @@
1
- const {coordsDistance, convertFromUTC, weekDaySelected} = require("./utils");
1
+ const { coordsDistance, convertFromUTC, weekDaySelected, convertFromLocal } = require('./utils')
2
2
 
3
3
  const minDistance = 0
4
4
  const minAvgSpeed = 0
5
5
 
6
- function addNearestPOIs(trips, userData){
7
- trips.forEach(t => {
8
- t.totalKms = t.distance / 1000
9
-
10
- const distance = userData.geofences
11
- .filter(g => g && g.area.startsWith('CIRCLE'))
12
- .map(g => {
13
- const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
14
- const coord = str.trim().split(' ')
15
- return {
16
- p: g,
17
- distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
18
- }
19
- })
20
- const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
21
- if (nearestPOIs.length > 0) {
22
- t.endPOIName = nearestPOIs[0].p.name
6
+ function addNearestPOIs (trips, userData) {
7
+ trips.forEach(t => {
8
+ t.totalKms = t.distance / 1000
9
+
10
+ const distance = userData.geofences
11
+ .filter(g => g && g.area.startsWith('CIRCLE'))
12
+ .map(g => {
13
+ const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
14
+ const coord = str.trim().split(' ')
15
+ return {
16
+ p: g,
17
+ distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
23
18
  }
24
- })
25
- }
26
-
27
- function checkTripsKms(traccarInstance, from, to, devices, data) {
28
- console.log('checkTripsKms')
29
- const trips = data.trips.filter(t => t.distance === minDistance && t.averageSpeed > minAvgSpeed)
30
- if(trips.length > 0) {
31
- //Vehicles with imported positions. calculate trip distance with route positions
32
- trips.forEach(t => {
33
- if(t.distance === minDistance && t.averageSpeed > minAvgSpeed) {
34
- const tripRoute = data.route.filter(p => p.deviceId === t.deviceId
35
- && new Date(p.fixTime).getTime() >= new Date(t.startTime).getTime()
36
- && new Date(p.fixTime).getTime() <= new Date(t.endTime).getTime())
37
-
38
- let current = null
39
- const distances = []
40
- for(const p of tripRoute) {
41
- if(current) {
42
- distances.push(coordsDistance(parseFloat(current.longitude),parseFloat(current.latitude),
43
- parseFloat(p.longitude),parseFloat(p.latitude)))
44
- }
45
- current = p
46
- }
47
-
48
- t.distance = distances.reduce((a, b) => a + b, 0)
49
- }
50
- })
19
+ })
20
+ const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
21
+ if (nearestPOIs.length > 0) {
22
+ t.endPOIName = nearestPOIs[0].p.name
51
23
  }
24
+ })
52
25
  }
53
26
 
54
- function isPartialInsideTimetable(t, userData, route){
55
- const tripStart = new Date(t.startTime)
56
- const tripEnd = new Date(t.endTime)
57
-
58
- let isPartialInside = false
59
-
60
- if(weekDaySelected(tripStart, userData.weekDays)) {
61
-
62
- const startDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
63
- const endDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
64
-
65
- if(startDate.getTime() > endDate.getTime()){
66
- //Trip starts outside time period and ends inside time period
67
- if (tripStart.getTime() < endDate.getTime()
68
- && tripEnd.getTime() > endDate.getTime()) {
69
- //Trip starts inside time period and ends outside time period
70
- const routeInside = route.filter(p => new Date(p.fixTime).getTime() < new Date(endDate.toUTCString()).getTime() && new Date(p.fixTime).getTime() > new Date(t.startTime).getTime() && t.deviceId === p.deviceId)
71
- updateTrip(t, routeInside)
72
- t.endTime = endDate.toISOString()
73
- t.endTimeIsOut = true
74
- isPartialInside = true
75
- }
76
-
77
- if (tripStart.getTime() < startDate.getTime()
78
- && new Date(t.endTime).getTime() > startDate.getTime()) {
79
-
80
- //Trip starts outside time period and ends inside time period
81
- const routeInside = route.filter(p => new Date(p.fixTime).getTime() > startDate.getTime() && new Date(p.fixTime).getTime() < new Date(t.endTime).getTime() && t.deviceId === p.deviceId)
82
- updateTrip(t, routeInside)
83
- t.startTime = startDate.toISOString()
84
- t.startTimeIsOut = true
85
- isPartialInside = true
86
- }
87
-
88
- } else {
89
- if (tripStart.getTime() < startDate.getTime()
90
- && tripEnd.getTime() > startDate.getTime()) {
91
- //Trip starts outside time period and ends inside time period
92
- const routeInside = route.filter(p => new Date(p.fixTime).getTime() > new Date(startDate.toUTCString()).getTime() && new Date(p.fixTime).getTime() < new Date(t.endTime).getTime() && t.deviceId === p.deviceId)
93
- updateTrip(t, routeInside)
94
- t.startTime = startDate.toISOString()
95
- t.startTimeIsOut = true
96
- isPartialInside = true
97
- }
98
-
99
- if (tripStart.getTime() < endDate.getTime()
100
- && tripEnd.getTime() > endDate.getTime()) {
101
- //Trip starts inside time period and ends outside time period
102
- const routeInside = route.filter(p => new Date(p.fixTime).getTime() < endDate.getTime() && new Date(p.fixTime).getTime() > new Date(t.startTime).getTime() && t.deviceId === p.deviceId)
103
- updateTrip(t, routeInside)
104
- t.endTime = endDate.toISOString()
105
- t.endTimeIsOut = true
106
- isPartialInside = true
107
- }
27
+ function checkTripsKms (traccarInstance, from, to, devices, data) {
28
+ console.log('checkTripsKms')
29
+ const trips = data.trips.filter(t => t.distance === minDistance && t.averageSpeed > minAvgSpeed)
30
+ if (trips.length > 0) {
31
+ // Vehicles with imported positions. calculate trip distance with route positions
32
+ trips.forEach(t => {
33
+ if (t.distance === minDistance && t.averageSpeed > minAvgSpeed) {
34
+ const tripRoute = data.route.filter(p => p.deviceId === t.deviceId &&
35
+ new Date(p.fixTime).getTime() >= new Date(t.startTime).getTime() &&
36
+ new Date(p.fixTime).getTime() <= new Date(t.endTime).getTime())
37
+
38
+ let current = null
39
+ const distances = []
40
+ for (const p of tripRoute) {
41
+ if (current) {
42
+ distances.push(coordsDistance(parseFloat(current.longitude), parseFloat(current.latitude),
43
+ parseFloat(p.longitude), parseFloat(p.latitude)))
44
+ }
45
+ current = p
108
46
  }
109
- }
110
47
 
111
- return isPartialInside
48
+ t.distance = distances.reduce((a, b) => a + b, 0)
49
+ }
50
+ })
51
+ }
112
52
  }
113
53
 
54
+ function isPartialInsideTimetable (t, userData, route) {
55
+ const tripStart = new Date(t.startTime)
56
+ const tripEnd = new Date(t.endTime)
57
+
58
+ let isPartialInside = false
59
+
60
+ if (weekDaySelected(tripStart, userData.weekDays)) {
61
+ const startDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
62
+ const endDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
63
+
64
+ if (startDate.getTime() > endDate.getTime()) {
65
+ // Trip starts outside time period and ends inside time period
66
+ if (tripStart.getTime() < endDate.getTime() &&
67
+ tripEnd.getTime() > endDate.getTime()) {
68
+ // Trip starts inside time period and ends outside time period
69
+ const routeInside = route.filter(p => new Date(p.fixTime).getTime() < new Date(endDate.toUTCString()).getTime() && new Date(p.fixTime).getTime() > new Date(t.startTime).getTime() && t.deviceId === p.deviceId)
70
+ updateTrip(t, routeInside)
71
+ t.endTime = convertFromLocal(endDate).toISOString()
72
+ t.endTimeIsOut = true
73
+ isPartialInside = true
74
+ }
75
+
76
+ if (tripStart.getTime() < startDate.getTime() &&
77
+ new Date(t.endTime).getTime() > startDate.getTime()) {
78
+ // Trip starts outside time period and ends inside time period
79
+ const routeInside = route.filter(p => new Date(p.fixTime).getTime() > startDate.getTime() && new Date(p.fixTime).getTime() < new Date(t.endTime).getTime() && t.deviceId === p.deviceId)
80
+ updateTrip(t, routeInside)
81
+ t.startTime = convertFromLocal(startDate).toISOString()
82
+ t.startTimeIsOut = true
83
+ isPartialInside = true
84
+ }
85
+ } else {
86
+ if (tripStart.getTime() < startDate.getTime() &&
87
+ tripEnd.getTime() > startDate.getTime()) {
88
+ // Trip starts outside time period and ends inside time period
89
+ const routeInside = route.filter(p => new Date(p.fixTime).getTime() > new Date(startDate.toUTCString()).getTime() && new Date(p.fixTime).getTime() < new Date(t.endTime).getTime() && t.deviceId === p.deviceId)
90
+ updateTrip(t, routeInside)
91
+ t.startTime = convertFromLocal(startDate).toISOString()
92
+ t.startTimeIsOut = true
93
+ isPartialInside = true
94
+ }
95
+
96
+ if (tripStart.getTime() < endDate.getTime() &&
97
+ tripEnd.getTime() > endDate.getTime()) {
98
+ // Trip starts inside time period and ends outside time period
99
+ const routeInside = route.filter(p => new Date(p.fixTime).getTime() < endDate.getTime() && new Date(p.fixTime).getTime() > new Date(t.startTime).getTime() && t.deviceId === p.deviceId)
100
+ updateTrip(t, routeInside)
101
+ t.endTime = convertFromLocal(endDate).toISOString()
102
+ t.endTimeIsOut = true
103
+ isPartialInside = true
104
+ }
105
+ }
106
+ }
107
+
108
+ return isPartialInside
109
+ }
114
110
 
115
- function isInsideTimetable(t, userData){
116
- const tripStart = new Date(t.startTime)
117
- const tripEnd = new Date(t.endTime)
111
+ function isInsideTimetable (t, userData) {
112
+ const tripStart = new Date(t.startTime)
113
+ const tripEnd = new Date(t.endTime)
118
114
 
119
- if(weekDaySelected(tripStart, userData.weekDays)) {
120
- const startDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
121
- const endDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
115
+ if (weekDaySelected(tripStart, userData.weekDays)) {
116
+ const startDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
117
+ const endDate = new Date(convertFromUTC(t.startTime, userData.user.attributes.timezone).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
122
118
 
123
- //Trips inside time period
124
- if(startDate.getTime() < endDate.getTime()) {
125
- console.log((tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()))
126
- return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
127
- } else {
128
- return (tripStart.getTime() < endDate.getTime() && tripEnd.getTime() < endDate.getTime()) ||
119
+ // Trips inside time period
120
+ if (startDate.getTime() < endDate.getTime()) {
121
+ console.log((tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()))
122
+ return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
123
+ } else {
124
+ return (tripStart.getTime() < endDate.getTime() && tripEnd.getTime() < endDate.getTime()) ||
129
125
  (tripStart.getTime() > startDate.getTime())
130
- }
131
126
  }
127
+ }
132
128
 
133
- return false
129
+ return false
134
130
  }
135
131
 
136
- function updateTrip(t, route){
137
- if (!route[route.length-1]) { return }
138
- const distance = route[route.length-1].attributes.totalDistance - route[0].attributes.totalDistance
139
- t.distance = distance
140
- t.duration = new Date(route[route.length-1].fixTime).getTime() - new Date(route[0].fixTime).getTime()
141
- t.maxSpeed = route.reduce((a, b) => Math.max(a, b.speed), 0)
142
- t.averageSpeed = distance > 0 ? ((route.reduce((a, b) => a + b.speed, 0)) / route.length) : 0
132
+ function updateTrip (t, route) {
133
+ if (!route[route.length - 1]) { return }
134
+ const distance = route[route.length - 1].attributes.totalDistance - route[0].attributes.totalDistance
135
+ t.distance = distance
136
+ t.duration = new Date(route[route.length - 1].fixTime).getTime() - new Date(route[0].fixTime).getTime()
137
+ t.maxSpeed = route.reduce((a, b) => Math.max(a, b.speed), 0)
138
+ t.averageSpeed = distance > 0 ? ((route.reduce((a, b) => a + b.speed, 0)) / route.length) : 0
143
139
  }
144
140
 
145
- function calculateTrip(device, route) {
146
- const startPos = route[0]
147
- const endPos = route[route.length-1]
148
-
149
- return {
150
- deviceId: device.id,
151
- deviceName: device.name,
152
- distance: route.reduce((a, b) => a + b.attributes.distance, 0),
153
- averageSpeed: Math.round((route.map(p => p.speed).reduce((a, b) => a + b, 0)) / route.length),
154
- maxSpeed: route.map(p => p.speed).reduce(function (a, b) { return Math.max(a, b) }),
155
- spentFuel: 0,
156
- startOdometer: startPos.attributes.odometer || startPos.attributes.totalDistance,
157
- endOdometer: endPos.attributes.odometer || endPos.attributes.totalDistance,
158
- startPositionId: startPos.id,
159
- endPositionId: endPos.id,
160
- startLat: startPos.latitude,
161
- startLon: startPos.longitude,
162
- startTime: startPos.fixTime,
163
- startAddress: startPos.address,
164
- endLat: endPos.latitude,
165
- endLon: endPos.longitude,
166
- endTime: endPos.fixTime,
167
- endAddress: endPos.address,
168
- endTimeIsOut: true,
169
- duration: new Date(endPos.fixTime).getTime() - new Date(startPos.fixTime).getTime(),
170
- driverUniqueId: null,
171
- driverName: null
172
- }
141
+ function calculateTrip (device, route) {
142
+ const startPos = route[0]
143
+ const endPos = route[route.length - 1]
144
+
145
+ return {
146
+ deviceId: device.id,
147
+ deviceName: device.name,
148
+ distance: route.reduce((a, b) => a + b.attributes.distance, 0),
149
+ averageSpeed: Math.round((route.map(p => p.speed).reduce((a, b) => a + b, 0)) / route.length),
150
+ maxSpeed: route.map(p => p.speed).reduce(function (a, b) { return Math.max(a, b) }),
151
+ spentFuel: 0,
152
+ startOdometer: startPos.attributes.odometer || startPos.attributes.totalDistance,
153
+ endOdometer: endPos.attributes.odometer || endPos.attributes.totalDistance,
154
+ startPositionId: startPos.id,
155
+ endPositionId: endPos.id,
156
+ startLat: startPos.latitude,
157
+ startLon: startPos.longitude,
158
+ startTime: startPos.fixTime,
159
+ startAddress: startPos.address,
160
+ endLat: endPos.latitude,
161
+ endLon: endPos.longitude,
162
+ endTime: endPos.fixTime,
163
+ endAddress: endPos.address,
164
+ endTimeIsOut: true,
165
+ duration: new Date(endPos.fixTime).getTime() - new Date(startPos.fixTime).getTime(),
166
+ driverUniqueId: null,
167
+ driverName: null
168
+ }
169
+ }
170
+
171
+ function getTripIdleTime (trip, idleEvents) {
172
+ const tripStartDate = new Date(trip.startTime)
173
+ const tripEndDate = new Date(trip.endTime)
174
+ const idleEventsInsideTrip = idleEvents.filter(i => tripStartDate < new Date(i.position.fixTime) && tripEndDate > new Date(i.position.fixTime))
175
+ return idleEventsInsideTrip.reduce((a, b) => a + b.idleTime, 0)
173
176
  }
174
177
 
175
178
  exports.checkTripsKms = checkTripsKms
@@ -177,3 +180,4 @@ exports.isInsideTimetable = isInsideTimetable
177
180
  exports.isPartialInsideTimetable = isPartialInsideTimetable
178
181
  exports.addNearestPOIs = addNearestPOIs
179
182
  exports.calculateTrip = calculateTrip
183
+ exports.getTripIdleTime = getTripIdleTime
package/src/util/utils.js CHANGED
@@ -186,6 +186,14 @@ function convertFromUTC (value, timezone) {
186
186
  return valueDate
187
187
  }
188
188
 
189
+ exports.convertFromLocal = (value, timezone) => {
190
+ const offset = getTimezoneOffset(timezone)
191
+
192
+ const valueDate = new Date(value)
193
+ valueDate.setTime(valueDate.getTime() + (offset * 60 * 1000))
194
+ return valueDate
195
+ }
196
+
189
197
  function weekDaySelected (date, weekDays) {
190
198
  return (date.getDay() === 0 && weekDays.sunday) ||
191
199
  (date.getDay() === 1 && weekDays.monday) ||