fleetmap-reports 1.0.209 → 1.0.213

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,19 +1,12 @@
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 getStyle">
4
+ <list default="true" id="eb665c86-c893-4333-bd2a-721dc27980b9" name="Changes" comment="try catch on pdf addImage">
5
5
  <change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
6
6
  <change beforePath="$PROJECT_DIR$/src/activity-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/activity-report.js" afterDir="false" />
7
- <change beforePath="$PROJECT_DIR$/src/events-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/events-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" />
9
8
  <change beforePath="$PROJECT_DIR$/src/kms-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/kms-report.js" afterDir="false" />
10
- <change beforePath="$PROJECT_DIR$/src/location-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/location-report.js" afterDir="false" />
11
- <change beforePath="$PROJECT_DIR$/src/reportStyle.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/reportStyle.js" afterDir="false" />
12
- <change beforePath="$PROJECT_DIR$/src/speeding-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/speeding-report.js" afterDir="false" />
13
- <change beforePath="$PROJECT_DIR$/src/trip-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/trip-report.js" afterDir="false" />
14
9
  <change beforePath="$PROJECT_DIR$/src/util/pdfDocument.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/util/pdfDocument.js" afterDir="false" />
15
- <change beforePath="$PROJECT_DIR$/src/util/utils.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/util/utils.js" afterDir="false" />
16
- <change beforePath="$PROJECT_DIR$/src/zone-report.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/zone-report.js" afterDir="false" />
17
10
  </list>
18
11
  <option name="SHOW_DIALOG" value="false" />
19
12
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -145,7 +138,12 @@
145
138
  <workItem from="1636647112207" duration="1748000" />
146
139
  <workItem from="1636981640447" duration="4315000" />
147
140
  <workItem from="1637009407292" duration="1470000" />
148
- <workItem from="1637012863006" duration="4019000" />
141
+ <workItem from="1637012863006" duration="5376000" />
142
+ <workItem from="1637087797229" duration="5701000" />
143
+ <workItem from="1637227826845" duration="1275000" />
144
+ <workItem from="1637441942952" duration="4543000" />
145
+ <workItem from="1637670815688" duration="2973000" />
146
+ <workItem from="1637674107929" duration="9187000" />
149
147
  </task>
150
148
  <task id="LOCAL-00001" summary="Fix getStyle">
151
149
  <created>1636983717385</created>
@@ -154,7 +152,21 @@
154
152
  <option name="project" value="LOCAL" />
155
153
  <updated>1636983717385</updated>
156
154
  </task>
157
- <option name="localTasksCounter" value="2" />
155
+ <task id="LOCAL-00002" summary="Fix getStyle in all reports">
156
+ <created>1637020728356</created>
157
+ <option name="number" value="00002" />
158
+ <option name="presentableId" value="LOCAL-00002" />
159
+ <option name="project" value="LOCAL" />
160
+ <updated>1637020728356</updated>
161
+ </task>
162
+ <task id="LOCAL-00003" summary="try catch on pdf addImage">
163
+ <created>1637247013210</created>
164
+ <option name="number" value="00003" />
165
+ <option name="presentableId" value="LOCAL-00003" />
166
+ <option name="project" value="LOCAL" />
167
+ <updated>1637247013211</updated>
168
+ </task>
169
+ <option name="localTasksCounter" value="4" />
158
170
  <servers />
159
171
  </component>
160
172
  <component name="TypeScriptGeneratedFilesManager">
@@ -174,6 +186,8 @@
174
186
  </component>
175
187
  <component name="VcsManagerConfiguration">
176
188
  <MESSAGE value="Fix getStyle" />
177
- <option name="LAST_COMMIT_MESSAGE" value="Fix getStyle" />
189
+ <MESSAGE value="Fix getStyle in all reports" />
190
+ <MESSAGE value="try catch on pdf addImage" />
191
+ <option name="LAST_COMMIT_MESSAGE" value="try catch on pdf addImage" />
178
192
  </component>
179
193
  </project>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.209",
3
+ "version": "1.0.213",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -71,18 +71,18 @@ async function createActivityReportByGroup(from, to, userData){
71
71
 
72
72
  async function createActivityReportByDevice(from, to, userData){
73
73
  const groupIds = userData.groups.map(g => g.id)
74
- const withoutGroupDevices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
74
+ const devicesToProcess = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
75
75
 
76
76
  const allData = {
77
77
  devices: [],
78
- xpert: withoutGroupDevices.filter(d => d.attributes.xpert).length > 0,
78
+ xpert: devicesToProcess.filter(d => d.attributes.xpert).length > 0,
79
79
  from: from,
80
80
  to: to
81
81
  }
82
82
 
83
- withoutGroupDevices.sort((a, b) => (a.name > b.name) ? 1 : -1)
84
- const devicesToSlice = withoutGroupDevices.slice()
85
-
83
+ //Get report data from traccar
84
+ devicesToProcess.sort((a, b) => (a.name > b.name) ? 1 : -1)
85
+ const devicesToSlice = devicesToProcess.slice()
86
86
  const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
87
87
  let data = []
88
88
  let trips = []
@@ -96,12 +96,11 @@ async function createActivityReportByDevice(from, to, userData){
96
96
 
97
97
  console.log('Summary:' + data.length)
98
98
 
99
- if (data.length === 0) {
100
- return allData
99
+ //Process report data
100
+ if (data.length > 0) {
101
+ allData.devices = processDevices(devicesToProcess, data, trips)
101
102
  }
102
103
 
103
- allData.devices = processDevices(withoutGroupDevices, data, trips)
104
-
105
104
  return allData
106
105
  }
107
106
 
package/src/index.test.js CHANGED
@@ -23,14 +23,21 @@ describe('test reports', function() {
23
23
  await new SessionApi(traccarConfig, null, axios).sessionPost('jppenas@gmail.com', 'penas46881')
24
24
  const report = new Index(traccarConfig, axios)
25
25
  const userData = await report.getUserData()
26
-
27
- const reportData = await report.tripReport(new Date(2021, 2, 30, 0, 0, 0, 0),
28
- new Date(2021, 2, 30, 23, 59, 59, 0),
26
+ userData.groupByDay = true
27
+ const reportData = await report.kmsReport(new Date(2021, 10, 19, 0, 0, 0, 0),
28
+ new Date(2021, 10, 21, 23, 59, 59, 0),
29
29
  userData)
30
30
 
31
- console.log(reportData)
31
+ const reportResult = reportData[0]
32
+ reportResult.devices.forEach(d => {
33
+ console.log(d.device.name)
34
+ d.days.forEach(day => {
35
+ console.log(day.date + ' - ' + day.kms)
36
+ })
37
+ })
38
+
32
39
 
33
- const pdf = report.tripReportToPDF(userData, reportData)
40
+ const pdf = report.kmsReportToExcel(userData, reportResult)
34
41
 
35
42
  console.log(pdf)
36
43
  })
package/src/kms-report.js CHANGED
@@ -3,26 +3,123 @@ const messages = require('../lang')
3
3
  const jsPDF = require('jspdf')
4
4
  require('jspdf-autotable')
5
5
  const {getStyle} = require("./reportStyle");
6
- const {headerFromUser} = require("./util/pdfDocument");
6
+ const {headerFromUser,addTable} = require("./util/pdfDocument");
7
7
  const {getUserPartner} = require("fleetmap-partners");
8
+ const automaticReports = require("./automaticReports");
9
+ const {convertMS} = require("./util/utils");
8
10
 
9
11
 
10
12
  let traccarInstance
11
13
 
12
14
  const fileName = 'KmsReport'
13
15
 
16
+ async function createKmsReportByDevice(from, to, userData) {
17
+ const groupIds = userData.groups.map(g => g.id)
18
+ const devicesToProcess = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
19
+
20
+ const allData = {
21
+ devices: []
22
+ }
23
+
24
+ devicesToProcess.sort((a, b) => (a.name > b.name) ? 1 : -1)
25
+ const devicesToSlice = devicesToProcess.slice()
26
+
27
+ const arrayOfArrays = automaticReports.sliceArray(devicesToSlice)
28
+ let data = []
29
+ for (const a of arrayOfArrays) {
30
+ const response = await traccarInstance.reports.reportsRouteGet(from, to, a.map(d => d.id))
31
+ data = data.concat(response.data)
32
+ }
33
+
34
+ console.log('locations:' + data.length)
35
+
36
+ if (data.length > 0) {
37
+ allData.devices = processDevices(from, to, devicesToProcess, data)
38
+ }
39
+
40
+ return allData
41
+ }
42
+
43
+ async function createKmsReportByDriver(from, to, userData) {
44
+
45
+ }
46
+
47
+ async function createKmsReportByGroup(from, to, userData) {
48
+
49
+ }
50
+
51
+ function processDevices(from, to, devices, data) {
52
+ const devicesResult = []
53
+
54
+ for (const d of devices) {
55
+ const locations = data.filter(t => t.deviceId === d.id)
56
+
57
+ if (locations.length > 0) {
58
+ locations.forEach(l => l.locationDate = l.fixTime.substring(0, 10))
59
+ const groupedLocations = locations.reduce(
60
+ (entryMap, e) => entryMap.set(e.locationDate, [...entryMap.get(e.locationDate)||[], e]),
61
+ new Map()
62
+ )
63
+
64
+ const days = []
65
+ const keys = Array.from(groupedLocations.keys())
66
+
67
+ keys.forEach(key => {
68
+ const dayLocations = groupedLocations.get(key)
69
+ const day = {
70
+ date: key,
71
+ kms: dayLocations.reduce((a, b) => a + b.attributes.distance, 0)
72
+ }
73
+ days.push(day)
74
+ })
75
+
76
+ devicesResult.push({
77
+ device: d,
78
+ days: days
79
+ })
80
+ }
81
+ }
82
+
83
+ return devicesResult
84
+ }
85
+
14
86
  async function createKmsReport(from, to, userData, traccar) {
15
87
  console.log('Create KmsReport')
16
88
  traccarInstance = traccar
17
- return await createActivityReport(from, to, userData, traccar)
89
+ if(userData.groupByDay){
90
+ const reportData = []
91
+
92
+ if(userData.byDriver){
93
+ const allData = await createKmsReportByDriver(from, to, userData)
94
+ reportData.push(allData)
95
+ }
96
+ else if(userData.byGroup){
97
+ const allGroupsData = await createKmsReportByGroup(from, to, userData)
98
+ allGroupsData.forEach(data => reportData.push(data))
99
+ const withoutGroupDevices = await createKmsReportByDevice(from, to, userData)
100
+ reportData.push(withoutGroupDevices)
101
+ } else {
102
+ const allData = await createKmsReportByDevice(from, to, userData)
103
+ reportData.push(allData)
104
+ }
105
+
106
+ return reportData
107
+ } else {
108
+ return await createActivityReport(from, to, userData, traccar)
109
+ }
18
110
  }
19
111
 
20
112
  async function exportKmsReportToPDF(userData, reportData) {
21
113
  const lang = userData.user.attributes.lang
22
114
  const translations = messages[lang] ? messages[lang] : messages['en-GB']
115
+ const kmsData = userData.byDriver ? reportData.drivers : reportData.devices
23
116
 
24
117
  const headers = []
25
- if(userData.byDriver) {
118
+ if(userData.groupByDay) {
119
+ headers.push(translations.report.date,
120
+ translations.report.distance)
121
+ }
122
+ else if(userData.byDriver) {
26
123
  headers.push(translations.report.driver,
27
124
  translations.report.group,
28
125
  translations.report.distance)
@@ -32,78 +129,82 @@ async function exportKmsReportToPDF(userData, reportData) {
32
129
  translations.report.group,
33
130
  translations.report.distance)
34
131
  }
35
- if (reportData.devices || reportData.drivers) {
36
- const doc = new jsPDF.jsPDF('l');
132
+ if (kmsData) {
133
+ const doc = userData.groupByDay ? new jsPDF.jsPDF() : new jsPDF.jsPDF('l')
37
134
  await headerFromUser(doc, translations.report.titleSpeedingReport, userData.user)
38
135
 
39
- let data = []
40
- doc.setFontSize(10)
41
- doc.text(new Date(reportData.from).toLocaleString() + ' - ' + new Date(reportData.to).toLocaleString(), 20, 30 )
42
- if(userData.byDriver) {
43
- reportData.drivers.forEach(d => {
44
- const group = userData.groups.find(g => g.drivers.includes(d.driver.id))
136
+ if (userData.groupByDay) {
137
+ for (const d of kmsData) {
138
+ const name = userData.byDriver ? d.driver.name : deviceName(d.device)
139
+ const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.id)) : userData.groups.find(g => d.device.groupId === g.id)
140
+
141
+ let space = 0
142
+ if (!first) {
143
+ doc.addPage()
144
+ } else {
145
+ first = false
146
+ space = 8
147
+ }
148
+ doc.setFontSize(13)
149
+ doc.text(name, 20, space + 20)
150
+ doc.setFontSize(11)
151
+ doc.text(group ? translations.report.group + ': ' + group.name : '', 200, space + 20)
152
+ doc.text(new Date(d.from).toLocaleString() + ' - ' + new Date(d.to).toLocaleString(), 20, space + 25)
45
153
 
154
+ const data = []
46
155
  const temp = [
47
156
  d.driver.name,
48
157
  group ? group.name : '',
49
158
  Number((d.summary.distance / 1000).toFixed(0)),
50
159
  ]
51
160
  data.push(temp)
52
- })
161
+ }
53
162
  } else {
54
- reportData.devices.forEach(d => {
55
- const group = userData.groups.find(g => d.device.groupId === g.id)
163
+ if (userData.byDriver) {
164
+ reportData.drivers.forEach(d => {
165
+ const group = userData.groups.find(g => g.drivers.includes(d.driver.id))
56
166
 
57
- const temp = [
58
- d.summary.deviceName,
59
- d.device.model,
60
- group ? group.name : '',
61
- Number((d.summary.distance / 1000).toFixed(0))
62
- ]
63
- data.push(temp)
64
- })
65
- }
167
+ const temp = [
168
+ d.driver.name,
169
+ group ? group.name : '',
170
+ Number((d.summary.distance / 1000).toFixed(0)),
171
+ ]
172
+ data.push(temp)
173
+ })
174
+ } else {
175
+ reportData.devices.forEach(d => {
176
+ const group = userData.groups.find(g => d.device.groupId === g.id)
66
177
 
67
- const footValues = []
68
- if(userData.byDriver) {
69
- footValues.push(
70
- 'Total:' + reportData.drivers.length,
71
- '',
72
- (reportData.drivers.reduce((a, b) => a + b.summary.distance, 0)/1000).toFixed(0)
73
- )
74
- } else {
75
- footValues.push(
76
- 'Total:' + reportData.devices.length,
77
- '',
78
- '',
79
- (reportData.devices.reduce((a, b) => a + b.summary.distance, 0)/1000).toFixed(0),
80
- )
81
- }
178
+ const temp = [
179
+ d.summary.deviceName,
180
+ d.device.model,
181
+ group ? group.name : '',
182
+ Number((d.summary.distance / 1000).toFixed(0))
183
+ ]
184
+ data.push(temp)
185
+ })
186
+ }
82
187
 
83
- const style = getStyle(getUserPartner(userData.user))
84
- doc.autoTable({
85
- head: [headers],
86
- body: data,
87
- foot: [footValues],
88
- showFoot: 'lastPage',
89
- headStyles: {
90
- fillColor: style.pdfHeaderColor,
91
- textColor: style.pdfHeaderTextColor,
92
- fontSize: 10
93
- },
94
- bodyStyles: {
95
- fillColor: style.pdfBodyColor,
96
- textColor: style.pdfBodyTextColor,
97
- fontSize: 8
98
- },
99
- footStyles: {
100
- fillColor: style.pdfFooterColor,
101
- textColor: style.pdfFooterTextColor,
102
- fontSize: 9
103
- },
104
- startY: 35 });
105
-
106
- return doc
188
+ const footValues = []
189
+ if(userData.byDriver) {
190
+ footValues.push(
191
+ 'Total:' + reportData.drivers.length,
192
+ '',
193
+ (reportData.drivers.reduce((a, b) => a + b.summary.distance, 0)/1000).toFixed(0)
194
+ )
195
+ } else {
196
+ footValues.push(
197
+ 'Total:' + reportData.devices.length,
198
+ '',
199
+ '',
200
+ (reportData.devices.reduce((a, b) => a + b.summary.distance, 0)/1000).toFixed(0),
201
+ )
202
+ }
203
+
204
+ const style = getStyle(getUserPartner(userData.user))
205
+
206
+ return addTable(doc, headers, data, footValues, style, 35)
207
+ }
107
208
  }
108
209
  }
109
210
 
@@ -120,55 +221,48 @@ function exportKmsReportToExcel(userData, reportData) {
120
221
 
121
222
  const headers = []
122
223
 
123
- if(userData.byDriver) {
224
+ if(userData.groupByDay){
124
225
  headers.push(
125
- {label: translations.report.driver, value: 'driver'},
226
+ {label: translations.report.vehicle, value: 'name'},
126
227
  {label: translations.report.group, value: 'group'},
228
+ {label: translations.report.date, value: 'date'},
127
229
  {label: translations.report.distance, value: 'distance'})
128
- } else {
230
+ } else if(userData.byDriver) {
129
231
  headers.push(
130
- {label: translations.report.vehicle, value: 'name'},
232
+ {label: translations.report.driver, value: 'name'},
131
233
  {label: translations.report.group, value: 'group'},
132
234
  {label: translations.report.distance, value: 'distance'})
133
235
  }
134
236
 
135
237
  let data = []
136
- if(userData.byDriver){
137
- if (reportData.drivers) {
138
- reportData.drivers.forEach(d => {
139
- const group = userData.groups.find(g => g.drivers.includes(d.driver.id))
238
+ const info = userData.byDriver ? reportData.drivers : reportData.devices
239
+ info.forEach(d => {
240
+ const group = userData.byDriver ? userData.groups.find(g => g.drivers.includes(d.driver.id)) :
241
+ userData.groups.find(g => d.device.groupId === g.id)
140
242
 
243
+ if(userData.groupByDay) {
244
+ data = data.concat([{}])
245
+ data = data.concat(d.days.map(a => {
246
+ return {
247
+ name: userData.byDriver ? d.driver.name : d.device.name,
248
+ group: group ? group.name : '',
249
+ date: a.date,
250
+ distance: Number((a.kms / 1000).toFixed(0))
251
+ }
252
+ }))
253
+ } else {
141
254
  data = data.concat([{
142
- driver: d.driver.name,
255
+ name: userData.byDriver ? d.driver.name : d.summary.deviceName,
143
256
  group: group ? group.name : '',
144
257
  distance: Number((d.summary.distance / 1000).toFixed(0))
145
258
  }])
146
- })
147
- console.log(data)
148
- return {
149
- headers,
150
- data,
151
- settings
152
259
  }
153
- }
154
- } else {
155
- if (reportData.devices) {
156
- reportData.devices.forEach(d => {
157
- const group = userData.groups.find(g => d.device.groupId === g.id)
260
+ })
158
261
 
159
- data = data.concat([{
160
- name: d.summary.deviceName,
161
- group: group ? group.name : '',
162
- distance: Number((d.summary.distance / 1000).toFixed(0))
163
- }])
164
- })
165
- console.log(data)
166
- return {
167
- headers,
168
- data,
169
- settings
170
- }
171
- }
262
+ return {
263
+ headers,
264
+ data,
265
+ settings
172
266
  }
173
267
  }
174
268
 
@@ -1,3 +1,4 @@
1
+ require('jspdf-autotable')
1
2
  const {getStyle} = require("../reportStyle");
2
3
  const {getUserPartner} = require("fleetmap-partners");
3
4
  const {getImgFromUrl} = require("./utils")
@@ -8,9 +9,12 @@ async function header(doc, title, hostname, style) {
8
9
  doc.text(title, 15, 15 )
9
10
 
10
11
  if(style.imgWidth && style.imgHeight) {
11
- const image = await getImgFromUrl(hostname)
12
- if(image){
13
- doc.addImage(image, 'PNG', 220 + (style.imgWidth < 50 ? 25 : 0), 5, style.imgWidth, style.imgHeight)
12
+ try{
13
+ const image = await getImgFromUrl(hostname)
14
+ if(image){
15
+ doc.addImage(image, 'PNG', 220 + (style.imgWidth < 50 ? 25 : 0), 5, style.imgWidth, style.imgHeight)
16
+ }
17
+ } catch (e) {
14
18
  }
15
19
  }
16
20
  doc.setFont('helvetica', 'normal')
@@ -21,5 +25,30 @@ async function headerFromUser(doc, title, user) {
21
25
  return header(doc, title, partner.host, getStyle(partner))
22
26
  }
23
27
 
28
+ function addTable(doc, headers, data, footValues, style, startY){
29
+ doc.autoTable({
30
+ head: [headers],
31
+ body: data,
32
+ foot: [footValues],
33
+ showFoot: 'lastPage',
34
+ headStyles: {
35
+ fillColor: style.pdfHeaderColor,
36
+ textColor: style.pdfHeaderTextColor,
37
+ fontSize: 10
38
+ },
39
+ bodyStyles: {
40
+ fillColor: style.pdfBodyColor,
41
+ textColor: style.pdfBodyTextColor,
42
+ fontSize: 8
43
+ },
44
+ footStyles: {
45
+ fillColor: style.pdfFooterColor,
46
+ textColor: style.pdfFooterTextColor,
47
+ fontSize: 9
48
+ },
49
+ startY: startY });
50
+ }
51
+
24
52
  exports.header = header
25
53
  exports.headerFromUser = headerFromUser
54
+ exports.addTable = addTable
package/src/util/utils.js CHANGED
@@ -35,12 +35,8 @@ async function getImgFromUrl(hostname) {
35
35
  img.src = '/img/logos/' + hostname + '.png'
36
36
  return img
37
37
  } catch (e) {
38
- try{
39
- const response = await axios.get('https://' + hostname + '/img/logos/' + hostname + '.png', { responseType: 'arraybuffer' })
40
- return Buffer.from(response.data, 'binary').toString('base64')
41
- } catch (e) {
42
- return null
43
- }
38
+ const response = await axios.get('https://' + hostname + '/img/logos/' + hostname + '.png', { responseType: 'arraybuffer' })
39
+ return Buffer.from(response.data, 'binary').toString('base64')
44
40
  }
45
41
  }
46
42