fleetmap-reports 1.0.513 → 1.0.516

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.513",
3
+ "version": "1.0.516",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,67 +1,66 @@
1
1
  const moment = require('moment')
2
2
 
3
- function sliceArray(longArray, size = 1) {
4
- const arrayToSlice = longArray.slice()
3
+ function sliceArray (longArray, size = 1) {
4
+ const arrayToSlice = longArray.slice()
5
5
 
6
- const arrayOfArrays = []
7
- for (let i=0; i<arrayToSlice.length; i+=size) {
8
- arrayOfArrays.push(arrayToSlice.slice(i,i+size));
9
- }
6
+ const arrayOfArrays = []
7
+ for (let i = 0; i < arrayToSlice.length; i += size) {
8
+ arrayOfArrays.push(arrayToSlice.slice(i, i + size))
9
+ }
10
10
 
11
- return arrayOfArrays
11
+ return arrayOfArrays
12
12
  }
13
13
 
14
- function deviceWithFuelInfo(device) {
15
- return device.attributes.xpert
16
- || (device.attributes.fuel_low_threshold >= 0 && device.attributes.fuel_high_threshold >= 0 && device.attributes.fuel_tank_capacity)
14
+ function deviceWithFuelInfo (device) {
15
+ return device.attributes.odooId || device.attributes.xpert ||
16
+ (device.attributes.fuel_low_threshold >= 0 && device.attributes.fuel_high_threshold >= 0 && device.attributes.fuel_tank_capacity)
17
17
  }
18
18
 
19
- function fuelSignalInverter(device) {
20
- return device.attributes.fuel_low_threshold <= device.attributes.fuel_high_threshold ? 1 : -1
19
+ function fuelSignalInverter (device) {
20
+ return device.attributes.fuel_low_threshold <= device.attributes.fuel_high_threshold ? 1 : -1
21
21
  }
22
22
 
23
- function calculateFuelDiff(a, b, device) {
24
- const diff = (b - a) * fuelSignalInverter(device)
25
- if(device.attributes.xpert) {
26
- return diff
27
- } else {
28
- return (diff * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
29
- }
23
+ function calculateFuelDiff (a, b, device) {
24
+ const diff = (b - a) * fuelSignalInverter(device)
25
+ if (device.attributes.xpert) {
26
+ return diff
27
+ } else {
28
+ return (diff * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
29
+ }
30
30
  }
31
31
 
32
- function calculateXpertSpentFuel(date, positions) {
33
- const begin = moment(date, 'YYYY-MM-DD').startOf('day')
34
- const end = moment(date, 'YYYY-MM-DD').endOf('day')
35
- const datePositions = positions.filter(p => moment(p.fixTime).isAfter(begin) && moment(p.fixTime).isBefore(end))
36
- const xpertMessages = datePositions.map(p => p.attributes.xpert).flat().filter(p => p)
37
- const xpertEndTripMessage = xpertMessages.filter(x => x.type === '3')
38
- if(xpertEndTripMessage.length > 1) {
39
- const diff = xpertEndTripMessage[xpertEndTripMessage.length-1].total_fuel - xpertEndTripMessage[0].total_fuel
40
- console.log('Diff:',diff)
41
- return Math.round(diff)
42
- }
43
- return 0
32
+ function calculateXpertSpentFuel (date, positions) {
33
+ const begin = moment(date, 'YYYY-MM-DD').startOf('day')
34
+ const end = moment(date, 'YYYY-MM-DD').endOf('day')
35
+ const datePositions = positions.filter(p => moment(p.fixTime).isAfter(begin) && moment(p.fixTime).isBefore(end))
36
+ const xpertMessages = datePositions.map(p => p.attributes.xpert).flat().filter(p => p)
37
+ const xpertEndTripMessage = xpertMessages.filter(x => x.type === '3')
38
+ if (xpertEndTripMessage.length > 1) {
39
+ const diff = xpertEndTripMessage[xpertEndTripMessage.length - 1].total_fuel - xpertEndTripMessage[0].total_fuel
40
+ console.log('Diff:', diff)
41
+ return Math.round(diff)
42
+ }
43
+ return 0
44
44
  }
45
45
 
46
- function calculateXpertDistance(date, positions) {
47
- const begin = moment(date, 'YYYY-MM-DD').startOf('day')
48
- const end = moment(date, 'YYYY-MM-DD').endOf('day')
49
- const datePositions = positions.filter(p => moment(p.fixTime).isAfter(begin) && moment(p.fixTime).isBefore(end))
46
+ function calculateXpertDistance (date, positions) {
47
+ const begin = moment(date, 'YYYY-MM-DD').startOf('day')
48
+ const end = moment(date, 'YYYY-MM-DD').endOf('day')
49
+ const datePositions = positions.filter(p => moment(p.fixTime).isAfter(begin) && moment(p.fixTime).isBefore(end))
50
50
 
51
- return datePositions.reduce((a, b) => a + b.attributes.distance, 0)
51
+ return datePositions.reduce((a, b) => a + b.attributes.distance, 0)
52
52
  }
53
53
 
54
- function calculateSpentFuel(value, device) {
55
- if(!value)
56
- return value
54
+ function calculateSpentFuel (value, device) {
55
+ if (!value) { return value }
57
56
 
58
- if(device.attributes.xpert) {
59
- return Math.round(( value * device.attributes.fuel_tank_capacity) / 100)
60
- } else {
61
- const valueSignalCheck = value * fuelSignalInverter(device)
62
- const valuePercentage = (valueSignalCheck * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
63
- return Math.round(( valuePercentage * device.attributes.fuel_tank_capacity) / 100)
64
- }
57
+ if (device.attributes.xpert) {
58
+ return Math.round((value * device.attributes.fuel_tank_capacity) / 100)
59
+ } else {
60
+ const valueSignalCheck = value * fuelSignalInverter(device)
61
+ const valuePercentage = (valueSignalCheck * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
62
+ return Math.round((valuePercentage * device.attributes.fuel_tank_capacity) / 100)
63
+ }
65
64
  }
66
65
 
67
66
  exports.sliceArray = sliceArray
@@ -36,7 +36,7 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
36
36
  for (const d of devices) {
37
37
  const trips = tripsData.filter(t => t.deviceId === d.id)
38
38
  const route = routeData.filter(r => r.deviceId === d.id)
39
- const deviceFuelServices = fuelServicesData.filter(f => d.attributes.odooId === f.vehicle_id[0])
39
+ const deviceFuelServices = fuelServicesData.filter(f => Number.parseInt(d.attributes.odooId) === f.vehicle_id[0])
40
40
 
41
41
  if (trips.length > 0) {
42
42
  const refuelingPositions = await refuelingReport.calculateRefuelingPositions(userData, d, { route, trips, fuelServices: deviceFuelServices })
@@ -45,17 +45,16 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
45
45
  new Map()
46
46
  )
47
47
 
48
- trips.forEach(t => {
49
- t.startDate = t.startTime.substring(0, 10)
50
- })
48
+ trips.forEach(t => { t.startDate = t.startTime.substring(0, 10) })
51
49
  const groupedTripsByDay = trips.reduce(
52
50
  (entryMap, e) => entryMap.set(e.startDate, [...entryMap.get(e.startDate) || [], e]),
53
51
  new Map()
54
52
  )
55
53
 
54
+ const odooAvgConsumption = userData.withOdooServices ? getOdooAvgConsumption(refuelingPositions, trips) : 0
55
+
56
56
  const days = []
57
57
  const keys = Array.from(groupedTripsByDay.keys())
58
- const odooAvgConsumption = userData.withOdooServices ? calculateAvgConsumption(refuelingPositions, trips) : 0
59
58
 
60
59
  keys.forEach(day => {
61
60
  const dayTrips = groupedTripsByDay.get(day)
@@ -67,7 +66,7 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
67
66
  date: day,
68
67
  distance,
69
68
  spentFuel,
70
- avgConsumption: userData.withOdooServices ? odooAvgConsumption : distance > 0 && spentFuel > 0 ? Math.round(spentFuel * 100 / (distance / 1000)) : 0,
69
+ avgConsumption: userData.withOdooServices ? odooAvgConsumption : getCanAvgConsumption(userData, odooAvgConsumption, distance, spentFuel),
71
70
  endOdometer: dayTrips.slice(-1)[0].endOdometer,
72
71
  duration: dayTrips.reduce((a, b) => a + b.duration, 0),
73
72
  refueling: (dayRefueling && dayRefueling.length > 0) ? dayRefueling.reduce((a, b) => a + b.diff, 0) : 0
@@ -91,12 +90,16 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
91
90
  return reportData
92
91
  }
93
92
 
94
- function calculateAvgConsumption (refuelingPositions, trips) {
93
+ function getOdooAvgConsumption (refuelingPositions, trips) {
95
94
  const odooTotalfuel = refuelingPositions.reduce((a, b) => a + b.diff, 0)
96
95
  const totalKms = trips.reduce((a, b) => a + b.distance, 0)
97
96
  return Math.round(odooTotalfuel * 100 / (totalKms / 1000))
98
97
  }
99
98
 
99
+ function getCanAvgConsumption (userData, distance, spentFuel) {
100
+ return distance > 0 && spentFuel > 0 ? Math.round(spentFuel * 100 / (distance / 1000)) : 0
101
+ }
102
+
100
103
  function calculateConsumption (userData, d, day, avgConsumption, data) {
101
104
  if (d.attributes.xpert) {
102
105
  return automaticReports.calculateXpertSpentFuel(day, data.route)
package/src/index.test.js CHANGED
@@ -15,6 +15,7 @@ async function getSpeedingReport (report, userData) {
15
15
 
16
16
  // eslint-disable-next-line no-undef
17
17
  describe('Test_Reports', function () {
18
+ this.timeout(5000000)
18
19
  // eslint-disable-next-line no-undef
19
20
  it('works with road speed limits', async () => {
20
21
  const report = await getReports()
@@ -25,7 +26,7 @@ describe('Test_Reports', function () {
25
26
  assert.equal(totalDistance, 36.63687856826021) // Total Kms
26
27
  assert.equal(totalEventTime, 1524000) // Total Duration
27
28
  }, 200000)
28
-
29
+ // eslint-disable-next-line no-undef
29
30
  it('works by device speed limit', async () => {
30
31
  const report = await getReports()
31
32
  const userData = await report.getUserData()
@@ -69,7 +70,7 @@ describe('Test_Reports', function () {
69
70
  assert.equal(device.trips[0].idleTime, 602000)
70
71
  assert.equal(device.trips[1].endPOIName, undefined)
71
72
  assert.equal(device.totalDistance, 339170.3099999875) // Total Kms
72
- }, 20000)
73
+ }, 30000)
73
74
  // eslint-disable-next-line no-undef
74
75
  it('Trip by driver', async () => {
75
76
  const report = await getReports()
@@ -350,33 +351,18 @@ describe('Test_Reports', function () {
350
351
  it('Refueling Report', async () => {
351
352
  const report = await getReports()
352
353
  const userData = await report.getUserData()
353
-
354
+ userData.withOdooServices = true
354
355
  const data = await report.refuelingReport(
355
- new Date(Date.UTC(2022, 1, 2, 0, 0, 0, 0)),
356
- new Date(Date.UTC(2022, 1, 2, 23, 59, 59, 0)),
357
- userData)
356
+ new Date(Date.UTC(2022, 9, 1, 0, 0, 0, 0)),
357
+ new Date(Date.UTC(2022, 9, 31, 23, 59, 59, 0)),
358
+ userData)
358
359
 
359
360
  assert.equal(data.length, 1)
360
361
  console.log(data[0])
361
- const device = data[0].devices.find(d => d.device.id === 16245)
362
+ const device = data[0].devices.find(d => d.device.id === 22326)
362
363
  assert.equal(device.refuelings.length, 2)
363
364
  }, 30000)
364
365
  // eslint-disable-next-line no-undef
365
- it('Refueling2 Report', async () => {
366
- const report = await getReports()
367
- const userData = await report.getUserData()
368
-
369
- const data = await report.refuelingReport(new Date(2022, 1, 21, 0, 0, 0, 0),
370
- new Date(2022, 1, 25, 23, 59, 59, 0),
371
- userData)
372
-
373
- assert.equal(data.length, 1)
374
- console.log(data[0])
375
- const device = data[0].devices.find(d => d.device.id === 16245)
376
- console.log(device.refuelings)
377
- assert.equal(device.refuelings.length, 4)
378
- }, 30000)
379
- // eslint-disable-next-line no-undef
380
366
  it('FuelConsumption Report', async () => {
381
367
  const report = await getReports()
382
368
  const userData = await report.getUserData()
@@ -396,15 +382,15 @@ describe('Test_Reports', function () {
396
382
  const report = await getReports()
397
383
  const userData = await report.getUserData()
398
384
  userData.withOdooServices = true
399
- userData.devices = userData.devices.filter(d => d.id === 25508)
385
+ userData.devices = userData.devices.filter(d => d.id === 22326)
400
386
  const data = await report.fuelConsumptionReport(
401
- new Date(Date.UTC(2022, 1, 1, 0, 0, 0, 0)),
402
- new Date(Date.UTC(2022, 1, 28, 23, 59, 59, 0)),
387
+ new Date(Date.UTC(2022, 9, 1, 0, 0, 0, 0)),
388
+ new Date(Date.UTC(2022, 9, 31, 23, 59, 59, 0)),
403
389
  userData)
404
390
 
405
391
  assert.equal(data.length, 1)
406
- const device = data[0].devices.find(d => d.device.id === 25508)
407
- assert.equal(device.days.length, 25)
392
+ const device = data[0].devices.find(d => d.device.id === 22326)
393
+ assert.equal(device.days.length, 23)
408
394
  }, 30000)
409
395
  // eslint-disable-next-line no-undef
410
396
  it('Zone Report', async () => {
@@ -3,6 +3,8 @@ const automaticReports = require('./automaticReports')
3
3
  const { devicesToProcess } = require('./util/device')
4
4
  const distance = require('@turf/distance')
5
5
  const { getTranslations } = require('./util/utils')
6
+ const odoo = require('./util/odoo')
7
+ const traccarHelper = require('./util/traccar')
6
8
 
7
9
  const positionsToCheck = 15
8
10
 
@@ -22,13 +24,16 @@ async function createRefuelingReport (from, to, userData, traccar) {
22
24
  console.log('Devices:' + devices.length)
23
25
 
24
26
  const arrayOfArrays = automaticReports.sliceArray(devices)
25
- let data = []
27
+ const data = []
26
28
  for (const a of arrayOfArrays) {
27
- const response = await traccar.reports.reportsRouteGet(from, to, a.map(d => d.id))
28
- data = data.concat(response.data)
29
+ const allInOne = await traccarHelper.getAllInOne(traccar, from, to, a, true, false, false, false)
30
+ data.push(...allInOne.route)
29
31
  }
30
32
 
31
- console.log('Locations:' + data.length)
33
+ const fuelServicesData = []
34
+ if (userData.withOdooServices) {
35
+ fuelServicesData.push(...(await odoo.getOdooFuelServices(traccar, from, to)))
36
+ }
32
37
 
33
38
  if (data.length === 0) {
34
39
  return reportData
@@ -40,19 +45,22 @@ async function createRefuelingReport (from, to, userData, traccar) {
40
45
 
41
46
  for (const d of devices) {
42
47
  const positions = data.filter(t => t.deviceId === d.id)
48
+ const deviceFuelServices = fuelServicesData.filter(f => Number.parseInt(d.attributes.odooId) === f.vehicle_id[0])
43
49
 
44
50
  if (positions.length > 0) {
45
- const refuelingPositions = await this.calculateRefuelingPositions(userData, d, { route: positions })
51
+ const refuelingPositions = await this.calculateRefuelingPositions(userData, d, { route: positions, fuelServices: deviceFuelServices })
46
52
 
47
53
  if (userData.drivers.length > 0) {
48
- refuelingPositions.forEach(p => {
49
- const geofence = findNearestPOI(p.position, userData.geofences)
50
- if (geofence) {
51
- p.position.geofenceName = geofence.name
52
- }
53
- const driver = userData.drivers.find(d => d.uniqueId === p.position.attributes.driverUniqueId)
54
- if (driver) {
55
- p.position.driverName = driver.name
54
+ refuelingPositions.forEach(r => {
55
+ if (r.position) {
56
+ const geofence = findNearestPOI(r.position, userData.geofences)
57
+ if (geofence) {
58
+ r.position.geofenceName = geofence.name
59
+ }
60
+ const driver = userData.drivers.find(d => d.uniqueId === r.position.attributes.driverUniqueId)
61
+ if (driver) {
62
+ r.position.driverName = driver.name
63
+ }
56
64
  }
57
65
  })
58
66
  }
@@ -121,7 +129,7 @@ async function calculateRefuelingPositions (userData, d, data) {
121
129
 
122
130
  const routeBeforeService = data.route.filter(r => new Date(r.fixTime).getTime() < serviceDate.getTime())
123
131
 
124
- const quantity = s.notes.split(':')[1].replace(',', '.') || 0
132
+ const quantity = s.liter
125
133
 
126
134
  if (routeBeforeService.length) {
127
135
  refuelingPositions.push({ date: s.date, diff: Number.parseFloat(quantity), cost: s.amount })
@@ -343,7 +343,7 @@ async function getHereEvents (devices, routes, threshold) {
343
343
  events.push(...reduced)
344
344
  resolve()
345
345
  }).catch(e => {
346
- console.warn('error on route match, moving on', e.message)
346
+ console.warn('route match, moving on', e.message)
347
347
  resolve()
348
348
  })
349
349
  }))
package/src/util/odoo.js CHANGED
@@ -1,14 +1,13 @@
1
1
 
2
- async function getOdooFuelServices(traccar, from, to) {
3
- const url = `/odoo/reports/refuelingServices?startDate=${from.toDateString()}&endDate=${to.toDateString()}`
2
+ async function getOdooFuelServices (traccar, from, to) {
3
+ const url = `/odoo/reports/refuelingServices?startDate=${from.toDateString()}&endDate=${to.toDateString()}`
4
4
 
5
- const {data} = await traccar.axios.get(url,{
6
- jar: traccar.cookieJar,
7
- withCredentials: true })
5
+ const { data } = await traccar.axios.get(url, {
6
+ jar: traccar.cookieJar,
7
+ withCredentials: true
8
+ })
8
9
 
9
- console.log(data)
10
-
11
- return data
10
+ return data
12
11
  }
13
12
 
14
13
  exports.getOdooFuelServices = getOdooFuelServices