fleetmap-reports 1.0.778 → 1.0.780

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.778",
3
+ "version": "1.0.780",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -13,6 +13,7 @@ const { isInsideTimetable, isPartialInsideTimetable, calculateTrip } = require('
13
13
  const tripHelper = require('./util/trips')
14
14
  const { devicesToProcess } = require('./util/device')
15
15
  const { getDriverData } = require('./util/driver')
16
+ const { calculateConsumption } = require('./util/fuel')
16
17
 
17
18
  const fileName = 'ActivityReport'
18
19
 
@@ -204,7 +205,7 @@ function processDevices (from, to, devices, data, userData) {
204
205
  if (summaryCurrentDay) {
205
206
  summaryCurrentDay.engineHours = tripsByDay.reduce((a, b) => a + b.duration, 0)
206
207
  summaryCurrentDay.distance = distance
207
- summaryCurrentDay.convertedSpentFuel = automaticReports.calculateSpentFuel(summaryCurrentDay.spentFuel, d)
208
+ summaryCurrentDay.convertedSpentFuel = calculateConsumption(d, { route: deviceRoute, summary: summaryCurrentDay })
208
209
  summaryCurrentDay.startTime = tripsByDay.length && tripsByDay[0].startTime
209
210
  summaryCurrentDay.startAddress = tripsByDay.length && tripsByDay[0].startAddress
210
211
  summaryCurrentDay.endTime = tripsByDay.length && tripsByDay[tripsByDay.length - 1].endTime
@@ -240,7 +241,7 @@ function processDevices (from, to, devices, data, userData) {
240
241
  summary.forEach(s => {
241
242
  s.engineHours = deviceTrips.reduce((a, b) => a + b.duration, 0)
242
243
  s.distance = deviceTrips.reduce((a, b) => a + b.distance, 0)
243
- s.convertedSpentFuel = automaticReports.calculateSpentFuel(s.spentFuel, d)
244
+ s.convertedSpentFuel = calculateConsumption(d, { route: deviceRoute, summary: s })
244
245
  s.startTime = deviceTrips.length && deviceTrips[0].startTime
245
246
  s.startAddress = deviceTrips.length && deviceTrips[0].startAddress
246
247
  s.endTime = deviceTrips.length && deviceTrips[deviceTrips.length - 1].endTime
@@ -21,10 +21,6 @@ function deviceWithFuelInfo (device) {
21
21
  (device.attributes.fuel_low_threshold >= 0 && device.attributes.fuel_high_threshold >= 0 && device.attributes.fuel_tank_capacity)
22
22
  }
23
23
 
24
- function fuelSignalInverter (device) {
25
- return device.attributes.fuel_low_threshold <= device.attributes.fuel_high_threshold ? 1 : -1
26
- }
27
-
28
24
  function calculateXpertDistance (date, positions) {
29
25
  const begin = moment(date, 'YYYY-MM-DD').startOf('day')
30
26
  const end = moment(date, 'YYYY-MM-DD').endOf('day')
@@ -33,19 +29,7 @@ function calculateXpertDistance (date, positions) {
33
29
  return datePositions.reduce((a, b) => a + b.attributes.distance, 0)
34
30
  }
35
31
 
36
- function calculateSpentFuel (value, device) {
37
- if (!value || device.attributes.xpert) { return value }
38
-
39
- if (device.attributes.fuel_low_threshold && device.attributes.fuel_high_threshold) {
40
- const valueSignalCheck = value * fuelSignalInverter(device)
41
- const valuePercentage = (valueSignalCheck * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
42
- return Math.round((valuePercentage * device.attributes.fuel_tank_capacity) / 100)
43
- }
44
- return value
45
- }
46
-
47
32
  exports.sliceArray = sliceArray
48
33
  exports.deviceWithFuelInfo = deviceWithFuelInfo
49
- exports.calculateSpentFuel = calculateSpentFuel
50
34
  exports.calculateXpertDistance = calculateXpertDistance
51
35
  exports.maxParallelRequests = maxParallelRequests
@@ -1,4 +1,3 @@
1
- const automaticReports = require('./automaticReports')
2
1
  const refuelingReport = require('./refueling-report')
3
2
  const traccarHelper = require('./util/traccar')
4
3
  const odoo = require('./util/odoo')
@@ -8,6 +7,7 @@ const { getStyle } = require('./reportStyle')
8
7
  const { getUserPartner } = require('fleetmap-partners')
9
8
  const { addTable, headerFromUser } = require('./util/pdfDocument')
10
9
  const jsPDF = require('jspdf')
10
+ const { useOdooFuelData, calculateConsumption } = require('./util/fuel')
11
11
 
12
12
  async function createFuelConsumptionReport (from, to, userData, traccar) {
13
13
  console.log('Create FuelConsumption Report')
@@ -22,24 +22,23 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
22
22
 
23
23
  const devices = devicesToProcess(userData)
24
24
 
25
- const allInOne = await traccarHelper.getAllInOne(traccar, from, to, devices, true, true, false, false)
26
- const tripsData = allInOne.trips
27
- const routeData = allInOne.route
25
+ const allInOne = await traccarHelper.getAllInOne(traccar, from, to, devices, true, true, true, false)
28
26
 
29
27
  const fuelServicesData = []
30
28
  if (devices.some(d => d.attributes.odooId)) {
31
29
  fuelServicesData.push(...(await odoo.getOdooFuelServices(traccar, from, to)))
32
30
  }
33
31
 
34
- if (tripsData.length === 0) {
32
+ if (allInOne.trips.length === 0) {
35
33
  return reportData
36
34
  }
37
35
 
38
36
  allData.totalDevices = 0
39
37
 
40
38
  for (const d of devices) {
41
- const trips = tripsData.filter(t => t.deviceId === d.id)
42
- const route = routeData.filter(r => r.deviceId === d.id)
39
+ const trips = allInOne.trips.filter(t => t.deviceId === d.id)
40
+ const route = allInOne.route.filter(r => r.deviceId === d.id)
41
+ const stops = allInOne.stops.filter(s => s.deviceId === d.id)
43
42
  const deviceFuelServices = fuelServicesData.filter(f => Number.parseInt(d.attributes.odooId) === f.vehicle_id[0])
44
43
 
45
44
  if (trips.length > 0) {
@@ -55,6 +54,12 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
55
54
  new Map()
56
55
  )
57
56
 
57
+ stops.forEach(s => { s.startDate = s.startTime.substring(0, 10) })
58
+ const groupedStopsByDay = stops.reduce(
59
+ (entryMap, e) => entryMap.set(e.startDate, [...entryMap.get(e.startDate) || [], e]),
60
+ new Map()
61
+ )
62
+
58
63
  route.forEach(p => { p.startDate = p.fixTime.substring(0, 10) })
59
64
  const groupedRouteByDay = route.reduce(
60
65
  (entryMap, e) => entryMap.set(e.startDate, [...entryMap.get(e.startDate) || [], e]),
@@ -69,7 +74,7 @@ async function createFuelConsumptionReport (from, to, userData, traccar) {
69
74
  const dayTrips = groupedTripsByDay.get(day)
70
75
  const dayRefueling = groupedRefuelingsByDay.get(day)
71
76
  const distance = dayTrips.reduce((a, b) => a + b.distance, 0)
72
- const spentFuel = calculateConsumption(userData, d, day, odooAvgConsumption, { trips: dayTrips, route: groupedRouteByDay.get(day) })
77
+ const spentFuel = calculateConsumption(d, { trips: dayTrips, stops: groupedStopsByDay.get(day), route: groupedRouteByDay.get(day) }, odooAvgConsumption)
73
78
 
74
79
  const dataRow = {
75
80
  date: day,
@@ -126,18 +131,6 @@ function calculateAvgConsumption (fuel, distance) {
126
131
  return { byKms: fuel * 100 / (distance / 1000), byLiters: (distance / 1000) / fuel }
127
132
  }
128
133
 
129
- function calculateConsumption (userData, d, day, avgConsumption, data) {
130
- if (useOdooFuelData(d, data.route)) {
131
- return (avgConsumption.byKms * (data.trips.reduce((a, b) => a + b.distance, 0) / 1000) / 100)
132
- }
133
-
134
- if (data.route.length > 1 && data.route[0].attributes.fuelUsed) {
135
- return data.route[data.route.length - 1].attributes.fuelUsed - data.route[0].attributes.fuelUsed
136
- }
137
-
138
- return automaticReports.calculateSpentFuel(data.trips.reduce((a, b) => a + b.spentFuel, 0), d)
139
- }
140
-
141
134
  function exportFuelConsumptionReportToExcel (userData, reportData) {
142
135
  const translations = getTranslations(userData)
143
136
  const lang = getLanguage(userData)
@@ -268,10 +261,6 @@ function deviceName (device) {
268
261
  return device.name + (device.attributes.license_plate ? ', ' + device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
269
262
  }
270
263
 
271
- function useOdooFuelData (d, route) {
272
- return route.length && !route[0].attributes.fuel && d.attributes.odooId
273
- }
274
-
275
264
  function getTotalKms (user, data) {
276
265
  const totalKms = data.reduce((a, b) => a + b.distance, 0)
277
266
  return formatNumber(totalKms / 1000, user.attributes.lang)
@@ -136,12 +136,12 @@ function getDeviceData (allInOne, d) {
136
136
 
137
137
  const highEngineRPMSections = calculateRPMSections(deviceRoute, d.attributes.highRPM || 1300)
138
138
  const highEngineRPM = highEngineRPMSections.map(a => a.length > 1
139
- ? a.map((p, index) => index === 0 ? 0 : new Date(p.fixTime).getTime() - new Date(a[index - 1].fixTime).getTime()).reduce((a, b) => a + b)
139
+ ? a.map((p, index) => index === 0 ? 0 : new Date(p.fixTime).getTime() - new Date(a[index - 1].fixTime).getTime()).reduce((a, b) => a + b, 0)
140
140
  : 0).reduce((a, b) => a + b, 0)
141
141
 
142
142
  const economicRPMSections = calculateRPMSections(deviceRoute, d.attributes.minEconomicRPM || 1000, d.attributes.maxEconomicRPM || 1250)
143
143
  const economicTime = economicRPMSections.map(a => a.length > 1
144
- ? a.map((p, index) => index === 0 ? 0 : new Date(p.fixTime).getTime() - new Date(a[index - 1].fixTime).getTime()).reduce((a, b) => a + b)
144
+ ? a.map((p, index) => index === 0 ? 0 : new Date(p.fixTime).getTime() - new Date(a[index - 1].fixTime).getTime()).reduce((a, b) => a + b, 0)
145
145
  : 0).reduce((a, b) => a + b, 0)
146
146
  const economicDistance = economicRPMSections.map(a => a.length > 1
147
147
  ? calculateDistance(a)
@@ -58,4 +58,18 @@ describe('activity report', function () {
58
58
  console.log(device)
59
59
  assert.equal(device.summary[0].convertedSpentFuel, 168.6)
60
60
  }, 800000)
61
+ // eslint-disable-next-line no-undef
62
+ it('Activity check fuel consumption group by day', async () => {
63
+ const report = await getReports()
64
+ const userData = await report.getUserData()
65
+ userData.groupByDay = true
66
+ userData.devices = userData.devices.filter(d => d.id === 69114)
67
+ const data = await report.activityReport(new Date(2023, 5, 11, 0, 0, 0, 0),
68
+ new Date(2023, 6, 11, 23, 59, 59, 0),
69
+ userData)
70
+ assert.equal(data.length, 1)
71
+ const device = data[0].devices.find(d => d.device.id === 69114)
72
+ console.log(device)
73
+ assert.equal(device.summary.reduce((a, b) => a + b.convertedSpentFuel, 0), 168.79999999999995)
74
+ }, 800000)
61
75
  })
@@ -19,6 +19,7 @@ const { getIdleEvents } = require('./util/route')
19
19
  const { reportByDriver, getDriverName, getDriverData } = require('./util/driver')
20
20
  const { getNearestPOIs } = require('./util/geofence')
21
21
  const { parallel } = require('./util/parallel')
22
+ const { calculateConsumption } = require('./util/fuel')
22
23
 
23
24
  const fileName = 'TripReport'
24
25
 
@@ -171,7 +172,7 @@ function processDevices (from, to, devices, data, userData, traccar) {
171
172
 
172
173
  if ((deviceRoute[0].protocol === 'teltonika' && deviceRoute.some(r => r.attributes.fuel)) ||
173
174
  automaticReports.deviceWithFuelInfo(d)) {
174
- trip.fuelConsumption = trip.spentFuel + (stop ? stop.spentFuel : 0)
175
+ trip.fuelConsumption = calculateConsumption(d, { trips: [trip], stops: (stop ? [stop] : []), route: deviceRoute })
175
176
  trip.avgFuelConsumption = trip.totalKms > 0 ? trip.fuelConsumption * 100 / trip.totalKms : 0
176
177
  }
177
178
 
package/src/util/fuel.js CHANGED
@@ -22,5 +22,45 @@ function getRefuelingLiters (d, position, diff) {
22
22
  return Math.round(diff * d.attributes.fuel_tank_capacity / 100)
23
23
  }
24
24
 
25
+ function calculateConsumption (d, data, avgConsumption) {
26
+ let fuelConsumption = 0
27
+ if (useOdooFuelData(d, data.route)) {
28
+ fuelConsumption = (avgConsumption.byKms * (data.trips.reduce((a, b) => a + b.distance, 0) / 1000) / 100)
29
+ } else {
30
+ const withFuelUsed = data.route && data.route.find(p => p.attributes.fuelUsed)
31
+ if (data.summary) {
32
+ fuelConsumption = calculateSpentFuel(data.summary.spentFuel, d, withFuelUsed)
33
+ } else if (data.trips && data.stops) {
34
+ const spentFuel = data.trips.reduce((a, b) => a + b.spentFuel, 0) + data.stops.reduce((a, b) => a + b.spentFuel, 0)
35
+ fuelConsumption = calculateSpentFuel(spentFuel, d, withFuelUsed)
36
+ } else if (data.route && data.route.length > 1 && data.route[0].attributes.fuelUsed) {
37
+ fuelConsumption = data.route[data.route.length - 1].attributes.fuelUsed - data.route[0].attributes.fuelUsed
38
+ }
39
+ }
40
+ return fuelConsumption > 0 ? fuelConsumption : 0
41
+ }
42
+
43
+ function calculateSpentFuel (value, device, withFuelUsed) {
44
+ if (!value) { return value }
45
+
46
+ if (device.attributes.xpert) {
47
+ return withFuelUsed ? value : (value * device.attributes.fuel_tank_capacity) / 100
48
+ }
49
+
50
+ if (device.attributes.fuel_low_threshold && device.attributes.fuel_high_threshold) {
51
+ const valueSignalCheck = value * fuelSignalInverter(device)
52
+ const valuePercentage = (valueSignalCheck * 100) / Math.abs(device.attributes.fuel_low_threshold - device.attributes.fuel_high_threshold)
53
+ return Math.round((valuePercentage * device.attributes.fuel_tank_capacity) / 100)
54
+ }
55
+
56
+ return value
57
+ }
58
+
59
+ function useOdooFuelData (d, route) {
60
+ return route && route.length && !route[0].attributes.fuel && d.attributes.odooId
61
+ }
62
+
25
63
  exports.calculateFuelDiff = calculateFuelDiff
26
64
  exports.getRefuelingLiters = getRefuelingLiters
65
+ exports.calculateConsumption = calculateConsumption
66
+ exports.useOdooFuelData = useOdooFuelData