fleetmap-reports 2.0.358 → 2.0.359
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 +1 -1
- package/src/partnerReports/driverranking-report.js +39 -7
- package/.claude/worktrees/eager-stonebraker-c08ac7/.eslintrc.js +0 -15
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/enGB.js +0 -309
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/esCL.js +0 -297
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/frFR.json +0 -324
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/index.js +0 -35
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptBR.js +0 -301
- package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptPT.js +0 -310
- package/.claude/worktrees/eager-stonebraker-c08ac7/package-lock.json +0 -11944
- package/.claude/worktrees/eager-stonebraker-c08ac7/package.json +0 -45
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/activity-report.js +0 -822
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/automaticReports.js +0 -34
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/carbone/index.js +0 -13
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/custom/vistawasteActivity-report.js +0 -544
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/events-report.js +0 -360
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-consumption-report.js +0 -296
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-drop-report.js +0 -128
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/here.js +0 -172
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/idle-report.js +0 -403
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/index.js +0 -244
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/kms-report.js +0 -549
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/location-report.js +0 -496
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/machines-report.js +0 -278
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/afriquia.js +0 -129
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/dailyuse-report.js +0 -80
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/delayedstart-report.js +0 -223
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/driverranking-report.js +0 -328
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/gpsjump-report.js +0 -61
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/performance-report.js +0 -359
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/refueling-report.js +0 -345
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/reportStyle.js +0 -34
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/sensor-report.js +0 -447
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/speeding-report.js +0 -663
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/stop-report.js +0 -242
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ActivityReportTemplate.mjml +0 -51
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EmptyReportTemplate.mjml +0 -25
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EventsReportTemplate.mjml +0 -75
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/FuelDropReportTemplate.mjml +0 -60
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/IdleReportTemplate.mjml +0 -54
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportGroupByDayTemplate.mjml +0 -43
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportTemplate.mjml +0 -44
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/LocationReportTemplate.mjml +0 -37
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/RefuelingReportTemplate.mjml +0 -60
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SensorReportTemplate.mjml +0 -23
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SpeedingReportTemplate.mjml +0 -80
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/TripReportTemplate.mjml +0 -97
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ZoneReportTemplate.mjml +0 -52
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/report.mjml +0 -96
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/activity.test.js +0 -99
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/carbone.test.js +0 -20
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/events.test.js +0 -30
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/fuel.test.js +0 -35
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/idle.test.js +0 -16
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.js +0 -24
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.test.js +0 -203
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/kms.test.js +0 -74
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/performance.test.js +0 -36
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/positions.test.js +0 -67
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/speeding.test.js +0 -120
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/translations.test.js +0 -21
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/trips.test.js +0 -140
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/zones.test.js +0 -162
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/trip-report.js +0 -641
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/device.js +0 -13
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/driver.js +0 -90
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/fuel.js +0 -102
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/geofence.js +0 -52
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/odoo.js +0 -18
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/parallel.js +0 -64
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/pdfDocument.js +0 -140
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/route.js +0 -78
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/timetable.js +0 -30
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.js +0 -213
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.worker.js +0 -49
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/trips.js +0 -270
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/utils.js +0 -358
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/worker.js +0 -14
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/xpert.js +0 -58
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/word/index.js +0 -95
- package/.claude/worktrees/eager-stonebraker-c08ac7/src/zone-report.js +0 -904
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
const traccar = require('./traccar')
|
|
2
|
-
const automaticReports = require('../automaticReports')
|
|
3
|
-
const traccarHelper = require('./traccar')
|
|
4
|
-
const { isInsideTimetable, isPartialInsideTimetable } = require('./trips')
|
|
5
|
-
|
|
6
|
-
// get devices used by each driver between two dates
|
|
7
|
-
async function devicesByDriver (traccarInstance, from, to, drivers, devices) {
|
|
8
|
-
const eventsData = await traccar.getEvents(traccarInstance, from, to, devices, ['driverChanged'])
|
|
9
|
-
const driverUniqueIdsToProcess = new Set(eventsData.map(e => e.attributes.driverUniqueId))
|
|
10
|
-
const driversToProcess = drivers.filter(d => driverUniqueIdsToProcess.has(d.uniqueId))
|
|
11
|
-
|
|
12
|
-
const deviceIdsToProcess = new Set(eventsData.map(e => e.deviceId))
|
|
13
|
-
const devicesToProcess = devices.filter(d => deviceIdsToProcess.has(d.id))
|
|
14
|
-
|
|
15
|
-
return { devices: devicesToProcess, drivers: driversToProcess }
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async function reportByDriver (devices, traccar, from, to, userData, processor, allInOneData = { route: true, trips: true, stops: true, summary: false }) {
|
|
19
|
-
const report = { drivers: [] }
|
|
20
|
-
|
|
21
|
-
const sliced = automaticReports.sliceArray(devices, 5)
|
|
22
|
-
|
|
23
|
-
let deviceCount = 0
|
|
24
|
-
for (const slice of sliced) {
|
|
25
|
-
const allInOne = await traccarHelper.getAllInOne(traccar, from, to, slice, allInOneData.route, allInOneData.trips, allInOneData.stops, allInOneData.summary, deviceCount, devices.length)
|
|
26
|
-
const results = await processor(from, to, userData, { trips: allInOne.trips, route: allInOne.route, stops: allInOne.stops })
|
|
27
|
-
report.drivers.push(...results)
|
|
28
|
-
deviceCount = deviceCount + slice.length
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return report
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getDriverUniqueIdTimeline (driverUniqueIdTimeline, driverUniqueId, date) {
|
|
35
|
-
if (!driverUniqueIdTimeline) {
|
|
36
|
-
return undefined
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return driverUniqueIdTimeline.find(d => d.uniqueId === driverUniqueId &&
|
|
40
|
-
(!d.startDate || new Date(d.startDate) <= new Date(date)) &&
|
|
41
|
-
(!d.endDate || new Date(d.endDate) >= new Date(date)))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getDriverName (driverUniqueId, date, userData) {
|
|
45
|
-
if (driverUniqueId) {
|
|
46
|
-
const timeline = getDriverUniqueIdTimeline(userData.driverUniqueIdTimeline, driverUniqueId, date)
|
|
47
|
-
|
|
48
|
-
if (timeline) {
|
|
49
|
-
return timeline.driverName
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const driver = userData.drivers ? userData.drivers.find(d => !d.uniqueId.localeCompare(driverUniqueId, undefined, { sensitivity: 'base' })) : undefined
|
|
53
|
-
|
|
54
|
-
return driver
|
|
55
|
-
? driver.name + ' ' + ((driver.attributes && driver.attributes.notes) || '')
|
|
56
|
-
: driverUniqueId
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return ''
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function getDriverData (d, data, userData) {
|
|
63
|
-
const route = data.route ? data.route.filter(p => !d.uniqueId.localeCompare(p.attributes.driverUniqueId, undefined, { sensitivity: 'base' })) : undefined
|
|
64
|
-
const trips = data.trips ? data.trips.filter(t => !d.uniqueId.localeCompare(t.driverUniqueId, undefined, { sensitivity: 'base' })) : undefined
|
|
65
|
-
const events = data.events ? data.events.filter(e => e.position && !d.uniqueId.localeCompare(e.position.attributes.driverUniqueId, undefined, { sensitivity: 'base' })) : undefined
|
|
66
|
-
|
|
67
|
-
const filteredTrips = []
|
|
68
|
-
if (trips) {
|
|
69
|
-
for (const t of trips) {
|
|
70
|
-
if (userData.allWeek ||
|
|
71
|
-
!userData.weekDays ||
|
|
72
|
-
isInsideTimetable(t, userData) ||
|
|
73
|
-
await isPartialInsideTimetable(undefined, t, userData, route)) {
|
|
74
|
-
filteredTrips.push(t)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
route,
|
|
81
|
-
trips: filteredTrips,
|
|
82
|
-
events
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
exports.getDriverData = getDriverData
|
|
87
|
-
exports.getDriverName = getDriverName
|
|
88
|
-
exports.getDriverUniqueIdTimeline = getDriverUniqueIdTimeline
|
|
89
|
-
exports.devicesByDriver = devicesByDriver
|
|
90
|
-
exports.reportByDriver = reportByDriver
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
function calculateFuelDiff (a, b) {
|
|
2
|
-
return b - a
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
function getRefuelingLiters (d, position, diff) {
|
|
6
|
-
if (position.protocol === 'teltonika' && !position.attributes.io89) {
|
|
7
|
-
return diff
|
|
8
|
-
}
|
|
9
|
-
return Math.round(diff * d.attributes.fuel_tank_capacity / 100)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function calculateTotalFuelFromSensor(trips, stops, positions, device, firstStopIndex) {
|
|
13
|
-
const lastStopIndex = firstStopIndex + trips.length - 1
|
|
14
|
-
const lastStop = stops.length > lastStopIndex ? stops[lastStopIndex] : null
|
|
15
|
-
const firstTripStart = new Date(trips[0].startTime).getTime()
|
|
16
|
-
const lastEndTime = lastStop ? new Date(lastStop.endTime).getTime() : new Date(trips[trips.length - 1].endTime).getTime()
|
|
17
|
-
|
|
18
|
-
const rangePositions = positions.filter(p => {
|
|
19
|
-
const t = new Date(p.fixTime).getTime()
|
|
20
|
-
return t >= firstTripStart && t <= lastEndTime && p.attributes.fuel != null
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
if (rangePositions.length < 2) return 0
|
|
24
|
-
|
|
25
|
-
const invertedSensor = device.attributes.fuel_low_threshold > device.attributes.fuel_high_threshold
|
|
26
|
-
const sensorRange = Math.abs(device.attributes.fuel_high_threshold - device.attributes.fuel_low_threshold)
|
|
27
|
-
const refuelThreshold = sensorRange * 0.2
|
|
28
|
-
|
|
29
|
-
let totalRawConsumption = 0
|
|
30
|
-
let segmentStartFuel = rangePositions[0].attributes.fuel
|
|
31
|
-
|
|
32
|
-
for (let i = 1; i < rangePositions.length; i++) {
|
|
33
|
-
const prev = rangePositions[i - 1]
|
|
34
|
-
const curr = rangePositions[i]
|
|
35
|
-
// refuel = significant increase for normal sensor, significant decrease for inverted
|
|
36
|
-
const fuelChange = invertedSensor
|
|
37
|
-
? prev.attributes.fuel - curr.attributes.fuel
|
|
38
|
-
: curr.attributes.fuel - prev.attributes.fuel
|
|
39
|
-
|
|
40
|
-
if (fuelChange > refuelThreshold) {
|
|
41
|
-
const segmentRawDiff = invertedSensor
|
|
42
|
-
? prev.attributes.fuel - segmentStartFuel
|
|
43
|
-
: segmentStartFuel - prev.attributes.fuel
|
|
44
|
-
if (segmentRawDiff > 0) totalRawConsumption += segmentRawDiff
|
|
45
|
-
segmentStartFuel = curr.attributes.fuel
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const lastFuel = rangePositions[rangePositions.length - 1].attributes.fuel
|
|
50
|
-
const lastSegmentRawDiff = invertedSensor
|
|
51
|
-
? lastFuel - segmentStartFuel
|
|
52
|
-
: segmentStartFuel - lastFuel
|
|
53
|
-
if (lastSegmentRawDiff > 0) totalRawConsumption += lastSegmentRawDiff
|
|
54
|
-
|
|
55
|
-
if (totalRawConsumption <= 0) return 0
|
|
56
|
-
return (totalRawConsumption / sensorRange) * device.attributes.fuel_tank_capacity
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
function calculateConsumption (d, data) {
|
|
61
|
-
let fuelConsumption = 0
|
|
62
|
-
const withFuelUsed = data.route && data.route.find(p => p.attributes.fuelUsed)
|
|
63
|
-
if (data.summary && withFuelUsed) {
|
|
64
|
-
fuelConsumption = calculateSpentFuel(data.summary.spentFuel, d, withFuelUsed)
|
|
65
|
-
} else if (data.trips && data.stops) {
|
|
66
|
-
fuelConsumption = data.trips.reduce((a, b) => a + calculateSpentFuel(b.spentFuel, d, withFuelUsed), 0) + data.stops.reduce((a, b) => a + calculateSpentFuel(b.spentFuel, d, withFuelUsed), 0)
|
|
67
|
-
} else if (data.route && data.route.length > 1 && data.route[0].attributes.fuelUsed) {
|
|
68
|
-
fuelConsumption = data.route[data.route.length - 1].attributes.fuelUsed - data.route[0].attributes.fuelUsed
|
|
69
|
-
} else if (data.summary) {
|
|
70
|
-
fuelConsumption = data.summary.spentFuel
|
|
71
|
-
}
|
|
72
|
-
return fuelConsumption > 0 ? fuelConsumption : 0
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function calculateSpentFuel (value, device, withFuelUsed) {
|
|
76
|
-
if (!value) { return value }
|
|
77
|
-
|
|
78
|
-
if (device.attributes.xpert) {
|
|
79
|
-
return withFuelUsed ? value : (value * device.attributes.fuel_tank_capacity) / 100
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const { fuel_low_threshold, fuel_high_threshold, fuel_tank_capacity } = device.attributes
|
|
83
|
-
if (fuel_low_threshold != null && fuel_high_threshold != null && fuel_tank_capacity) {
|
|
84
|
-
const sensorRange = Math.abs(fuel_high_threshold - fuel_low_threshold)
|
|
85
|
-
const rawFuel = fuel_low_threshold > fuel_high_threshold
|
|
86
|
-
? (value < 0 ? Math.abs(value) : 0)
|
|
87
|
-
: value
|
|
88
|
-
return rawFuel > 0 ? (rawFuel / sensorRange) * fuel_tank_capacity : 0
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return value > 0 ? value : 0
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function useOdooFuelData (d, route) {
|
|
95
|
-
return route && route.length && !route[0].attributes.fuel && d.attributes.odooId
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
exports.calculateFuelDiff = calculateFuelDiff
|
|
99
|
-
exports.getRefuelingLiters = getRefuelingLiters
|
|
100
|
-
exports.calculateConsumption = calculateConsumption
|
|
101
|
-
exports.useOdooFuelData = useOdooFuelData
|
|
102
|
-
exports.calculateTotalFuelFromSensor = calculateTotalFuelFromSensor
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const turf = require('@turf/helpers')
|
|
2
|
-
const inside = require('@turf/boolean-point-in-polygon')
|
|
3
|
-
const { coordsDistance } = require('./utils')
|
|
4
|
-
const booleanPointInPolygon = require('@turf/boolean-point-in-polygon')
|
|
5
|
-
const distance = require('@turf/distance')
|
|
6
|
-
const pointToLineDistance = require('@turf/point-to-line-distance')
|
|
7
|
-
|
|
8
|
-
exports.insideGeofence = function insideGeofence (position, geofence) {
|
|
9
|
-
const coords = geofence.area.slice(9, geofence.area.length - 2).split(',')
|
|
10
|
-
const coords2 = coords.map(c => {
|
|
11
|
-
return c.trim().split(' ').map(a => parseFloat(a))
|
|
12
|
-
})
|
|
13
|
-
const pt = turf.point([parseFloat(position.latitude), parseFloat(position.longitude)])
|
|
14
|
-
const poly = turf.polygon([coords2])
|
|
15
|
-
|
|
16
|
-
return inside.default(pt, poly)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
exports.getNearestPOI = (position, geofences) => getNearestPOIs(position.longitude, position.latitude, geofences)[0]
|
|
20
|
-
function getNearestPOIs (long, lat, geofences) {
|
|
21
|
-
const distance = geofences
|
|
22
|
-
.filter(g => g && g.area && g.area.startsWith('CIRCLE'))
|
|
23
|
-
.map(g => {
|
|
24
|
-
const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
|
|
25
|
-
const radius = g.area.substring(g.area.indexOf(',') + 1, g.area.indexOf(')'))
|
|
26
|
-
const coord = str.trim().split(' ')
|
|
27
|
-
return {
|
|
28
|
-
p: g,
|
|
29
|
-
distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), long, lat)),
|
|
30
|
-
r: parseFloat(radius)
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
return distance.filter(a => a.distance < a.r).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
|
|
34
|
-
}
|
|
35
|
-
exports.getNearestPOIs = getNearestPOIs
|
|
36
|
-
|
|
37
|
-
exports.loadGroupsData = async function loadGroupsData (userData, traccarInstance) {
|
|
38
|
-
for (const g of userData.groups) {
|
|
39
|
-
g.geofenceIds = (await traccarInstance.geofences.geofencesGet(undefined, undefined, undefined, g.id, undefined, undefined).then(r => r.data)).map(g => g.id)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.checkGeofenceIn = function checkGeofenceIn (p, g) {
|
|
44
|
-
switch (g.geometry.type) {
|
|
45
|
-
case 'Polygon':
|
|
46
|
-
return booleanPointInPolygon.default(p, g)
|
|
47
|
-
case 'Point':
|
|
48
|
-
return distance.default(p, g, { units: 'meters' }) <= g.properties.distance
|
|
49
|
-
case 'LineString':
|
|
50
|
-
return pointToLineDistance.default(p, g, { units: 'meters' }) < (g.properties.geofence.attributes.polylineDistance || 25)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
async function getOdooFuelServices (traccar, from, to) {
|
|
3
|
-
const url = `/odoo/reports/refuelingServices?startDate=${from.toDateString()}&endDate=${to.toDateString()}`
|
|
4
|
-
|
|
5
|
-
try {
|
|
6
|
-
const { data } = await traccar.axios.get(url, {
|
|
7
|
-
jar: traccar.cookieJar,
|
|
8
|
-
withCredentials: true
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
return data
|
|
12
|
-
} catch (e) {
|
|
13
|
-
console.log(e)
|
|
14
|
-
return []
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
exports.getOdooFuelServices = getOdooFuelServices
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
const { sliceArray } = require('../automaticReports')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
|
|
4
|
-
exports.parallel = (report, method, toSlice, ...args) => {
|
|
5
|
-
const cluster = require('cluster')
|
|
6
|
-
const numCPUs = require('os').cpus().length
|
|
7
|
-
return new Promise((resolve, reject) => {
|
|
8
|
-
if (cluster.isPrimary) {
|
|
9
|
-
console.log('parallel with', numCPUs, 'cpus', 'toSlice len', toSlice.length)
|
|
10
|
-
cluster.setupPrimary({ exec: path.resolve(__dirname, 'worker.js') })
|
|
11
|
-
const sliced = toSlice.length > (numCPUs - 1) ? sliceArray(toSlice, toSlice.length / (numCPUs - 1)) : [toSlice]
|
|
12
|
-
console.log('sliced in', sliced.length)
|
|
13
|
-
const _result = []
|
|
14
|
-
let done = 0
|
|
15
|
-
let workerCount = 0
|
|
16
|
-
if (!sliced.length) {
|
|
17
|
-
console.error(report, method, 'got sliced length', sliced.length, toSlice)
|
|
18
|
-
reject(new Error('0 to process'))
|
|
19
|
-
}
|
|
20
|
-
sliced.forEach((slice) => {
|
|
21
|
-
if (!slice.length) {
|
|
22
|
-
console.error(report, method, 'got empty slice', slice)
|
|
23
|
-
reject(new Error('got empty slice'))
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
console.log('forking worker', workerCount++, report, method, slice.length)
|
|
27
|
-
const worker = cluster.fork()
|
|
28
|
-
worker.on('message', ({ result }) => {
|
|
29
|
-
console.log('received result from worker', worker.process.pid)
|
|
30
|
-
_result.push(result)
|
|
31
|
-
if (++done === sliced.length) {
|
|
32
|
-
resolve(_result.flat())
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
worker.on('error', (e) => {
|
|
36
|
-
console.error(e)
|
|
37
|
-
reject(new Error(`Worker ${worker.process.pid} error ${e.message}`))
|
|
38
|
-
reject(e)
|
|
39
|
-
})
|
|
40
|
-
worker.on('exit', (code, signal) => {
|
|
41
|
-
if (code !== 0) {
|
|
42
|
-
reject(new Error(`Worker ${worker.process.pid} exited with code ${code} and signal ${signal}`))
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
worker.send({
|
|
46
|
-
report,
|
|
47
|
-
method,
|
|
48
|
-
args: [slice, ...args]
|
|
49
|
-
})
|
|
50
|
-
console.log('sent to worker', worker.process.pid)
|
|
51
|
-
} catch (e) {
|
|
52
|
-
console.error(report, method, 'worker', workerCount, 'numCPUs', numCPUs)
|
|
53
|
-
reject(e)
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
cluster.on('exit', (worker, code, signal) => {
|
|
57
|
-
console.log('worker died', worker.process.pid, code, signal)
|
|
58
|
-
if (signal === 'SIGKILL') {
|
|
59
|
-
reject(new Error(`Worker died ${worker.process.pid}, code ${code} signal ${signal}`))
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
}
|