fleetmap-reports 1.0.263 → 1.0.267

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,11 +1,11 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
3
  <component name="ChangeListManager">
4
- <list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="fix activity report by driver">
4
+ <list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="check if weekDays parameter is set">
5
5
  <change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
6
6
  <change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
7
- <change beforePath="$PROJECT_DIR$/src/activity-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/activity-report.js" afterDir="false" />
8
7
  <change beforePath="$PROJECT_DIR$/src/index.test.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.test.js" afterDir="false" />
8
+ <change beforePath="$PROJECT_DIR$/src/trip-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/trip-report.js" afterDir="false" />
9
9
  </list>
10
10
  <option name="SHOW_DIALOG" value="false" />
11
11
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -219,7 +219,13 @@
219
219
  <workItem from="1640866364417" duration="67000" />
220
220
  <workItem from="1640866782794" duration="123000" />
221
221
  <workItem from="1640866964393" duration="1022000" />
222
- <workItem from="1640870147277" duration="6811000" />
222
+ <workItem from="1640870147277" duration="8236000" />
223
+ <workItem from="1641321068227" duration="14805000" />
224
+ <workItem from="1641387675790" duration="32947000" />
225
+ <workItem from="1641509412324" duration="41000" />
226
+ <workItem from="1641510744190" duration="1404000" />
227
+ <workItem from="1641526151665" duration="1679000" />
228
+ <workItem from="1641640203903" duration="3434000" />
223
229
  </task>
224
230
  <task id="LOCAL-00001" summary="Fix getStyle">
225
231
  <created>1636983717385</created>
@@ -361,12 +367,51 @@
361
367
  <option name="project" value="LOCAL" />
362
368
  <updated>1640872780968</updated>
363
369
  </task>
364
- <option name="localTasksCounter" value="21" />
370
+ <task id="LOCAL-00021" summary="activity report by driver grouped by day">
371
+ <created>1640878664617</created>
372
+ <option name="number" value="00021" />
373
+ <option name="presentableId" value="LOCAL-00021" />
374
+ <option name="project" value="LOCAL" />
375
+ <updated>1640878664617</updated>
376
+ </task>
377
+ <task id="LOCAL-00022" summary="fix kms-report by driver and fix activity report with time period">
378
+ <created>1641348028566</created>
379
+ <option name="number" value="00022" />
380
+ <option name="presentableId" value="LOCAL-00022" />
381
+ <option name="project" value="LOCAL" />
382
+ <updated>1641348028566</updated>
383
+ </task>
384
+ <task id="LOCAL-00023" summary="Refactor trip and speeding reports">
385
+ <created>1641511586537</created>
386
+ <option name="number" value="00023" />
387
+ <option name="presentableId" value="LOCAL-00023" />
388
+ <option name="project" value="LOCAL" />
389
+ <updated>1641511586537</updated>
390
+ </task>
391
+ <task id="LOCAL-00024" summary="check if weekDays parameter is set">
392
+ <created>1641527800168</created>
393
+ <option name="number" value="00024" />
394
+ <option name="presentableId" value="LOCAL-00024" />
395
+ <option name="project" value="LOCAL" />
396
+ <updated>1641527800170</updated>
397
+ </task>
398
+ <option name="localTasksCounter" value="25" />
365
399
  <servers />
366
400
  </component>
367
401
  <component name="TypeScriptGeneratedFilesManager">
368
402
  <option name="version" value="3" />
369
403
  </component>
404
+ <component name="Vcs.Log.History.Properties">
405
+ <option name="COLUMN_ID_ORDER">
406
+ <list>
407
+ <option value="Default.Root" />
408
+ <option value="Default.Author" />
409
+ <option value="Default.Date" />
410
+ <option value="Default.Subject" />
411
+ <option value="Space.CommitStatus" />
412
+ </list>
413
+ </option>
414
+ </component>
370
415
  <component name="Vcs.Log.Tabs.Properties">
371
416
  <option name="TAB_STATES">
372
417
  <map>
@@ -399,6 +444,10 @@
399
444
  <MESSAGE value="timezone - check if it's running on client side" />
400
445
  <MESSAGE value="calculate avg speed" />
401
446
  <MESSAGE value="fix activity report by driver" />
402
- <option name="LAST_COMMIT_MESSAGE" value="fix activity report by driver" />
447
+ <MESSAGE value="activity report by driver grouped by day" />
448
+ <MESSAGE value="fix kms-report by driver and fix activity report with time period" />
449
+ <MESSAGE value="Refactor trip and speeding reports" />
450
+ <MESSAGE value="check if weekDays parameter is set" />
451
+ <option name="LAST_COMMIT_MESSAGE" value="check if weekDays parameter is set" />
403
452
  </component>
404
453
  </project>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.263",
3
+ "version": "1.0.267",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -87,11 +87,14 @@ async function createActivityReportByDevice(from, to){
87
87
  //Get report data from traccar
88
88
  devicesToProcess.sort((a, b) => (a.name > b.name) ? 1 : -1)
89
89
 
90
+ // use the km report to calculate kms
91
+ const kmsReport = await createKmsReport(from, to, userData, traccarInstance)
92
+
90
93
  let data = []
91
94
  if(userData.groupByDay) {
92
95
  const dates = getDates(from, to)
93
96
  for(const date of dates){
94
- if(userData.allWeek){
97
+ if(userData.allWeek || !userData.weekDays){
95
98
  const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
96
99
  const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
97
100
 
@@ -110,9 +113,33 @@ async function createActivityReportByDevice(from, to){
110
113
  const fromByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
111
114
  const toByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
112
115
 
113
- const summary = await traccar.getSummary(traccarInstance, fromByDay, toByDay, devicesToProcess)
114
- summary.forEach(s => s.date = date)
115
- data = data.concat(summary)
116
+ if(fromByDay.getTime() < toByDay.getTime()) {
117
+ const summary = await traccar.getSummary(traccarInstance, new Date(fromByDay.toUTCString()), new Date(toByDay.toUTCString()), devicesToProcess)
118
+ summary.forEach(s => s.date = date)
119
+ data = data.concat(summary)
120
+ } else {
121
+ const dayStart = new Date(new Date(date).toISOString().split('T')[0] + ' 00:00:00')
122
+ const dayEnd = new Date(new Date(date).toISOString().split('T')[0] + ' 23:59:59')
123
+
124
+ const summaryStart = await traccar.getSummary(traccarInstance, new Date(dayStart.toUTCString()), new Date(toByDay.toUTCString()), devicesToProcess)
125
+ const summaryEnd = await traccar.getSummary(traccarInstance, new Date(fromByDay.toUTCString()), new Date(dayEnd.toUTCString()), devicesToProcess)
126
+
127
+ const summary = []
128
+ summaryStart.forEach(s => {
129
+ const sEnd = summaryEnd.find(a => s.deviceId === a.deviceId)
130
+ summary.push({
131
+ date: date,
132
+ deviceId: s.deviceId,
133
+ averageSpeed: (s.averageSpeed + sEnd.averageSpeed) / 2,
134
+ distance: s.distance + sEnd.distance,
135
+ engineHours: s.engineHours + sEnd.engineHours,
136
+ maxSpeed: s.maxSpeed > sEnd.maxSpeed ? s.maxSpeed : sEnd.maxSpeed,
137
+ endOdometer: 0,
138
+ startOdometer: 0
139
+ })
140
+ })
141
+ data = data.concat(summary)
142
+ }
116
143
  }else {
117
144
  data = data.concat({date: date})
118
145
  }
@@ -122,9 +149,6 @@ async function createActivityReportByDevice(from, to){
122
149
  data = await traccar.getSummary(traccarInstance, from, to, devicesToProcess)
123
150
  }
124
151
 
125
- // use the km report to calculate kms
126
- const kmsReport = await createKmsReport(from, to, userData, traccarInstance)
127
-
128
152
  console.log('Summary:' + data.length)
129
153
 
130
154
  //Process report data
@@ -136,11 +160,11 @@ async function createActivityReportByDevice(from, to){
136
160
  }
137
161
 
138
162
  async function createActivityReportByDriver(from, to){
139
- const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
140
- console.log(deviceIds)
163
+ const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
164
+
141
165
  let tripsData = []
142
- if(deviceIds.length > 0) {
143
- tripsData = await traccar.getTrips(traccarInstance, from, to, deviceIds)
166
+ if(devices.length > 0) {
167
+ tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
144
168
  }
145
169
 
146
170
  const allData = {
@@ -163,9 +187,6 @@ function processDevices(devices, data, kmsReport) {
163
187
  if (summary) {
164
188
  summary.forEach(s => {
165
189
  const deviceKms = kmsReport[0].devices.filter(r => r.device.id === d.id)
166
-
167
- console.log(deviceKms)
168
-
169
190
  s.convertedSpentFuel = automaticReports.calculateSpentFuel(s.spentFuel, d)
170
191
  s.distance = deviceKms.length ? (userData.groupByDay ? deviceKms[0].days.find(d => d.date.getTime() === s.date.getTime()).kms : deviceKms[0].summary.distance) : 0
171
192
  })
@@ -193,7 +214,7 @@ function processDrivers(from, to, drivers, data) {
193
214
  if(userData.groupByDay) {
194
215
  const dates = getDates(from, to)
195
216
  for(const date of dates){
196
- if(userData.allWeek){
217
+ if(userData.allWeek || !userData.weekDays){
197
218
  const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
198
219
  const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
199
220
 
@@ -388,7 +409,7 @@ function exportActivityReportToPDF_Vehicle_GroupByDay(doc, translations, reportD
388
409
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
389
410
  doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
390
411
 
391
- if (!userData.allWeek) {
412
+ if (!userData.allWeek && userData.weekDays) {
392
413
  doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
393
414
  + (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
394
415
  + (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
@@ -515,7 +536,7 @@ function exportActivityReportToPDF_Driver_GroupByDay(doc, translations, reportDa
515
536
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
516
537
  doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
517
538
 
518
- if (!userData.allWeek) {
539
+ if (!userData.allWeek && userData.weekDays) {
519
540
  doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
520
541
  + (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
521
542
  + (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
package/src/kms-report.js CHANGED
@@ -7,6 +7,7 @@ const {getUserPartner} = require("fleetmap-partners");
7
7
  const traccar = require("./util/traccar");
8
8
  const {getDates} = require("./util/utils");
9
9
  const trips = require("./util/trips");
10
+ const drivers = require("./util/driver");
10
11
 
11
12
 
12
13
  let traccarInstance
@@ -26,7 +27,7 @@ async function createKmsReportByDevice(from, to) {
26
27
 
27
28
  devicesToProcess.sort((a, b) => (a.name > b.name) ? 1 : -1)
28
29
  const route = userData.allWeek ? [] : await traccar.getRoute(traccarInstance, from, to, devicesToProcess)
29
- const tripsData = await traccar.getTrips(traccarInstance, from, to, devicesToProcess.map(d => d.id))
30
+ const tripsData = await traccar.getTrips(traccarInstance, from, to, devicesToProcess)
30
31
 
31
32
  console.log('trips:' + tripsData.length)
32
33
 
@@ -39,13 +40,84 @@ async function createKmsReportByDevice(from, to) {
39
40
  }
40
41
 
41
42
  async function createKmsReportByDriver(from, to) {
43
+ const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
44
+ console.log(devices.length)
42
45
 
46
+ if(!devices.length) {
47
+ //empty report
48
+ return { drivers: [] }
49
+ }
50
+
51
+ const tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
52
+ return { drivers: processDrivers(from, to, userData.drivers, tripsData) }
43
53
  }
44
54
 
45
55
  async function createKmsReportByGroup(from, to) {
46
56
 
47
57
  }
48
58
 
59
+ function processDrivers(from, to, drivers, data) {
60
+ console.log(data)
61
+ const driversResult = []
62
+ drivers.forEach(d => {
63
+ const trips = data.filter(t => t.driverUniqueId === d.uniqueId)
64
+ if (trips.length > 0) {
65
+ const driverData = {
66
+ driver: d
67
+ }
68
+ if(userData.groupByDay) {
69
+ driverData.days = []
70
+ const dates = getDates(from, to)
71
+ for(const date of dates){
72
+ if(userData.allWeek || !userData.weekDays){
73
+ const fromByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0)
74
+ const toByDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59)
75
+
76
+ const tripsByDay = trips.filter(t => new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
77
+
78
+ driverData.days.push({
79
+ date: date,
80
+ kms: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0)
81
+ })
82
+ } else {
83
+ if((date.getDay() === 0 && userData.weekDays.sunday) ||
84
+ (date.getDay() === 1 && userData.weekDays.monday) ||
85
+ (date.getDay() === 2 && userData.weekDays.tuesday) ||
86
+ (date.getDay() === 3 && userData.weekDays.wednesday) ||
87
+ (date.getDay() === 4 && userData.weekDays.thursday) ||
88
+ (date.getDay() === 5 && userData.weekDays.friday) ||
89
+ (date.getDay() === 6 && userData.weekDays.saturday)) {
90
+
91
+ const fromByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.startTime)
92
+ const toByDay = new Date(new Date(date).toISOString().split('T')[0] + ' ' + userData.dayHours.endTime)
93
+
94
+ const tripsByDay = trips.filter(t => new Date(t.startTime) > fromByDay && new Date(t.endTime) < toByDay)
95
+
96
+ driverData.days.push({
97
+ date: date,
98
+ kms: tripsByDay.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0)
99
+ })
100
+ }else {
101
+ driverData.days.push({
102
+ date: date,
103
+ kms: 0
104
+ })
105
+ }
106
+ }
107
+ }
108
+ } else {
109
+ driverData.summary = {
110
+ distance: trips.filter(t => t.distance > 0).reduce((a, b) => a + b.distance, 0)
111
+ }
112
+ }
113
+ driversResult.push(driverData)
114
+ }
115
+ })
116
+
117
+ return driversResult
118
+ }
119
+
120
+
49
121
  function processDevices(from, to, devices, route, trips) {
50
122
  const devicesResult = []
51
123
 
@@ -81,7 +153,7 @@ function processDevices(from, to, devices, route, trips) {
81
153
  kms: 0
82
154
  }
83
155
 
84
- if(userData.allWeek){
156
+ if(userData.allWeek || !userData.weekDays){
85
157
  day.kms = dayTrips.reduce((a, b) => a + b.distance, 0) || 0
86
158
  } else {
87
159
  if((currentDate.getDay() === 0 && userData.weekDays.sunday) ||
@@ -230,7 +302,7 @@ async function exportKmsReportToPDF(userData, reportData) {
230
302
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space + 20)
231
303
  doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, space + 25)
232
304
 
233
- if(!userData.allWeek) {
305
+ if(!userData.allWeek && userData.weekDays) {
234
306
  doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
235
307
  + (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
236
308
  + (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
@@ -16,109 +16,135 @@ let traccarInstance
16
16
  let userData
17
17
 
18
18
  const fileName = 'SpeedingReport'
19
+ const eventTypes = ['deviceOverspeed']
19
20
 
20
21
  async function createSpeedingReport(from, to, reportUserData, traccar) {
22
+ console.log('Create SpeedingReport')
21
23
  traccarInstance = traccar
22
24
  userData = reportUserData
23
- console.log('createSpeedingReport', from, to, userData, traccar)
24
25
  const reportData = []
25
26
 
26
- if(userData.byDriver){
27
+ if (userData.byDriver) {
28
+ console.log("ByDriver")
27
29
  const allData = await createSpeedingReportByDriver(from, to)
28
30
  reportData.push(allData)
29
31
  }
30
- else if(userData.byGroup){
32
+ else if (userData.byGroup) {
31
33
  console.log("ByGroup")
32
- for (const g of userData.groups) {
33
- const devices = userData.devices.filter(d => d.groupId === g.id)
34
- console.log(g.name + ' devices:' + devices.length)
35
- if(devices.length > 0) {
36
- const groupData = {
37
- devices: [],
38
- group: g,
39
- xpert: devices.filter(d => d.attributes.xpert).length > 0
40
- }
34
+ const allData = await createSpeedingReportByGroup(from, to)
35
+ reportData.push(...allData)
36
+ } else {
37
+ console.log("ByDevice")
38
+ const allData = await createSpeedingReportByDevice(from, to, userData.devices)
39
+ reportData.push(allData)
40
+ }
41
41
 
42
- const eventTypes = ['deviceOverspeed']
43
- const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
44
- const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, devices)
42
+ return reportData
43
+ }
45
44
 
46
- devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
45
+ async function createSpeedingReportByGroup(from, to){
46
+ const reportData = []
47
+ for (const g of userData.groups) {
48
+ const devices = userData.devices.filter(d => d.groupId === g.id)
49
+ console.log(g.name + ' devices:' + devices.length)
50
+ if(devices.length > 0) {
51
+ const groupData = {
52
+ devices: [],
53
+ group: g,
54
+ xpert: devices.filter(d => d.attributes.xpert).length > 0
55
+ }
47
56
 
48
- if (events.length > 0) {
49
- groupData.devices = await processDevices(from, to, devices, events, routes)
50
- reportData.push(groupData)
51
- }
57
+ const events = await traccar.getEvents(traccarInstance, from, to, devices, eventTypes)
58
+ const routes = await traccar.getRoute(traccarInstance, from, to, devices)
59
+
60
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
61
+
62
+ if (events.length > 0) {
63
+ groupData.devices = await processDevices(from, to, devices, events, routes)
64
+ reportData.push(groupData)
52
65
  }
53
66
  }
54
-
55
- const withoutGroupData = await createSpeedingReportByDevice(from, to)
56
- reportData.push(withoutGroupData)
57
- } else {
58
- const allData = await createSpeedingReportByDevice(from, to)
59
- reportData.push(allData)
60
67
  }
61
68
 
69
+ const groupIds = userData.groups.map(g => g.id)
70
+ const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
71
+
72
+ const withoutGroupData = await createSpeedingReportByDevice(from, to, withoutGroupDevices)
73
+ reportData.push(withoutGroupData)
74
+
62
75
  return reportData
63
76
  }
64
77
 
65
- async function createSpeedingReportByDevice(from, to) {
66
- const groupIds = userData.groups.map(g => g.id)
67
- const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
68
-
69
- withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
78
+ async function createSpeedingReportByDevice(from, to, devices) {
79
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
70
80
 
71
- const eventTypes = ['deviceOverspeed']
72
- const events = await traccar.getEvents(traccarInstance, from, to, withoutGroupDevices, eventTypes)
73
- const routes = userData.useVehicleSpeedLimit ? [] : await traccar.getRoute(traccarInstance, from, to, withoutGroupDevices)
81
+ const routes = await traccar.getRoute(traccarInstance, from, to, devices)
82
+ const events = []
83
+ if(!userData.useVehicleSpeedLimit && userData.customSpeed){
84
+ events.push(...await getCustomSpeedLimitEvents(devices, routes))
85
+ } else {
86
+ events.push(...await traccar.getEvents(traccarInstance, from, to, devices, eventTypes))
87
+ }
74
88
 
75
- const allData = { devices: [] }
89
+ if(userData.roadSpeedLimits){
90
+ events.push(...await getHereEvents(devices, routes))
91
+ }
76
92
 
77
- if(events.length > 0 || userData.roadSpeedLimits) {
78
- allData.devices = await processDevices(from, to, withoutGroupDevices, events, routes)
79
- allData.xpert = withoutGroupDevices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
93
+ if(!events.length) {
94
+ //empty report
95
+ return { devices: [] }
80
96
  }
81
97
 
82
- return allData
98
+ return {
99
+ devices: await processDevices(from, to, devices, events, routes),
100
+ xpert: devices.filter(d => d && d.attributes && d.attributes.xpert).length > 0
101
+ }
83
102
  }
84
103
 
85
104
  async function createSpeedingReportByDriver(from, to) {
86
- const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
87
- console.log('Devices with driver',deviceIds.length)
105
+ const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
106
+ console.log('Devices with driver',devices.length)
107
+
108
+ if(!devices.length) {
109
+ //empty report
110
+ return { drivers: [] }
111
+ }
88
112
 
89
- let eventsData = []
90
- if(deviceIds.length > 0) {
91
- const devices = userData.devices.filter(d => deviceIds.includes(d.id))
92
- eventsData = await traccar.getEvents(traccarInstance, from, to, devices,['deviceOverspeed'])
113
+ const routes = await traccar.getRoute(traccarInstance, from, to, devices)
114
+ const events = []
115
+ if(!userData.useVehicleSpeedLimit && userData.customSpeed){
116
+ events.push(...await getCustomSpeedLimitEvents(devices, routes))
117
+ } else {
118
+ events.push(...await traccar.getEvents(traccarInstance, from, to, devices, eventTypes))
93
119
  }
94
120
 
95
- const allData = {
96
- drivers: []
121
+ if(userData.roadSpeedLimits){
122
+ events.push(...await getHereEvents(devices, routes))
97
123
  }
98
- console.log(eventsData.length)
99
124
 
100
- await getEventsPosition(from , to, userData.devices, eventsData)
101
- allData.drivers = await processDrivers(from, to, eventsData)
102
- console.log(allData.drivers.length)
103
- return allData
125
+ if(!events.length) {
126
+ //empty report
127
+ return { drivers: [] }
128
+ }
129
+
130
+ return {drivers: await processDrivers(from, to, events, routes)}
104
131
  }
105
132
 
106
- async function processDrivers(from, to, data) {
107
- console.log(data)
133
+ async function processDrivers(from, to, events, routes) {
108
134
  const driversResult = []
109
- const alertsWithPosition = data.filter(a => a.position)
110
-
111
- userData.drivers.forEach(d => {
112
- const alerts = alertsWithPosition.filter(e => e.position.attributes.driverUniqueId === d.uniqueId)
113
135
 
114
- if (alerts.length > 0) {
136
+ await findEventsPosition(from, to, userData.devices, events, routes)
115
137
 
138
+ userData.drivers.forEach(d => {
139
+ const driverEvents = events.filter(e => e.position && e.position.attributes.driverUniqueId === d.uniqueId)
140
+ if (driverEvents.length > 0) {
141
+ driverEvents.sort((a, b) => a.positionId - b.positionId)
116
142
  driversResult.push({
117
143
  driver: d,
118
144
  from: from,
119
145
  to: to,
120
- alerts: alerts,
121
- maxSpeed: alerts.reduce((a, b) => {
146
+ alerts: driverEvents,
147
+ maxSpeed: driverEvents.reduce((a, b) => {
122
148
  return a > b.attributes.maxSpeed ? a : b.attributes.maxSpeed
123
149
  }, 0),
124
150
  })
@@ -130,117 +156,38 @@ async function processDrivers(from, to, data) {
130
156
 
131
157
  async function processDevices(from, to, devices, events, routes) {
132
158
  const devicesResult = []
159
+ await findEventsPosition(from, to, devices, events, routes)
133
160
 
134
- if(userData.useVehicleSpeedLimit) {
135
- await getEventsPosition(from, to, devices, events)
136
-
137
- console.log(events)
138
-
139
- for (const d of devices) {
140
- const deviceEvents = events.filter(t => t.deviceId === d.id)
141
-
142
- if (deviceEvents.length > 0) {
143
- const alertsWithPosition = deviceEvents.filter(a => a.position).sort((a, b) => a.positionId - b.positionId)
144
- devicesResult.push({
145
- device: d,
146
- from: from,
147
- to: to,
148
- alerts: alertsWithPosition,
149
- maxSpeed: alertsWithPosition.reduce((a, b) => {
150
- return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
151
- }, 0),
152
- })
153
- }
154
- }
155
- } else {
156
- for (const d of devices) {
157
- const positions = routes.filter(t => t.deviceId === d.id)
158
- const maxSpeed = userData.customSpeed / 1.85200
159
-
160
- const alerts = []
161
- for(let pIndex = 0; pIndex < positions.length ; pIndex++){
162
- const position = positions[pIndex]
163
- if(position.speed > maxSpeed){
164
- const alert = {
165
- position: position,
166
- attributes: {
167
- speedLimit: maxSpeed,
168
- speed: position.speed
169
- }
170
- }
171
-
172
- pIndex = calculateEventData(positions, pIndex, alert)
173
-
174
- alerts.push(alert)
175
- }
176
- }
177
- if(alerts.length > 0){
178
- devicesResult.push({
179
- device: d,
180
- from: from,
181
- to: to,
182
- alerts: alerts,
183
- maxSpeed: alerts.reduce((a, b) => {
184
- return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
185
- }, 0),
186
- })
187
- }
161
+ for (const d of devices) {
162
+ const deviceEvents = events.filter(e => e.deviceId === d.id && e.position)
163
+ if (deviceEvents.length > 0) {
164
+ deviceEvents.sort((a, b) => a.positionId - b.positionId)
165
+ devicesResult.push({
166
+ device: d,
167
+ from: from,
168
+ to: to,
169
+ alerts: deviceEvents,
170
+ maxSpeed: deviceEvents.reduce((a, b) => {
171
+ return a > (b && b.attributes && b.attributes.maxSpeed) ? a : (b && b.attributes && b.attributes.maxSpeed)
172
+ }, 0),
173
+ })
188
174
  }
189
175
  }
190
176
 
191
177
  return devicesResult
192
178
  }
193
179
 
194
- async function getEventsPosition(from, to, devices, events){
195
-
196
- const deviceIds = [...new Set(events.map(e => e.deviceId))]
197
- const routeData = await traccar.getRoute(traccarInstance, from, to, deviceIds.map(id => { return { id: id } } ))
198
-
199
- console.log(events)
200
-
180
+ async function findEventsPosition(from, to, devices, events, routes){
201
181
  for (const d of devices) {
202
- let alerts = events.filter(t => t.deviceId === d.id)
203
-
204
- if (alerts.length > 0 || userData.roadSpeedLimits) {
205
- const positions = routeData.filter(p => p.deviceId === d.id)
206
-
207
- if (userData.roadSpeedLimits && positions.length) {
208
- try {
209
- const results = await here.routeMatch(positions)
210
- const hereAlerts = results.map(r => {
211
- const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
212
- return {
213
- ...r,
214
- roadSpeedLimit: r.speedLimit,
215
- deviceId: d.id,
216
- position,
217
- positionId: position && position.id,
218
- attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
219
- }
220
- })
221
- console.log('hereAlerts', hereAlerts)
222
- const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
223
- if (idx === 1) {
224
- return [cur]
225
- }
226
- if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
227
- return acc.concat(cur)
228
- }
229
- return acc
230
- })
231
- events.push(...reduced)
232
- alerts = events.filter(t => t.deviceId === d.id)
233
- } catch (e) {
234
- console.error(e)
235
- }
236
- }
182
+ let deviceEvents = events.filter(e => e.deviceId === d.id && e.positionId)
183
+ if (deviceEvents.length > 0) {
184
+ deviceEvents.sort((a,b) => a.positionId-b.positionId )
185
+ const positions = routes.filter(p => p.deviceId === d.id)
237
186
 
238
- for (const a of alerts) {
187
+ for (const a of deviceEvents) {
239
188
  let pIndex = positions.findIndex(p => p.id === a.positionId)
240
189
  if (pIndex > 0) {
241
- a.position = positions[pIndex]
242
190
  let geofence = null
243
-
244
191
  if (a.geofenceId) {
245
192
  geofence = userData.geofences.find(g => g.id === a.geofenceId)
246
193
  if (geofence) {
@@ -248,44 +195,87 @@ async function getEventsPosition(from, to, devices, events){
248
195
  }
249
196
  }
250
197
 
251
- let endEventPosition = a.position
252
- let maxSpeed = a.position.speed
253
- let dist = 0
254
- while (pIndex + 1 < positions.length) {
255
- pIndex++
256
-
257
- dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
258
- point([positions[pIndex].longitude, positions[pIndex].latitude]))
259
- endEventPosition = positions[pIndex]
260
- if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
261
- a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
262
- a.attributes.maxSpeed = maxSpeed
263
- a.distance = dist
264
- break
265
- } else {
266
- if (maxSpeed < endEventPosition.speed) {
267
- maxSpeed = endEventPosition.speed
268
- }
269
- }
270
- }
198
+ if(!a.position) {
199
+ a.position = positions[pIndex]
200
+ pIndex = calculateEventData(positions, pIndex, a, d, geofence)
271
201
 
272
- if (a.position.attributes.driverUniqueId) {
273
- const driver = userData.drivers.find(d => d.uniqueId === a.position.attributes.driverUniqueId)
274
- a.driver = driver && driver.name
202
+ positions.slice(pIndex)
275
203
  }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
276
209
 
277
- a.deviceName = d.name
210
+ async function getCustomSpeedLimitEvents(devices, routes){
211
+ console.log('calculate custom speed limit events')
212
+ const events = []
213
+ const maxSpeed = userData.customSpeed / 1.85200
278
214
 
279
- positions.slice(pIndex)
215
+ for (const d of devices) {
216
+ const positions = routes.filter(p => p.deviceId === d.id)
217
+ let eventIsActive = false
218
+
219
+ for (const position of positions) {
220
+ if(position.speed > maxSpeed && !eventIsActive){
221
+ const event = {
222
+ positionId: position && position.id,
223
+ deviceId: d.id,
224
+ attributes: {
225
+ speedLimit: maxSpeed,
226
+ speed: position.speed
227
+ }
280
228
  }
229
+ events.push(event)
230
+ eventIsActive = true
231
+ } else if (position.speed <= maxSpeed) {
232
+ eventIsActive = false
281
233
  }
282
234
  }
283
235
  }
236
+
237
+ return events
284
238
  }
285
239
 
286
- function calculateEventData(positions, pIndex, a, geofence){
287
- let endEventPosition = a.position
288
- let maxSpeed = a.position.speed
240
+ async function getHereEvents(devices, routes){
241
+ console.log('calculate custom speed limit events')
242
+ const events = []
243
+ for (const d of devices) {
244
+ const positions = routes.filter(p => p.deviceId === d.id)
245
+ try {
246
+ const results = await here.routeMatch(positions)
247
+ const hereAlerts = results.map(r => {
248
+ const position = positions.find(p => new Date(p.fixTime).getTime() === r.timestamp)
249
+ return {
250
+ ...r,
251
+ roadSpeedLimit: r.speedLimit,
252
+ deviceId: d.id,
253
+ position,
254
+ positionId: position && position.id,
255
+ attributes: {speedLimit: r.speedLimit, speed: r.currentSpeedKmh / 1.85200}
256
+ }
257
+ })
258
+ console.log('hereAlerts', hereAlerts)
259
+ const reduced = hereAlerts.reduce((acc, cur, idx, src) => {
260
+ if (idx === 1) {
261
+ return [cur]
262
+ }
263
+ if (cur.timestamp - src[idx - 1].timestamp > 300000 || cur.roadSpeedLimit !== src[idx - 1].roadSpeedLimit) {
264
+ return acc.concat(cur)
265
+ }
266
+ return acc
267
+ })
268
+ events.push(...reduced)
269
+ } catch (e) {
270
+ //console.error(e)
271
+ }
272
+ }
273
+ return events
274
+ }
275
+
276
+ function calculateEventData(positions, pIndex, alert, device, geofence){
277
+ let endEventPosition = alert.position
278
+ let maxSpeed = alert.position.speed
289
279
  let dist = 0
290
280
  while (pIndex + 1 < positions.length) {
291
281
  pIndex++
@@ -293,10 +283,10 @@ function calculateEventData(positions, pIndex, a, geofence){
293
283
  dist += distance(point([endEventPosition.longitude, endEventPosition.latitude]),
294
284
  point([positions[pIndex].longitude, positions[pIndex].latitude]))
295
285
  endEventPosition = positions[pIndex]
296
- if (endEventPosition.speed <= a.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
297
- a.eventTime = new Date(endEventPosition.fixTime) - new Date(a.position.fixTime)
298
- a.attributes.maxSpeed = maxSpeed
299
- a.distance = dist
286
+ if (endEventPosition.speed <= alert.attributes.speedLimit || (geofence && isOutsideGeofence(geofence, endEventPosition))) {
287
+ alert.eventTime = new Date(endEventPosition.fixTime) - new Date(alert.position.fixTime)
288
+ alert.attributes.maxSpeed = maxSpeed
289
+ alert.distance = dist
300
290
  break
301
291
  } else {
302
292
  if (maxSpeed < endEventPosition.speed) {
@@ -305,6 +295,14 @@ function calculateEventData(positions, pIndex, a, geofence){
305
295
  }
306
296
  }
307
297
 
298
+
299
+ if (alert.position.attributes.driverUniqueId) {
300
+ const driver = userData.drivers.find(d => d.uniqueId === alert.position.attributes.driverUniqueId)
301
+ alert.driver = driver && driver.name
302
+ }
303
+
304
+ alert.deviceName = device.name
305
+
308
306
  return pIndex
309
307
  }
310
308
 
@@ -367,7 +365,7 @@ async function exportSpeedingReportToPDF(userData, reportData) {
367
365
  doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
368
366
  doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
369
367
  if (d.alerts[0] && !userData.byDriver) {
370
- doc.text(translations.report.speedLimit + ": " + (userData.useVehicleSpeedLimit ? Math.round(d.alerts[0].attributes.speedLimit * 1.85200) : userData.customSpeed) + ' Km/h', 20, space + 30)
368
+ doc.text(translations.report.speedLimit + ": " + ((userData.useVehicleSpeedLimit || !userData.customSpeed) ? Math.round(d.alerts[0].attributes.speedLimit * 1.85200) : userData.customSpeed) + ' Km/h', 20, space + 30)
371
369
  }
372
370
  d.alerts.map(a => {
373
371
  const temp = [
@@ -3,13 +3,13 @@ const messages = require('../lang')
3
3
  const jsPDF = require('jspdf')
4
4
  const {convertMS, convertToLocaleString, convertToLocaleDateString, convertToLocaleTimeString} = require("./util/utils")
5
5
  require('jspdf-autotable')
6
- const {coordsDistance} = require("./util/utils")
7
6
  const drivers = require("./util/driver")
8
7
  const {getUserPartner} = require("fleetmap-partners")
9
8
  const {headerFromUser, addTable} = require("./util/pdfDocument")
10
9
  const {getStyle} = require("./reportStyle")
11
10
  const traccar = require("./util/traccar")
12
11
  const trips = require("./util/trips");
12
+ const {isInsideTimetable, addNearestPOIs} = require("./util/trips");
13
13
 
14
14
 
15
15
  let traccarInstance
@@ -23,26 +23,26 @@ async function createTripReport(from, to, reportUserData, traccar) {
23
23
  traccarInstance = traccar
24
24
  const reportData = []
25
25
 
26
- if(userData.byDriver){
27
- const allData = await createTripReportByDriver(from, to)
28
- reportData.push(allData)
26
+ if (userData.byDriver) {
27
+ console.log("ByDriver")
28
+ const report = await createTripReportByDriver(from, to)
29
+ reportData.push(report)
29
30
  }
30
- else if(userData.byGroup){
31
+ else if (userData.byGroup) {
31
32
  console.log("ByGroup")
32
33
  const allData = await createTripReportByGroup(from, to)
33
34
  reportData.push(...allData)
35
+ } else {
36
+ console.log("ByDevice")
37
+ const report = await createTripReportByDevice(from, to)
38
+ reportData.push(report)
34
39
  }
35
40
 
36
- const groupIds = userData.groups.map(g => g.id)
37
- const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
38
-
39
- const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
40
- reportData.push(allData)
41
-
42
41
  return reportData
43
42
  }
44
43
 
45
- async function createTripReportByDevice(from, to, devices) {
44
+ async function createTripReportByDevice(from, to) {
45
+ const devices = userData.devices
46
46
  const allData = {
47
47
  devices: [],
48
48
  xpert: devices.filter(d => d.attributes.xpert).length > 0
@@ -51,7 +51,7 @@ async function createTripReportByDevice(from, to, devices) {
51
51
  devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
52
52
 
53
53
  const devicesToSlice = devices.slice()
54
- const data = await traccar.getTrips(traccarInstance, from, to, devicesToSlice.map(d => d.id))
54
+ const data = await traccar.getTrips(traccarInstance, from, to, devicesToSlice)
55
55
  const stopsData = await traccar.getStops(traccarInstance, from, to, devicesToSlice)
56
56
 
57
57
  console.log('Trips:' + data.length)
@@ -77,90 +77,75 @@ async function createTripReportByGroup(from, to) {
77
77
  }
78
78
 
79
79
  const response = await traccarInstance.reports.reportsTripsGet(from, to, null, [g.id])
80
- const data = response.data
80
+ const tripsData = response.data
81
81
 
82
82
  const stopsResponse = await traccarInstance.reports.reportsStopsGet(from, to, null, [g.id])
83
83
  const stopsData = stopsResponse.data
84
84
 
85
85
  devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
86
86
 
87
- if (data.length > 0) {
88
-
89
- console.log('Trips:' + data.length)
90
- groupData.devices = processDevices(from, to, devices, data, stopsData, userData)
87
+ if (tripsData.length > 0) {
88
+ console.log('Trips:' + tripsData.length)
89
+ groupData.devices = processDevices(from, to, devices, tripsData, stopsData, userData)
91
90
 
92
91
  reportData.push(groupData)
93
92
  }
94
93
  }
95
94
  }
95
+
96
+ const groupIds = userData.groups.map(g => g.id)
97
+ const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
98
+
99
+ const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
100
+ reportData.push(allData)
101
+
96
102
  return reportData
97
103
  }
98
104
 
99
105
  async function createTripReportByDriver(from, to){
100
- const deviceIds = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
101
- console.log(deviceIds.length)
102
-
103
- let tripsData = []
104
- if(deviceIds.length > 0) {
105
- const response = await traccarInstance.reports.reportsTripsGet(from, to, deviceIds)
106
- tripsData = response.data
107
- }
106
+ const devices = await drivers.devicesByDriver(traccarInstance, from, to, userData.drivers, userData.devices)
107
+ console.log(devices.length)
108
108
 
109
- const allData = {
110
- drivers: []
109
+ if(!devices.length){
110
+ //Empty report
111
+ return { drivers:[] }
111
112
  }
112
113
 
113
- allData.drivers = processDrivers(from, to, userData.drivers, tripsData)
114
+ const tripsData = await traccar.getTrips(traccarInstance, from, to, devices)
114
115
 
115
- return allData
116
+ return { drivers: processDrivers(from, to, userData.drivers, tripsData)}
116
117
  }
117
118
 
118
119
  function processDevices(from, to, devices, data, stopsData) {
119
120
  const devicesResult = []
120
121
 
121
122
  devices.forEach(d => {
122
- const trips = data.filter(t => t.deviceId === d.id && (userData.allWeek || isInsideTimetable(t, userData)))
123
+ const trips = data.filter(t => t.deviceId === d.id
124
+ && (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
123
125
  const stops = stopsData.filter(s => s.deviceId === d.id)
124
126
 
125
- trips.forEach(t => {
126
- t.totalKms = t.distance / 1000
127
+ addNearestPOIs(trips, userData)
128
+
129
+ trips.forEach(trip => {
127
130
  if (automaticReports.deviceWithFuelInfo(d)) {
128
- t.fuelConsumption = Math.round((t.spentFuel * d.attributes.fuel_tank_capacity) / 100)
129
- t.avgFuelConsumption = t.totalKms > 0 ? Math.round(t.fuelConsumption * 100 / t.totalKms) : 0
131
+ trip.fuelConsumption = Math.round((trip.spentFuel * d.attributes.fuel_tank_capacity) / 100)
132
+ trip.avgFuelConsumption = trip.totalKms > 0 ? Math.round(trip.fuelConsumption * 100 / trip.totalKms) : 0
130
133
  } else {
131
- t.fuelConsumption = '-'
132
- t.avgFuelConsumption = '-'
134
+ trip.fuelConsumption = '-'
135
+ trip.avgFuelConsumption = '-'
133
136
  }
134
137
 
135
- const distance = userData.geofences
136
- .filter(g => g && g.area.startsWith('CIRCLE'))
137
- .map(g => {
138
- const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
139
- const coord = str.trim().split(' ')
140
- return {
141
- p: g,
142
- distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
143
- }
144
- })
145
- const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
146
- if (nearestPOIs.length > 0) {
147
- t.endPOIName = nearestPOIs[0].p.name
138
+ const stop = getStop(new Date(trip.startTime), stops)
139
+ if (stop) {
140
+ trip.stopDuration = (new Date(stop.endTime) - new Date(stop.startTime))
141
+ trip.stopEngineHours = stop.engineHours
142
+ } else {
143
+ trip.stopDuration = 0
144
+ trip.stopEngineHours = 0
148
145
  }
149
146
  })
150
147
 
151
148
  if (trips.length > 0) {
152
- trips.forEach(trip => {
153
- const stop = getStop(new Date(trip.startTime), stops)
154
-
155
- if (stop) {
156
- trip.stopDuration = (new Date(stop.endTime) - new Date(stop.startTime))
157
- trip.stopEngineHours = stop.engineHours
158
- } else {
159
- trip.stopDuration = 0
160
- trip.stopEngineHours = 0
161
- }
162
- })
163
-
164
149
  const deviceData = {
165
150
  device: d,
166
151
  from: from,
@@ -188,11 +173,12 @@ function processDrivers(from, to, drivers, data) {
188
173
  console.log(data)
189
174
  const driversResult = []
190
175
  drivers.forEach(d => {
191
- const trips = data.filter(t => t.driverUniqueId === d.uniqueId)
176
+ const trips = data.filter(t => t.driverUniqueId === d.uniqueId
177
+ && (userData.allWeek || !userData.weekDays || isInsideTimetable(t, userData)))
192
178
 
193
- trips.forEach(t => {
194
- t.totalKms = t.distance / 1000
195
- })
179
+ trips.sort((a,b)=>new Date(a.startTime).getTime()-new Date(b.startTime).getTime())
180
+
181
+ addNearestPOIs(trips, userData)
196
182
 
197
183
  if (trips.length > 0) {
198
184
  const driverData = {
@@ -201,14 +187,13 @@ function processDrivers(from, to, drivers, data) {
201
187
  to: to,
202
188
  totalDuration: trips.reduce((a, b) => a + b.duration, 0),
203
189
  totalDistance: trips.reduce((a, b) => a + b.distance, 0),
204
- maxSpeed: trips.reduce((a, b) => {
205
- return a > b.maxSpeed ? a : b.maxSpeed
206
- }, 0),
190
+ maxSpeed: trips.reduce((a, b) => { return a > b.maxSpeed ? a : b.maxSpeed }, 0),
207
191
  trips: trips,
208
192
  }
209
193
  driversResult.push(driverData)
210
194
  }
211
195
  })
196
+ console.log(driversResult)
212
197
 
213
198
  return driversResult
214
199
  }
@@ -262,7 +247,7 @@ async function exportTripReportToPDF(userData, reportData) {
262
247
  doc.setFontSize(11)
263
248
  doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space+20 )
264
249
  doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
265
- if(!userData.allWeek) {
250
+ if(!userData.allWeek && userData.weekDays) {
266
251
  doc.text((userData.weekDays.monday ? ' ' + translations.report.monday + ',' : '')
267
252
  + (userData.weekDays.tuesday ? ' ' + translations.report.tuesday + ',' : '')
268
253
  + (userData.weekDays.wednesday ? ' ' + translations.report.wednesday + ',' : '')
@@ -453,30 +438,6 @@ function getStop(tripEndDate, stops){
453
438
  return null
454
439
  }
455
440
 
456
- function isInsideTimetable(t, userData){
457
- const tripStart = new Date(t.startTime)
458
- const tripEnd = new Date(t.endTime)
459
-
460
- if((tripStart.getDay() === 0 && userData.weekDays.sunday) ||
461
- (tripStart.getDay() === 1 && userData.weekDays.monday) ||
462
- (tripStart.getDay() === 2 && userData.weekDays.tuesday) ||
463
- (tripStart.getDay() === 3 && userData.weekDays.wednesday) ||
464
- (tripStart.getDay() === 4 && userData.weekDays.thursday) ||
465
- (tripStart.getDay() === 5 && userData.weekDays.friday) ||
466
- (tripStart.getDay() === 6 && userData.weekDays.saturday)) {
467
-
468
- const startDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
469
- const endDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
470
-
471
- console.log(tripStart, startDate, endDate)
472
-
473
- //Trips inside time period
474
- return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
475
- }
476
-
477
- return false
478
- }
479
-
480
441
  exports.createTripReport = createTripReport;
481
442
  exports.exportTripReportToPDF = exportTripReportToPDF;
482
443
  exports.exportTripReportToExcel = exportTripReportToExcel;
@@ -9,10 +9,9 @@ async function devicesByDriver(traccarInstance, from, to, drivers, devices){
9
9
  return e.attributes.driverUniqueId === d.uniqueId
10
10
  })
11
11
 
12
- deviceIds.push(events.map(e => e.deviceId))
12
+ deviceIds.push(...events.map(e => e.deviceId))
13
13
  }
14
-
15
- return [...new Set(deviceIds.flat())]
14
+ return devices.filter(d => deviceIds.includes(d.id))
16
15
  }
17
16
 
18
17
  exports.devicesByDriver = devicesByDriver
@@ -14,12 +14,12 @@ async function getRoute(traccar, from, to, devices){
14
14
  return result.map(r => r.data).flat()
15
15
  }
16
16
 
17
- async function getTrips(traccar, from, to, deviceIds){
18
- const devicesToSlice = deviceIds.slice()
17
+ async function getTrips(traccar, from, to, devices){
18
+ const devicesToSlice = devices.slice()
19
19
  const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
20
20
  let requests = []
21
21
  for (const a of arrayOfArrays) {
22
- const promise = traccar.reports.reportsTripsGet(from, to, a)
22
+ const promise = traccar.reports.reportsTripsGet(from, to, a.map(d => d.id))
23
23
  requests = requests.concat(promise)
24
24
  }
25
25
 
package/src/util/trips.js CHANGED
@@ -1,8 +1,30 @@
1
1
  const traccar = require("./traccar");
2
+ const {coordsDistance} = require("./utils");
2
3
 
3
4
  const minDistance = 0
4
5
  const minAvgSpeed = 0
5
6
 
7
+ function addNearestPOIs(trips, userData){
8
+ trips.forEach(t => {
9
+ t.totalKms = t.distance / 1000
10
+
11
+ const distance = userData.geofences
12
+ .filter(g => g && g.area.startsWith('CIRCLE'))
13
+ .map(g => {
14
+ const str = g.area.substring('CIRCLE ('.length, g.area.indexOf(','))
15
+ const coord = str.trim().split(' ')
16
+ return {
17
+ p: g,
18
+ distance: Math.round(coordsDistance(parseFloat(coord[1]), parseFloat(coord[0]), t.endLon, t.endLat))
19
+ }
20
+ })
21
+ const nearestPOIs = distance.filter(a => a.distance < 100).sort((a, b) => (a.distance > b.distance) ? 1 : -1)
22
+ if (nearestPOIs.length > 0) {
23
+ t.endPOIName = nearestPOIs[0].p.name
24
+ }
25
+ })
26
+ }
27
+
6
28
  async function checkTripsKms(traccarInstance, from, to, routeData, tripsData, devices) {
7
29
  console.log('checkTripsKms')
8
30
  const trips = tripsData.filter(t => t.distance === minDistance && t.averageSpeed > minAvgSpeed)
@@ -20,4 +42,35 @@ async function checkTripsKms(traccarInstance, from, to, routeData, tripsData, de
20
42
  }
21
43
  }
22
44
 
45
+ function isInsideTimetable(t, userData){
46
+ const tripStart = new Date(t.startTime)
47
+ const tripEnd = new Date(t.endTime)
48
+
49
+ if((tripStart.getDay() === 0 && userData.weekDays.sunday) ||
50
+ (tripStart.getDay() === 1 && userData.weekDays.monday) ||
51
+ (tripStart.getDay() === 2 && userData.weekDays.tuesday) ||
52
+ (tripStart.getDay() === 3 && userData.weekDays.wednesday) ||
53
+ (tripStart.getDay() === 4 && userData.weekDays.thursday) ||
54
+ (tripStart.getDay() === 5 && userData.weekDays.friday) ||
55
+ (tripStart.getDay() === 6 && userData.weekDays.saturday)) {
56
+
57
+ const startDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.startTime)
58
+ const endDate = new Date(new Date(tripStart).toISOString().split('T')[0] + ' '+userData.dayHours.endTime)
59
+
60
+ console.log(tripStart, startDate, endDate)
61
+
62
+ //Trips inside time period
63
+ if(startDate.getTime() < endDate.getTime()) {
64
+ return tripStart.getTime() > startDate.getTime() && tripEnd.getTime() < endDate.getTime()
65
+ } else {
66
+ return (tripStart.getTime() < endDate.getTime() && tripEnd.getTime() < endDate.getTime()) ||
67
+ (tripStart.getTime() > startDate.getTime())
68
+ }
69
+ }
70
+
71
+ return false
72
+ }
73
+
23
74
  exports.checkTripsKms = checkTripsKms
75
+ exports.isInsideTimetable = isInsideTimetable
76
+ exports.addNearestPOIs = addNearestPOIs