fleetmap-reports 2.0.357 → 2.0.358

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.
Files changed (87) hide show
  1. package/.claude/worktrees/eager-stonebraker-c08ac7/.eslintrc.js +15 -0
  2. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/enGB.js +309 -0
  3. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/esCL.js +297 -0
  4. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/frFR.json +324 -0
  5. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/index.js +35 -0
  6. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptBR.js +301 -0
  7. package/.claude/worktrees/eager-stonebraker-c08ac7/lang/ptPT.js +310 -0
  8. package/.claude/worktrees/eager-stonebraker-c08ac7/package-lock.json +11944 -0
  9. package/.claude/worktrees/eager-stonebraker-c08ac7/package.json +45 -0
  10. package/.claude/worktrees/eager-stonebraker-c08ac7/src/activity-report.js +822 -0
  11. package/.claude/worktrees/eager-stonebraker-c08ac7/src/automaticReports.js +34 -0
  12. package/.claude/worktrees/eager-stonebraker-c08ac7/src/carbone/index.js +13 -0
  13. package/.claude/worktrees/eager-stonebraker-c08ac7/src/custom/vistawasteActivity-report.js +544 -0
  14. package/.claude/worktrees/eager-stonebraker-c08ac7/src/events-report.js +360 -0
  15. package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-consumption-report.js +296 -0
  16. package/.claude/worktrees/eager-stonebraker-c08ac7/src/fuel-drop-report.js +128 -0
  17. package/.claude/worktrees/eager-stonebraker-c08ac7/src/here.js +172 -0
  18. package/.claude/worktrees/eager-stonebraker-c08ac7/src/idle-report.js +403 -0
  19. package/.claude/worktrees/eager-stonebraker-c08ac7/src/index.js +244 -0
  20. package/.claude/worktrees/eager-stonebraker-c08ac7/src/kms-report.js +549 -0
  21. package/.claude/worktrees/eager-stonebraker-c08ac7/src/location-report.js +496 -0
  22. package/.claude/worktrees/eager-stonebraker-c08ac7/src/machines-report.js +278 -0
  23. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/afriquia.js +129 -0
  24. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/dailyuse-report.js +80 -0
  25. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/delayedstart-report.js +223 -0
  26. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/driverranking-report.js +328 -0
  27. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/gpsjump-report.js +61 -0
  28. package/.claude/worktrees/eager-stonebraker-c08ac7/src/partnerReports/performance-report.js +359 -0
  29. package/.claude/worktrees/eager-stonebraker-c08ac7/src/refueling-report.js +345 -0
  30. package/.claude/worktrees/eager-stonebraker-c08ac7/src/reportStyle.js +34 -0
  31. package/.claude/worktrees/eager-stonebraker-c08ac7/src/sensor-report.js +447 -0
  32. package/.claude/worktrees/eager-stonebraker-c08ac7/src/speeding-report.js +663 -0
  33. package/.claude/worktrees/eager-stonebraker-c08ac7/src/stop-report.js +242 -0
  34. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ActivityReportTemplate.mjml +51 -0
  35. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EmptyReportTemplate.mjml +25 -0
  36. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/EventsReportTemplate.mjml +75 -0
  37. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/FuelDropReportTemplate.mjml +60 -0
  38. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/IdleReportTemplate.mjml +54 -0
  39. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportGroupByDayTemplate.mjml +43 -0
  40. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/KmsReportTemplate.mjml +44 -0
  41. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/LocationReportTemplate.mjml +37 -0
  42. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/RefuelingReportTemplate.mjml +60 -0
  43. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SensorReportTemplate.mjml +23 -0
  44. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/SpeedingReportTemplate.mjml +80 -0
  45. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/TripReportTemplate.mjml +97 -0
  46. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/ZoneReportTemplate.mjml +52 -0
  47. package/.claude/worktrees/eager-stonebraker-c08ac7/src/templates/report.mjml +96 -0
  48. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/activity.test.js +99 -0
  49. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/carbone.test.js +20 -0
  50. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/events.test.js +30 -0
  51. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/fuel.test.js +35 -0
  52. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/idle.test.js +16 -0
  53. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.js +24 -0
  54. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/index.test.js +203 -0
  55. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/kms.test.js +74 -0
  56. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/performance.test.js +36 -0
  57. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/positions.test.js +67 -0
  58. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/speeding.test.js +120 -0
  59. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/translations.test.js +21 -0
  60. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/trips.test.js +140 -0
  61. package/.claude/worktrees/eager-stonebraker-c08ac7/src/tests/zones.test.js +162 -0
  62. package/.claude/worktrees/eager-stonebraker-c08ac7/src/trip-report.js +641 -0
  63. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/device.js +13 -0
  64. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/driver.js +90 -0
  65. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/fuel.js +102 -0
  66. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/geofence.js +52 -0
  67. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/odoo.js +18 -0
  68. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/parallel.js +64 -0
  69. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/pdfDocument.js +140 -0
  70. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/route.js +78 -0
  71. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/timetable.js +30 -0
  72. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.js +213 -0
  73. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/traccar.worker.js +49 -0
  74. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/trips.js +270 -0
  75. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/utils.js +358 -0
  76. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/worker.js +14 -0
  77. package/.claude/worktrees/eager-stonebraker-c08ac7/src/util/xpert.js +58 -0
  78. package/.claude/worktrees/eager-stonebraker-c08ac7/src/word/index.js +95 -0
  79. package/.claude/worktrees/eager-stonebraker-c08ac7/src/zone-report.js +904 -0
  80. package/lang/enGB.js +18 -0
  81. package/lang/esCL.js +18 -0
  82. package/lang/frFR.json +7 -1
  83. package/lang/ptBR.js +18 -0
  84. package/lang/ptPT.js +18 -0
  85. package/package.json +1 -1
  86. package/src/partnerReports/driverranking-report.js +149 -49
  87. package/src/util/pdfDocument.js +2 -1
@@ -0,0 +1,34 @@
1
+ const moment = require('moment')
2
+
3
+ const maxParallelRequests = 25
4
+ function sliceArray (longArray, size) {
5
+ if (!size) {
6
+ size = (longArray.length / maxParallelRequests) + 1
7
+ }
8
+ const arrayToSlice = longArray.slice()
9
+
10
+ const arrayOfArrays = []
11
+ for (let i = 0; i < arrayToSlice.length; i += size) {
12
+ arrayOfArrays.push(arrayToSlice.slice(i, i + size))
13
+ }
14
+
15
+ return arrayOfArrays
16
+ }
17
+
18
+ function deviceWithFuelInfo (device) {
19
+ return device.attributes.odooId || device.attributes.xpert ||
20
+ device.attributes.fuel_tank_capacity
21
+ }
22
+
23
+ function calculateXpertDistance (date, positions) {
24
+ const begin = moment(date, 'YYYY-MM-DD').startOf('day')
25
+ const end = moment(date, 'YYYY-MM-DD').endOf('day')
26
+ const datePositions = positions.filter(p => moment(p.fixTime).isAfter(begin) && moment(p.fixTime).isBefore(end))
27
+
28
+ return datePositions.reduce((a, b) => a + b.attributes.distance, 0)
29
+ }
30
+
31
+ exports.sliceArray = sliceArray
32
+ exports.deviceWithFuelInfo = deviceWithFuelInfo
33
+ exports.calculateXpertDistance = calculateXpertDistance
34
+ exports.maxParallelRequests = maxParallelRequests
@@ -0,0 +1,13 @@
1
+ const baseURL = 'https://api.carbone.io/render'
2
+
3
+ const axios = require('axios').create({
4
+ baseURL,
5
+ headers: {
6
+ Authorization: `Bearer ${process.env.CARBONE_API_KEY}`
7
+ }
8
+ })
9
+
10
+ exports.getPdf = async (template, body) => {
11
+ const { data } = await axios.post(template, body).then(r => r.data)
12
+ return `${baseURL}/${data.renderId}`
13
+ }
@@ -0,0 +1,544 @@
1
+ const {convertMS,coordsDistance} = require("../util/utils")
2
+ const {insideGeofence} = require("../util/geofence");
3
+ const jsPDF = require('jspdf')
4
+ require('jspdf-autotable')
5
+ const reportStyle = require("./../reportStyle")
6
+ const speeding_localidade_ligeiro = 60
7
+ const speeding_localidade_pesado = 50
8
+ const speeding_fora_localidade_ligeiro = 80
9
+ const speeding_fora_localidade_pesado = 65
10
+
11
+ let traccarInstance
12
+
13
+ async function createVistaWasteActivityReport(from, to, userData, traccar) {
14
+ console.log('Create customreport_vistawaste_activity')
15
+ traccarInstance = traccar
16
+ const reportData = {
17
+ devices: []
18
+ }
19
+
20
+ const estaleiros = [
21
+ {
22
+ "name": "ESTALEIRO KILAMBA",
23
+ "area": "POLYGON((-8.99036238 13.28504777, -8.99039417 13.28641302, -8.99115450 13.28639961, -8.99111477 13.28502631, -8.99036238 13.28504777))"
24
+ },
25
+ {
26
+ "name": "ESTALEIRO CAMAMA",
27
+ "area": "POLYGON((-8.90046068 13.25974549, -8.90163723 13.25978841, -8.90161074 13.26026047, -8.90160279 13.26074327, -8.90044479 13.26061988, -8.90046068 13.25974549))"
28
+ },
29
+ {
30
+ "name": "ESTALEIRO MORRO BENTO",
31
+ "area": "POLYGON((-8.89844343 13.18852632, -8.89869186 13.18842876, -8.89892439 13.18829900, -8.89928610 13.18797513, -8.89958024 13.18752854, -8.89836393 13.18705379, -8.89788694 13.18794428, -8.89780082 13.18811728, -8.89844343 13.18852632))"
32
+ },
33
+ {
34
+ "name": "ESTALEIRO VIANA",
35
+ "area": "POLYGON((-8.959712366859051 13.398229886846394,-8.961936865901805 13.398784062152373,-8.962332683987768 13.397008438266084,-8.960161022571128 13.396436337157951,-8.959712366859051 13.398229886846394))"
36
+ }
37
+ ]
38
+
39
+ const aterros = [
40
+ {
41
+ "name": "ATERRO MULENVOS",
42
+ "area": "POLYGON((-8.84199831467157 13.353586792945864, -8.837055409386934 13.360404968261719, -8.839133292931493 13.363355398178099, -8.844725497826346 13.367915153503418, -8.849093189309215 13.361692428588865, -8.850407727084232 13.358130455017088, -8.848955374593118 13.357014656066895, -8.847980068973513 13.356928825378414, -8.84745001048762 13.356692790985106, -8.846729129721837 13.356049060821531, -8.84594198992049 13.35538923740387, -8.845441081897903 13.35453629493713, -8.84399666076834 13.35343658924103, -8.84199831467157 13.353586792945864))"
43
+ }
44
+ ]
45
+
46
+ const localidades = [
47
+ {
48
+ "name": "LOCALIDADE LUANDA",
49
+ "area": "POLYGON((-8.955958201666093 13.138961791992184, -8.988513900385996 13.180847167968746, -8.979697020449052 13.218612670898434, -8.978340558346787 13.330535888671871, -8.985122818104188 13.404006958007809, -8.935609408774312 13.444519042968746, -8.835883944366856 13.435592651367184, -8.804671778278191 13.408813476562498, -8.756491311686318 13.389587402343748, -8.740203543653791 13.205566406249996, -8.955958201666093 13.138961791992184))"
50
+ }
51
+ ]
52
+
53
+ const devices = userData.devices
54
+ devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
55
+
56
+
57
+ let speeding_localidade = 0
58
+ let speeding_fora_localidade = 0
59
+ for (const device of devices) {
60
+
61
+ const deviceActivities = {
62
+ activities: [],
63
+ entradas_em_aterro: 0,
64
+ km: 0,
65
+ tempo_em_trabalho: 0,
66
+ tempo_em_recolha: 0,
67
+ tempo_em_aterro: 0,
68
+ tempo_em_regresso: 0,
69
+ horas_extra: 0,
70
+ tempo_excesso_localidade: 0,
71
+ tempo_excesso_fora_localidade: 0,
72
+ viagens_sem_driver: 0
73
+ }
74
+
75
+ const timer_start = new Date(Date.now())
76
+
77
+ if(device.category === 'truck') {
78
+ speeding_localidade = speeding_localidade_pesado
79
+ speeding_fora_localidade = speeding_fora_localidade_pesado
80
+ } else {
81
+ speeding_localidade = speeding_localidade_ligeiro
82
+ speeding_fora_localidade = speeding_fora_localidade_ligeiro
83
+ }
84
+
85
+ let in_estaleiro_old = undefined
86
+ let in_aterro_old
87
+ let fixtime_old
88
+ let coord_old
89
+
90
+ let service_counter = 0
91
+ let estaleiro_name = ''
92
+
93
+ let service_status = 'fora'
94
+
95
+ console.log('- Getting position List' + ' Device:' + device.id)
96
+ let response
97
+ try {
98
+ response = await traccarInstance.reports.reportsRouteGet(from, to, [device.id])
99
+ }
100
+ catch (error) {
101
+ console.log(error)
102
+ }
103
+
104
+ const position_list = response ? response.data : []
105
+
106
+ const current_activity = {}
107
+
108
+ console.log('- Analyzing route - positions:'+position_list.length)
109
+ for (let i = 0 ; i < position_list.length ; i++) {
110
+
111
+ const position = position_list[i]
112
+
113
+ //verifica se a posição está num Estaleiro
114
+ let in_estaleiro = false
115
+ for (let j = 0 ; j < estaleiros.length ; j++) {
116
+ const estaleiro = estaleiros[j]
117
+ if (insideGeofence(position, estaleiro)){
118
+ in_estaleiro = true
119
+ estaleiro_name = estaleiro['name']
120
+ break
121
+ }
122
+ }
123
+
124
+ //verifica se a posição está num Aterro
125
+ let in_aterro = false
126
+ let aterro_name = ""
127
+ for (let j = 0 ; j < aterros.length ; j++) {
128
+ const aterro = aterros[j]
129
+ if (insideGeofence(position, aterro)) {
130
+ in_aterro = true
131
+ aterro_name = aterro['name']
132
+ break
133
+ }
134
+ }
135
+
136
+ //verifica se a posição está numa Localidade
137
+ let in_localidade = false
138
+ for (let j = 0 ; j < localidades.length ; j++) {
139
+ const localidade = localidades[j]
140
+ if (insideGeofence(position, localidade)){
141
+ in_localidade = true
142
+ break
143
+ }
144
+ }
145
+
146
+ //primeira iteração
147
+ if (in_estaleiro_old === undefined) {
148
+ in_estaleiro_old = in_estaleiro
149
+ in_aterro_old = in_aterro
150
+ fixtime_old = position.fixTime
151
+ coord_old = { latitude: position.latitude, longitude: position.longitude}
152
+ }
153
+
154
+ //espera que o veículo esteja dentro do estaleiro para começar
155
+ if (service_status === 'fora' && in_estaleiro)
156
+ {
157
+ service_status = 'estaleiro'
158
+ }
159
+
160
+ let driver_da_viagem
161
+
162
+ if (service_status === 'estaleiro' && !in_estaleiro && in_estaleiro_old) {
163
+ console.log('*** Saiu do estaleiro')
164
+ service_status = 'service'
165
+ current_activity.device = device
166
+ current_activity['saida_do_estaleiro'] = position.fixTime
167
+ current_activity['estaleiro'] = estaleiro_name
168
+ current_activity['km'] = 0
169
+ current_activity['tempo_em_recolha'] = 0
170
+ current_activity['tempo_em_aterro'] = 0
171
+ current_activity['tempo_em_regresso'] = 0
172
+ current_activity['entradas_em_aterro'] = 0
173
+ current_activity['entrada_no_aterro'] = ''
174
+ current_activity['tempo_excesso_localidade'] = 0
175
+ current_activity['tempo_excesso_fora_localidade'] = 0
176
+ current_activity['motorista'] = ''
177
+ current_activity['viagens_sem_driver'] = 0
178
+ driver_da_viagem = undefined
179
+ }
180
+
181
+ const time_since_last_position = new Date(position.fixTime) - new Date(fixtime_old)
182
+ //está em serviço
183
+ if (service_status === 'service') {
184
+
185
+ const distance = coordsDistance(parseFloat(position.longitude), parseFloat(position.latitude),
186
+ parseFloat(coord_old.longitude), parseFloat(coord_old.latitude))
187
+
188
+ current_activity['km'] += distance
189
+ current_activity['tempo_em_recolha'] += time_since_last_position
190
+ current_activity['tempo_em_regresso'] += time_since_last_position
191
+ if (position['speed'] > speeding_localidade) {
192
+ current_activity['tempo_excesso_localidade'] += time_since_last_position
193
+ }
194
+ if (position['speed'] > speeding_fora_localidade) {
195
+ current_activity['tempo_excesso_fora_localidade'] += time_since_last_position
196
+ }
197
+ if (current_activity['motorista'] === "" && position['driverUniqueId'] && position['driverUniqueId'] !== "" && position['driverUniqueId'] !== "0") {
198
+ const driver = userData.drivers.find(d => d.uniqueId === position['driverUniqueId'])
199
+ current_activity['motorista'] = driver ? driver.name : ''
200
+ }
201
+ if (position['driverUniqueId'] && position['driverUniqueId'] !== "" && position['driverUniqueId'] !== "0") {
202
+ driver_da_viagem = position['driverUniqueId']
203
+ }
204
+ }
205
+
206
+ //está em aterro
207
+ if (service_status === 'aterro') {
208
+ current_activity['tempo_em_aterro'] += time_since_last_position
209
+ }
210
+
211
+ //entrou no aterro
212
+ if (service_status === 'service' && in_aterro && !in_aterro_old) {
213
+ console.log("*** Entrou no aterro")
214
+ service_status = 'aterro'
215
+
216
+ current_activity['entradas_em_aterro'] += 1
217
+
218
+ if (!current_activity['entrada_no_aterro']) {
219
+ current_activity['entrada_no_aterro'] = position.fixTime
220
+ current_activity['aterro'] = aterro_name
221
+ }
222
+ if (!driver_da_viagem) {
223
+ current_activity['viagens_sem_driver'] += 1
224
+ }
225
+ driver_da_viagem = undefined
226
+ }
227
+
228
+ //saiu do aterro
229
+ if (service_status === 'aterro' && !in_aterro && in_aterro_old)
230
+ {
231
+ console.log("*** Saiu do aterro")
232
+ service_status = 'service'
233
+ current_activity['saida_do_aterro'] = position.fixTime
234
+ current_activity['tempo_em_regresso'] = 0
235
+ }
236
+
237
+ //entrou no estaleiro
238
+ if (service_status === 'service' && in_estaleiro && !in_estaleiro_old) {
239
+ console.log("*** Entrou no estaleiro")
240
+ service_status = 'estaleiro'
241
+
242
+
243
+ //só aproveita a actividade se tiver passado num Aterro
244
+ if (current_activity.entradas_em_aterro > 0) {
245
+
246
+ current_activity['entrada_no_estaleiro'] = position.fixTime
247
+ current_activity['tempo_em_trabalho'] = (new Date(current_activity['entrada_no_estaleiro']) - new Date(current_activity['saida_do_estaleiro'])).valueOf()
248
+ current_activity['tempo_em_recolha'] = current_activity['tempo_em_recolha'] - current_activity['tempo_em_regresso']
249
+ current_activity['horas_extra'] = 0
250
+
251
+ if (new Date(current_activity['entrada_no_estaleiro']).getHours() >= 15 &&
252
+ new Date(current_activity['entrada_no_estaleiro']).getHours() < 19) {
253
+
254
+ const entrada = new Date(current_activity['entrada_no_estaleiro'])
255
+ entrada.setHours(15, 0, 0, 0)
256
+ current_activity['horas_extra'] = new Date(current_activity['entrada_no_estaleiro']) - entrada
257
+ }
258
+
259
+ if (new Date(current_activity['entrada_no_estaleiro']).getHours() >= 5 &&
260
+ new Date(current_activity['entrada_no_estaleiro']).getHours() < 7) {
261
+ const entrada = new Date(current_activity['entrada_no_estaleiro'])
262
+ entrada.setHours(5, 0, 0, 0)
263
+ current_activity['horas_extra'] = new Date(current_activity['entrada_no_estaleiro']) - entrada
264
+ }
265
+
266
+ current_activity['data'] = new Date(current_activity['saida_do_aterro']).toLocaleDateString()
267
+
268
+ if (!driver_da_viagem) {
269
+ current_activity['viagens_sem_driver'] += 1
270
+ }
271
+
272
+ service_counter += 1
273
+
274
+ deviceActivities.activities.push({ ...current_activity })
275
+
276
+ deviceActivities.entradas_em_aterro += current_activity['entradas_em_aterro']
277
+ deviceActivities.km += current_activity['km']
278
+ deviceActivities.tempo_em_trabalho += current_activity['tempo_em_trabalho']
279
+ deviceActivities.tempo_em_recolha += current_activity['tempo_em_recolha']
280
+ deviceActivities.tempo_em_aterro += current_activity['tempo_em_aterro']
281
+ deviceActivities.tempo_em_regresso += current_activity['tempo_em_regresso']
282
+ deviceActivities.horas_extra += current_activity['horas_extra']
283
+ deviceActivities.tempo_excesso_localidade += current_activity['tempo_excesso_localidade']
284
+ deviceActivities.tempo_excesso_fora_localidade += current_activity['tempo_excesso_fora_localidade']
285
+ deviceActivities.viagens_sem_driver += current_activity['viagens_sem_driver']
286
+ }
287
+ }
288
+
289
+ in_estaleiro_old = in_estaleiro
290
+ in_aterro_old = in_aterro
291
+ fixtime_old = position.fixTime
292
+
293
+ coord_old = {latitude: position.latitude, longitude: position.longitude}
294
+ }
295
+
296
+ console.log("- Analyzing route - DONE")
297
+ console.log("Handling device " + device.id + " - DONE (Events:" + service_counter + " / Duration: " + (new Date(Date.now()) - timer_start).toLocaleString() + ")")
298
+
299
+ reportData.devices = reportData.devices.concat(deviceActivities.activities)
300
+ }
301
+
302
+ //calcula as médias
303
+ if (reportData.devices.length > 0) {
304
+ reportData['entradas_em_aterro'] = reportData.devices.reduce((a, b) => a + b.entradas_em_aterro, 0) / reportData.devices
305
+ reportData['km'] = reportData.devices.reduce((a, b) => a + b.km, 0) / reportData.devices
306
+ reportData['tempo_em_trabalho'] = reportData.devices.reduce((a, b) => a + b.tempo_em_trabalho, 0) / reportData.devices
307
+ reportData['tempo_em_recolha'] = reportData.devices.reduce((a, b) => a + b.tempo_em_recolha, 0) / reportData.devices
308
+ reportData['tempo_em_aterro'] = reportData.devices.reduce((a, b) => a + b.tempo_em_aterro, 0) / reportData.devices
309
+ reportData['tempo_em_regresso'] = reportData.devices.reduce((a, b) => a + b.tempo_em_regresso, 0) / reportData.devices
310
+ reportData['horas_extra'] = reportData.devices.reduce((a, b) => a + b.horas_extra, 0) / reportData.devices
311
+ reportData['tempo_excesso_localidade'] = reportData.devices.reduce((a, b) => a + b.tempo_excesso_localidade, 0) / reportData.devices
312
+ reportData['tempo_excesso_fora_localidade'] = reportData.devices.reduce((a, b) => a + b.tempo_excesso_fora_localidade, 0) / reportData.devices
313
+ reportData['viagens_sem_driver'] = reportData.devices.reduce((a, b) => a + b.viagens_sem_driver, 0) / reportData.devices
314
+ }
315
+
316
+ return [reportData]
317
+ /*
318
+
319
+
320
+
321
+
322
+
323
+ #Formata o resultado para aparecer bem no relatório
324
+ for index, activity in enumerate(json_response['activity']):
325
+ json_response['activity'][index]['veiculo'] = json_response['activity'][index]['veiculo']
326
+ json_response['activity'][index]['motorista'] = json_response['activity'][index]['motorista']
327
+ json_response['activity'][index]['data'] = json_response['activity'][index]['data']
328
+ json_response['activity'][index]['estaleiro'] = json_response['activity'][index]['estaleiro'].replace("ESTALEIRO ", "")
329
+ json_response['activity'][index]['saida_do_estaleiro'] = json_response['activity'][index]['saida_do_estaleiro'].strftime("%H:%M")
330
+ json_response['activity'][index]['entrada_no_aterro'] = json_response['activity'][index]['entrada_no_aterro'].strftime("%H:%M")
331
+ json_response['activity'][index]['aterro'] = json_response['activity'][index]['aterro'].replace("ATERRO ", "")
332
+ json_response['activity'][index]['saida_do_aterro'] = json_response['activity'][index]['saida_do_aterro'].strftime("%H:%M")
333
+ json_response['activity'][index]['entrada_no_estaleiro'] = json_response['activity'][index]['entrada_no_estaleiro'].strftime("%H:%M")
334
+ json_response['activity'][index]['entradas_em_aterro'] = json_response['activity'][index]['entradas_em_aterro']
335
+ json_response['activity'][index]['km'] = round(json_response['activity'][index]['km'] / 1000, 1)
336
+ json_response['activity'][index]['tempo_em_trabalho'] = common.get_hm(json_response['activity'][index]['tempo_em_trabalho'])
337
+ json_response['activity'][index]['tempo_em_recolha'] = common.get_hm(json_response['activity'][index]['tempo_em_recolha'])
338
+ json_response['activity'][index]['tempo_em_aterro'] = common.get_hm(json_response['activity'][index]['tempo_em_aterro'])
339
+ json_response['activity'][index]['tempo_em_regresso'] = common.get_hm(json_response['activity'][index]['tempo_em_regresso'])
340
+ json_response['activity'][index]['horas_extra'] = common.get_hm(json_response['activity'][index]['horas_extra'])
341
+ json_response['activity'][index]['tempo_excesso_localidade'] = common.get_hm(json_response['activity'][index]['tempo_excesso_localidade'])
342
+ json_response['activity'][index]['tempo_excesso_fora_localidade'] = common.get_hm(json_response['activity'][index]['tempo_excesso_fora_localidade'])
343
+ json_response['activity'][index]['viagens_sem_driver'] = json_response['activity'][index]['viagens_sem_driver']
344
+
345
+ if len(json_response['activity']) > 0:
346
+ json_response['activity_sum']['km'] = round(json_response['activity_sum']['km'] / 1000, 1)
347
+ json_response['activity_sum']['tempo_em_trabalho'] = common.get_hm(json_response['activity_sum']['tempo_em_trabalho'])
348
+ json_response['activity_sum']['tempo_em_recolha'] = common.get_hm(json_response['activity_sum']['tempo_em_recolha'])
349
+ json_response['activity_sum']['tempo_em_aterro'] = common.get_hm(json_response['activity_sum']['tempo_em_aterro'])
350
+ json_response['activity_sum']['tempo_em_regresso'] = common.get_hm(json_response['activity_sum']['tempo_em_regresso'])
351
+ json_response['activity_sum']['horas_extra'] = common.get_hm(json_response['activity_sum']['horas_extra'])
352
+ json_response['activity_sum']['tempo_excesso_localidade'] = common.get_hm(json_response['activity_sum']['tempo_excesso_localidade'])
353
+ json_response['activity_sum']['tempo_excesso_fora_localidade'] = common.get_hm(json_response['activity_sum']['tempo_excesso_fora_localidade'])
354
+ json_response['activity_sum']['viagens_sem_driver'] = json_response['activity_sum']['viagens_sem_driver']
355
+
356
+ json_response['activity_avg']['entradas_em_aterro'] = round(json_response['activity_avg']['entradas_em_aterro'], 1)
357
+ json_response['activity_avg']['km'] = round(json_response['activity_avg']['km'] / 1000, 1)
358
+ json_response['activity_avg']['tempo_em_trabalho'] = common.get_hm(json_response['activity_avg']['tempo_em_trabalho'])
359
+ json_response['activity_avg']['tempo_em_recolha'] = common.get_hm(json_response['activity_avg']['tempo_em_recolha'])
360
+ json_response['activity_avg']['tempo_em_aterro'] = common.get_hm(json_response['activity_avg']['tempo_em_aterro'])
361
+ json_response['activity_avg']['tempo_em_regresso'] = common.get_hm(json_response['activity_avg']['tempo_em_regresso'])
362
+ json_response['activity_avg']['horas_extra'] = common.get_hm(json_response['activity_avg']['horas_extra'])
363
+ json_response['activity_avg']['tempo_excesso_localidade'] = common.get_hm(json_response['activity_avg']['tempo_excesso_localidade'])
364
+ json_response['activity_avg']['tempo_excesso_fora_localidade'] = common.get_hm(json_response['activity_avg']['tempo_excesso_fora_localidade'])
365
+ json_response['activity_avg']['viagens_sem_driver'] = round(json_response['activity_avg']['viagens_sem_driver'], 1)
366
+ else:
367
+ json_response['activity_sum'] = []
368
+ json_response['activity_avg'] = []
369
+
370
+ if len(json_response['activity']) == 0:
371
+ json_response['server_message'] = common.language_strings['common'][user_language]['no_data']
372
+ json_response['server_render'] = True
373
+
374
+ return json_response*/
375
+ }
376
+
377
+ function exportVistaWasteActivityReportToPDF(userData, reportData){
378
+ console.log('Export to PDF')
379
+
380
+ const headers = [
381
+ 'Veículo',
382
+ 'Matrícula',
383
+ 'Grupo',
384
+ 'Data',
385
+ 'Estaleiro',
386
+ 'Entrada Estaleiro',
387
+ 'Saída Estaleiro',
388
+ 'Aterro',
389
+ 'Entrada Aterro',
390
+ 'Saída Aterro',
391
+ 'Entradas Aterro',
392
+ 'Kms',
393
+ 'Tempo Trabalho',
394
+ 'Tempo Recolha',
395
+ 'Tempo Aterro',
396
+ 'Tempo Regresso',
397
+ 'Horas Extra',
398
+ 'Vel. Dentro Localidades',
399
+ 'Vel. Fora Localidades',
400
+ 'Viagens sem Motorista'
401
+ ]
402
+
403
+ const doc = new jsPDF.jsPDF('l');
404
+ doc.setFontSize(14)
405
+ doc.text('Relatório de Actividade VistaWaste', 15, 15 )
406
+
407
+ let data = []
408
+ reportData.devices.forEach(d => {
409
+ try {
410
+ const group = userData.groups.find(g => d.device.groupId === g.id)
411
+
412
+ const temp = [
413
+ d.device.name,
414
+ d.device.attributes.license_plate,
415
+ group ? group.name : '',
416
+ d.data,
417
+ d.estaleiro.replace('ESTALEIRO ', ''),
418
+ new Date(d.entrada_no_estaleiro).toLocaleTimeString(),
419
+ new Date(d.saida_do_estaleiro).toLocaleTimeString(),
420
+ d.aterro.replace('ATERRO ', ''),
421
+ new Date(d.entrada_no_aterro).toLocaleTimeString(),
422
+ new Date(d.saida_do_aterro).toLocaleTimeString(),
423
+ d.entradas_em_aterro,
424
+ (d.km/1000).toFixed(1),
425
+ convertMS(d.tempo_em_trabalho),
426
+ convertMS(d.tempo_em_recolha),
427
+ convertMS(d.tempo_em_aterro),
428
+ convertMS(d.tempo_em_regresso),
429
+ convertMS(d.horas_extra),
430
+ convertMS(d.tempo_excesso_localidade),
431
+ convertMS(d.tempo_excesso_fora_localidade),
432
+ d.viagens_sem_driver
433
+ ]
434
+
435
+ data.push(temp)
436
+
437
+ } catch (e) {
438
+ console.error(e, 'moving on...')
439
+ }
440
+ })
441
+
442
+ const footValues = [
443
+ 'Total:' + reportData.devices.length,
444
+ '',
445
+ '',
446
+ '',
447
+ '',
448
+ ''
449
+ ]
450
+
451
+ doc.autoTable({
452
+ head: [headers],
453
+ body: data,
454
+ foot: [footValues],
455
+ showFoot: 'lastPage',
456
+ headStyles: {
457
+ fillColor: reportStyle.pdfHeaderColor,
458
+ textColor: reportStyle.pdfHeaderTextColor,
459
+ fontSize: 7,
460
+ },
461
+ bodyStyles: {
462
+ fillColor: reportStyle.pdfBodyColor,
463
+ textColor: reportStyle.pdfBodyTextColor,
464
+ fontSize: 6,
465
+ },
466
+ footStyles: {
467
+ fillColor: reportStyle.pdfFooterColor,
468
+ textColor: reportStyle.pdfFooterTextColor
469
+ },
470
+ startY: 25 });
471
+
472
+ return doc
473
+ }
474
+
475
+ function exportVistaWasteActivityReportToExcel(userData, reportData){
476
+ console.log('Export to Excel')
477
+
478
+ const settings = {
479
+ sheetName: 'Relatório Actividade VistaWaste', // The name of the sheet
480
+ fileName: 'actividade_vistawaste' // The name of the spreadsheet
481
+ }
482
+
483
+ const headers = [
484
+ {label: 'Veículo', value: 'veiculo'},
485
+ {label: 'Matrícula', value: 'matricula'},
486
+ {label: 'Grupo', value: 'grupo'},
487
+ {label: 'Data', value: 'data'},
488
+ {label: 'Estaleiro', value: 'estaleiro'},
489
+ {label: 'Entrada Estaleiro', value: 'entrada_estaleiro'},
490
+ {label: 'Saída Estaleiro', value: 'saida_estaleiro'},
491
+ {label: 'Aterro', value: 'aterro'},
492
+ {label: 'Entrada Aterro', value: 'entrada_aterro'},
493
+ {label: 'Saída Aterro', value: 'saida_aterro'},
494
+ {label: 'Entradas Aterro', value: 'entradas_aterro'},
495
+ {label: 'Kms', value: 'kms'},
496
+ {label: 'Tempo Trabalho', value: 'tempo_trabalho'},
497
+ {label: 'Tempo Recolha', value: 'tempo_recolha'},
498
+ {label: 'Tempo Aterro', value: 'tempo_aterro'},
499
+ {label: 'Tempo Regresso', value: 'tempo_regresso'},
500
+ {label: 'Horas Extra', value: 'horas_extra'},
501
+ {label: 'Vel. Dentro Localidades', value: 'vel_dentro_localidade'},
502
+ {label: 'Vel. Fora Localidades', value: 'vel_fora_localidade'},
503
+ {label: 'Viagens sem Motorista', value: 'viagens_sem_motorista'}
504
+ ]
505
+
506
+ let data = []
507
+
508
+ reportData.devices.forEach(d => {
509
+ const group = userData.groups.find(g => d.device.groupId === g.id)
510
+
511
+ data = data.concat([{
512
+ veiculo: d.device.name,
513
+ matricula: d.device.attributes.license_plate,
514
+ grupo: group ? group.name : '',
515
+ data: d.data,
516
+ estaleiro: d.estaleiro.replace('ESTALEIRO ', ''),
517
+ entrada_estaleiro: new Date(d.entrada_no_estaleiro).toLocaleTimeString(),
518
+ saida_estaleiro: new Date(d.saida_do_estaleiro).toLocaleTimeString(),
519
+ aterro: d.aterro.replace('ATERRO ', ''),
520
+ entrada_aterro: new Date(d.entrada_no_aterro).toLocaleTimeString(),
521
+ saida_aterro: new Date(d.saida_do_aterro).toLocaleTimeString(),
522
+ entradas_aterro: d.entradas_em_aterro,
523
+ kms: (d.km/1000).toFixed(1),
524
+ tempo_trabalho: convertMS(d.tempo_em_trabalho),
525
+ tempo_recolha: convertMS(d.tempo_em_recolha),
526
+ tempo_aterro: convertMS(d.tempo_em_aterro),
527
+ tempo_regresso: convertMS(d.tempo_em_regresso),
528
+ horas_extra: convertMS(d.horas_extra),
529
+ vel_dentro_localidade: convertMS(d.tempo_excesso_localidade),
530
+ vel_fora_localidade: convertMS(d.tempo_excesso_fora_localidade),
531
+ viagens_sem_motorista: d.viagens_sem_driver
532
+ }])
533
+ })
534
+ console.log(data)
535
+ return {
536
+ headers,
537
+ data,
538
+ settings
539
+ }
540
+ }
541
+
542
+ exports.createVistaWasteActivityReport = createVistaWasteActivityReport;
543
+ exports.exportVistaWasteActivityReportToPDF = exportVistaWasteActivityReportToPDF;
544
+ exports.exportVistaWasteActivityReportToExcel = exportVistaWasteActivityReportToExcel;