fleetmap-reports 1.0.288 → 1.0.292

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.
@@ -3,7 +3,7 @@ const moment = require('moment')
3
3
  function sliceArray(longArray) {
4
4
  const arrayToSlice = longArray.slice()
5
5
 
6
- const size = 200
6
+ const size = 10
7
7
  const arrayOfArrays = []
8
8
  for (let i=0; i<arrayToSlice.length; i+=size) {
9
9
  arrayOfArrays.push(arrayToSlice.slice(i,i+size));
@@ -1,8 +1,11 @@
1
1
  const automaticReports = require("./automaticReports")
2
2
  const messages = require('../lang')
3
3
  const jsPDF = require('jspdf')
4
- const autotable = require('jspdf-autotable')
5
- const reportStyle = require("./reportStyle")
4
+ require('jspdf-autotable')
5
+ const {getStyle} = require("./reportStyle");
6
+ const {headerFromUser} = require("./util/pdfDocument");
7
+ const {getUserPartner} = require("fleetmap-partners");
8
+ const {convertToLocaleString} = require("./util/utils");
6
9
 
7
10
  const fileName = 'EventReport'
8
11
 
@@ -114,10 +117,11 @@ async function processDevices(from, to, devices, geofences, drivers, data) {
114
117
  return devicesResult
115
118
  }
116
119
 
117
- function exportSpeedingReportToPDF(userData, reportData) {
120
+ async function exportSpeedingReportToPDF(userData, reportData) {
118
121
  console.log('Export to PDF')
119
122
 
120
123
  const lang = userData.user.attributes.lang
124
+ const timezone = userData.user.attributes.timezone
121
125
  const translations = messages[lang] ? messages[lang] : messages['en-GB']
122
126
 
123
127
  const headers = [
@@ -129,8 +133,7 @@ function exportSpeedingReportToPDF(userData, reportData) {
129
133
  if (reportData.devices) {
130
134
  let first = true
131
135
  const doc = new jsPDF.jsPDF('l');
132
- doc.setFontSize(14)
133
- doc.text(translations.report.titleEventsReport, 15, 15 )
136
+ await headerFromUser(doc, translations.report.titleEventsReport, userData.user)
134
137
 
135
138
  reportData.devices.forEach(d => {
136
139
  let data = []
@@ -144,12 +147,11 @@ function exportSpeedingReportToPDF(userData, reportData) {
144
147
  first = false
145
148
  space = 10
146
149
  }
147
- doc.setFontSize(12)
148
-
150
+ doc.setFontSize(13)
149
151
  doc.text(name, 20, space+20 )
150
- doc.setFontSize(10)
152
+ doc.setFontSize(11)
151
153
  doc.text(group, 200, space+20 )
152
- doc.text(new Date(d.from).toLocaleString() + ' - ' + new Date(d.to).toLocaleString(), 20, space+25 )
154
+ doc.text(convertToLocaleString(d.from, lang, timezone) + ' - ' + convertToLocaleString(d.to, lang, timezone), 20, space+25 )
153
155
 
154
156
  doc.autoTable(['','','','',''], [
155
157
  [translations.report.event_ignitionOn,translations.report.event_ignitionOff, translations.report.event_geofenceEnter,
@@ -158,9 +160,10 @@ function exportSpeedingReportToPDF(userData, reportData) {
158
160
  d.alerts.filter(a => a.type === 'geofenceEnter').length,d.alerts.filter(a => a.type === 'geofenceExit').length,
159
161
  d.alerts.filter(a => a.type === 'deviceOverspeed').length],
160
162
  [translations.report.event_driverChanged,translations.report.event_powerOn, translations.report.event_sos,
161
- translations.report.event_deviceFuelDrop],
163
+ translations.report.event_deviceFuelDrop, translations.report.eve],
162
164
  [d.alerts.filter(a => a.type === 'driverChanged').length,d.alerts.filter(a => a.type === 'powerOn').length,
163
- d.alerts.filter(a => a.type === 'sos').length,d.alerts.filter(a => a.type === 'deviceFuelDrop').length]
165
+ d.alerts.filter(a => a.type === 'sos').length,d.alerts.filter(a => a.type === 'deviceFuelDrop').length,
166
+ d.alerts.filter(a => a.type === 'powerCut').length]
164
167
  ], { startY: space+30 , showHead: false, bodyStyles: { fillColor: [256, 256, 256], textColor: [30, 30, 30], halign: 'center', valign: 'middle' } , alternateRowStyles: {fillColor: [256, 256, 256], valign: 'bottom'}});
165
168
 
166
169
  d.alerts.map(a => {
@@ -178,22 +181,26 @@ function exportSpeedingReportToPDF(userData, reportData) {
178
181
  '','',''
179
182
  ]
180
183
 
184
+ const style = getStyle(getUserPartner(userData.user))
181
185
  doc.autoTable({
182
186
  head: [headers],
183
187
  body: data,
184
188
  foot: [footValues],
185
189
  showFoot: 'lastPage',
186
190
  headStyles: {
187
- fillColor: reportStyle.pdfHeaderColor,
188
- textColor: reportStyle.pdfHeaderTextColor
191
+ fillColor: style.pdfHeaderColor,
192
+ textColor: style.pdfHeaderTextColor,
193
+ fontSize: 10
189
194
  },
190
195
  bodyStyles: {
191
- fillColor: reportStyle.pdfBodyColor,
192
- textColor: reportStyle.pdfBodyTextColor
196
+ fillColor: style.pdfBodyColor,
197
+ textColor: style.pdfBodyTextColor,
198
+ fontSize: 8
193
199
  },
194
200
  footStyles: {
195
- fillColor: reportStyle.pdfFooterColor,
196
- textColor: reportStyle.pdfFooterTextColor
201
+ fillColor: style.pdfFooterColor,
202
+ textColor: style.pdfFooterTextColor,
203
+ fontSize: 9
197
204
  },
198
205
  startY: space + 65
199
206
  })
@@ -265,10 +272,7 @@ function getAlertInfo(drivers, alert) {
265
272
 
266
273
  function getAlertDate(user, alert) {
267
274
  if(alert.position) {
268
- return new Date(alert.position.fixTime).toLocaleString(user.attributes.lang, {
269
- timeZone: user.attributes.timezone,
270
- hour12: false
271
- })
275
+ return convertToLocaleString(alert.position.fixTime, user.attributes.lang, user.attributes.timezone)
272
276
  }
273
277
  }
274
278
 
package/src/here.js CHANGED
@@ -97,10 +97,10 @@ function fillGeocoding(rows) {
97
97
  }*/
98
98
 
99
99
  exports.routeMatch = async (rows) => {
100
+ console.log('here sending', rows.length)
100
101
  const csv = generateCSV(rows)
101
102
  const response = await axios.post(calcRoute, csv, { headers: { 'Content-Type': 'application/binary' }})
102
103
  const hereData = response.data
103
- console.dir(hereData, {depth: null})
104
104
  const route = hereData.response.route[0]
105
105
  const results = []
106
106
  const wayPoints = route.waypoint
@@ -0,0 +1,285 @@
1
+ const traccar = require("./util/traccar");
2
+ const messages = require("../lang");
3
+ const jsPDF = require("jspdf");
4
+ const {headerFromUser, AmiriRegular} = require("./util/pdfDocument");
5
+ const {convertToLocaleString, convertMS} = require("./util/utils");
6
+ const {getStyle} = require("./reportStyle");
7
+ const {getUserPartner} = require("fleetmap-partners");
8
+
9
+
10
+ let traccarInstance
11
+ let userData
12
+
13
+ const fileName = 'IdleReport'
14
+
15
+ async function createIdleReport(from, to, reportUserData, traccar) {
16
+ console.log('Create IdleReport')
17
+ userData = reportUserData
18
+ traccarInstance = traccar
19
+ const reportData = []
20
+
21
+ if (userData.byGroup) {
22
+ console.log("ByGroup")
23
+ const allData = await createTripReportByGroup(from, to)
24
+ reportData.push(...allData)
25
+ } else {
26
+ console.log("ByDevice")
27
+ const report = await createTripReportByDevice(from, to)
28
+ reportData.push(report)
29
+ }
30
+
31
+ return reportData
32
+ }
33
+
34
+ async function createTripReportByGroup(from, to) {
35
+ const reportData = []
36
+ for (const g of userData.groups) {
37
+ const devices = userData.devices.filter(d => d.groupId === g.id)
38
+ console.log(g.name + ' devices:' + devices.length)
39
+ if(devices.length > 0) {
40
+ const groupData = {
41
+ devices: [],
42
+ group: g,
43
+ from: from,
44
+ to: to
45
+ }
46
+
47
+ const response = await traccarInstance.reports.reportsRouteGet(from, to, null, [g.id])
48
+ const routes = response.data
49
+
50
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
51
+
52
+ if (routes.length > 0) {
53
+ console.log('Routes:' + routes.length)
54
+ groupData.devices = processDevices(from, to, devices, routes)
55
+
56
+ reportData.push(groupData)
57
+ }
58
+ }
59
+ }
60
+
61
+ const groupIds = userData.groups.map(g => g.id)
62
+ const withoutGroupDevices = userData.devices.filter(d => !groupIds.includes(d.groupId))
63
+
64
+ const allData = await createTripReportByDevice(from, to, withoutGroupDevices)
65
+ reportData.push(allData)
66
+
67
+ return reportData
68
+ }
69
+
70
+ async function createTripReportByDevice(from, to) {
71
+ const devices = userData.devices
72
+ const allData = {
73
+ devices: [],
74
+ from: from,
75
+ to: to
76
+ }
77
+
78
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
79
+
80
+ const devicesToSlice = devices.slice()
81
+ const route = await traccar.getRoute(traccarInstance, from, to, devicesToSlice)
82
+
83
+ console.log('Route:' + route.length)
84
+
85
+ if (route.length > 0) {
86
+ allData.devices = processDevices(from, to, devices, route)
87
+ }
88
+
89
+ return allData
90
+ }
91
+
92
+ function processDevices(from, to, devices, routes) {
93
+ const devicesResult = []
94
+
95
+ devices.forEach(d => {
96
+ const route = routes.filter(p => p.deviceId === d.id)
97
+
98
+ const idleEvents = []
99
+ let inIdle = false
100
+ route.forEach(p => {
101
+ if(p.attributes.ignition && p.speed === 0){
102
+ if(!inIdle) {
103
+ const idleEvent = {
104
+ position: p,
105
+ idleTime: 0
106
+ }
107
+ idleEvents.push(idleEvent)
108
+ inIdle = true
109
+ }
110
+ } else if(inIdle) {
111
+ const currentIdleEvent = idleEvents[idleEvents.length-1]
112
+ currentIdleEvent.idleTime = new Date(p.fixTime) - new Date(currentIdleEvent.position.fixTime)
113
+ inIdle = false
114
+ }
115
+ })
116
+
117
+ if(idleEvents.length) {
118
+ const deviceData = {
119
+ device: d,
120
+ idleEvents: idleEvents
121
+ }
122
+ devicesResult.push(deviceData)
123
+ }
124
+ })
125
+
126
+ return devicesResult
127
+ }
128
+
129
+ async function exportIdleReportToPDF(userData, reportData) {
130
+ console.log('Export to PDF')
131
+
132
+ const lang = userData.user.attributes.lang
133
+ const timezone = userData.user.attributes.timezone
134
+ const translations = messages[lang] ? messages[lang] : messages['en-GB']
135
+
136
+ const idleData = userData.byDriver ? reportData.drivers : reportData.devices
137
+
138
+ const headers = [
139
+ translations.report.date,
140
+ translations.report.address,
141
+ translations.report.duration
142
+ ]
143
+
144
+ if (userData.byDriver) {
145
+ headers.push(translations.report.vehicle)
146
+ } else {
147
+ headers.push(translations.report.driver)
148
+ }
149
+
150
+ if (idleData) {
151
+ let first = true
152
+ const doc = new jsPDF.jsPDF('l');
153
+ await headerFromUser(doc, translations.report.titleIdleReport, userData.user)
154
+
155
+ idleData.forEach(d => {
156
+ try {
157
+ let data = []
158
+
159
+ const name = userData.byDriver ? d.driver.name : deviceName(d.device)
160
+ const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
161
+
162
+ let space = 0
163
+ if(!first) {
164
+ doc.addPage()
165
+ } else {
166
+ first = false
167
+ space = 10
168
+ }
169
+ doc.setFontSize(13)
170
+ doc.text(name, 20, space+20 )
171
+ doc.setFontSize(11)
172
+ doc.text(group ? translations.report.group + ': ' + group.name : '', 150, space+20 )
173
+ doc.text(convertToLocaleString(reportData.from, lang, timezone) + ' - ' + convertToLocaleString(reportData.to, lang, timezone), 20, space+25 )
174
+
175
+ d.idleEvents.map(a => {
176
+ const temp = [
177
+ getIdleEventDate(a, userData.user),
178
+ a.position.address,
179
+ convertMS(a.idleTime, true),
180
+ userData.byDriver ? a.deviceName : a.driver
181
+ ]
182
+
183
+ data.push(temp)
184
+ })
185
+
186
+ const footValues = [
187
+ 'Total:' + d.idleEvents.length,
188
+ '',
189
+ convertMS(d.idleEvents.reduce((a, b) => a + b.idleTime, 0), true)
190
+ ]
191
+
192
+ if(userData.roadSpeedLimits){
193
+ footValues.splice(2, 0, '')
194
+ }
195
+
196
+ doc.addFileToVFS("Amiri-Regular.ttf", AmiriRegular());
197
+ doc.addFont("Amiri-Regular.ttf", "Amiri", "normal");
198
+
199
+ const style = getStyle(getUserPartner(userData.user))
200
+ doc.autoTable({
201
+ head: [headers],
202
+ body: data,
203
+ foot: [footValues],
204
+ showFoot: 'lastPage',
205
+ headStyles: {
206
+ fillColor: style.pdfHeaderColor,
207
+ textColor: style.pdfHeaderTextColor,
208
+ fontSize: 10
209
+ },
210
+ bodyStyles: {
211
+ fillColor: style.pdfBodyColor,
212
+ textColor: style.pdfBodyTextColor,
213
+ fontSize: 8,
214
+ font: timezone === 'Asia/Qatar' ? "Amiri" : ''
215
+
216
+ },
217
+ footStyles: {
218
+ fillColor: style.pdfFooterColor,
219
+ textColor: style.pdfFooterTextColor,
220
+ fontSize: 9
221
+ },
222
+ startY: space+35 });
223
+ } catch (e) {
224
+ console.error(e, 'moving on...')
225
+ }
226
+ })
227
+
228
+ return doc
229
+ }
230
+ }
231
+
232
+ function exportIdleReportToExcel(userData, reportData) {
233
+ console.log('Export to Excel')
234
+
235
+ const lang = userData.user.attributes.lang
236
+ const translations = messages[lang] ? messages[lang] : messages['en-GB']
237
+
238
+ const idleData = userData.byDriver ? reportData.drivers : reportData.devices
239
+
240
+ const settings = {
241
+ sheetName: translations.report.titleIdleReport.substring(0, 31), // The name of the sheet
242
+ fileName: fileName, // The name of the spreadsheet
243
+ }
244
+ const headers = [
245
+ userData.byDriver ? {label: translations.report.driver, value:'driver'} : {label: translations.report.vehicle, value:'name'},
246
+ {label: translations.report.date, value:'fixTime'},
247
+ {label: translations.report.address, value:'address'},
248
+ {label: translations.report.duration, value:'duration'},
249
+ userData.byDriver ? {label: translations.report.vehicle, value:'name'} : {label: translations.report.driver, value:'driver'}
250
+ ]
251
+
252
+ let data = []
253
+ if (idleData) {
254
+ idleData.forEach(d => {
255
+ data = data.concat([{}])
256
+ data = data.concat(d.idleEvents.map(a => {
257
+ return {
258
+ driver: userData.byDriver ? d.driver.name : a.driver,
259
+ duration: convertMS(a.idleTime, true),
260
+ fixTime: getIdleEventDate(a, userData.user),
261
+ name: userData.byDriver ? a.deviceName : d.device.name,
262
+ address: a.position.address + (a.geofenceName ? ' - ' + a.geofenceName : '')
263
+ }
264
+ }))
265
+ })
266
+ console.log(data)
267
+ return {
268
+ headers,
269
+ data,
270
+ settings
271
+ }
272
+ }
273
+ }
274
+
275
+ function deviceName(device){
276
+ return device.name + (device.attributes.license_plate ? ', ' +device.attributes.license_plate : '') + (device.model ? ', ' + device.model : '')
277
+ }
278
+
279
+ function getIdleEventDate(row, user) {
280
+ return convertToLocaleString(row.position.fixTime, user.attributes.lang, user.attributes.timezone)
281
+ }
282
+
283
+ exports.createIdleReport = createIdleReport;
284
+ exports.exportIdleReportToPDF = exportIdleReportToPDF;
285
+ exports.exportIdleReportToExcel = exportIdleReportToExcel;
package/src/index.js CHANGED
@@ -19,8 +19,8 @@ function Reports(config, axios) {
19
19
  byGroup: false
20
20
  }
21
21
  }
22
- this.speedingReport = (from, to, userData, roadSpeedLimits) => {
23
- return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar, roadSpeedLimits)
22
+ this.speedingReport = (from, to, userData) => {
23
+ return require('./speeding-report').createSpeedingReport(from, to, userData, this.traccar)
24
24
  }
25
25
 
26
26
  this.speedingReportToPDF = (userData, reportData) => {
@@ -124,6 +124,16 @@ function Reports(config, axios) {
124
124
  this.vistaWasteActivityReportToExcel = (userData, reportData) => {
125
125
  return require('./custom/vistawasteActivity-report').exportVistaWasteActivityReportToExcel(userData, reportData)
126
126
  }
127
+
128
+ this.idleReport = (from, to, userData) => {
129
+ return require('./idle-report').createIdleReport(from, to, userData, this.traccar)
130
+ }
131
+ this.idleReportToPDF = (userData, reportData) => {
132
+ return require('./idle-report').exportIdleReportToPDF(userData, reportData)
133
+ }
134
+ this.idleReportToExcel = (userData, reportData) => {
135
+ return require('./idle-report').exportIdleReportToExcel(userData, reportData)
136
+ }
127
137
  }
128
138
  module.exports = Reports
129
139
 
package/src/index.test.js CHANGED
@@ -1,27 +1,20 @@
1
- const Index = require('./index')
2
- const {SessionApi} = require("traccar-api");
3
- const axios = require('axios')
4
- const axiosCookieJarSupport = require('axios-cookiejar-support').default;
5
- const tough = require('tough-cookie');
6
- const cookieJar = new tough.CookieJar();
1
+ const {getReports} = require("./tests");
7
2
 
8
- axiosCookieJarSupport(axios)
3
+ describe('speedingReport', function() {
4
+ this.timeout(500000)
5
+ it('test speeding', async () => {
6
+ const report = await getReports()
7
+ const userData = await report.getUserData()
9
8
 
10
- test('speedingReport', async () => {
11
- const traccarConfig = {
12
- basePath: 'https://api.pinme.io/api',
13
- baseOptions: {
14
- withCredentials: true,
15
- jar: cookieJar
16
- }
17
- }
18
-
19
- await new SessionApi(traccarConfig, null, axios).sessionPost('-','-')
20
- const report = new Index(traccarConfig, axios)
21
- const userData = await report.getUserData()
22
-
23
- await report.speedingReport(new Date(2021, 2, 30, 0, 0, 0, 0),
24
- new Date(2021, 2, 30, 23, 59, 59, 0),
25
- userData)
26
-
27
- }, 10000)
9
+ await report.speedingReport(new Date(2021, 2, 30, 0, 0, 0, 0),
10
+ new Date(2021, 2, 30, 23, 59, 59, 0),
11
+ userData)
12
+ })
13
+ it('test kmsReport by day', async () => {
14
+ const reports = await getReports()
15
+ const userData = await reports.getUserData()
16
+ userData.groupByDay = true
17
+ await reports.kmsReport(new Date(2021, 9), new Date(2021, 10),
18
+ userData)
19
+ })
20
+ })