-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontentScript.js
More file actions
122 lines (107 loc) · 2.99 KB
/
contentScript.js
File metadata and controls
122 lines (107 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
window.addEventListener('load', () => {
const params = parseSearch(location.search)
const body = document.body
if (params.atknodetype !== 'timereg.hours') {
return
}
if (!body.querySelector('form[name=weekview]')) {
return
}
processPage(body)
})
const parseSearch = (search) => {
return search
.slice(1)
.split('&')
.map(param =>
param
.split('=')
)
.reduce((acc, [key, value]) => ({
...acc,
[key]: value
}), {})
}
const processPage = async (body) => {
const table = body.querySelector('table.recordlist')
const resultDiv = document.createElement('div')
resultDiv.innerHTML = "Hakee prosentteja..."
table.parentElement.appendChild(resultDiv)
const rows = await Array.from(table.querySelectorAll('thead th a'))
.map(element => element.href)
.map(async (href) => {
return await fetch(href, { credentials: 'include'})
.then(r => r.text())
.then(t => (new DOMParser).parseFromString(t, 'text/html'))
.then(d => parseDayPage(d.body))
})
.reduce(async (acc, p) => (await acc).concat(await p), Promise.resolve([]))
const { total, billing, training } = rows.reduce((grouped, row) => {
if (checkIfIgnore(row)) return grouped
const group = getGroup(row)
const time = grouped[group] + row.time
const total = grouped.total + row.time
return {
...grouped,
[group]: time,
total
}
}, {
total: 0,
billing: 0,
training: 0
})
resultDiv.innerHTML = `
<table class="recordlist">
<tbody>
<tr class="row1">
<td>Laskutus</td>
<td align="center">${billing}</td>
<td align="center">${toPercentage(billing / total)}%</td>
</tr>
<tr class="row2">
<td>Training</td>
<td align="center">${training}</td>
<td align="center">${toPercentage(training / total)}%</td>
</tr>
</tbody>
<tfoot>
<tr class="row1">
<th>Yhteensä</th>
<th>${total}</th>
<th></th>
</tr>
</tfoot>
</table>
`
}
const parseDayPage = (body) => {
return Array.from(body.querySelectorAll('#admin tr:not(:first-child):not(:last-child'))
.map(row => {
const [project, phase, activity,, time] = Array.from(row.querySelectorAll('td[onclick]')).map(c => c.innerText.trim())
return {
project,
phase,
activity,
time: parseTime(time)
}
})
}
const parseTime = (text) => {
const [hours, minutes] = text.split(':')
return +hours + minutes / 60
}
const toPercentage = (number) => {
return isNaN(number) ? 0 : (number*100).toFixed(2)
}
const checkIfIgnore = ({ project, phase, activity }) => {
return project === 'Sysart' &&
phase === 'Palkalliset poissaolot' &&
activity !== 'Sairasloma / hoitovapaa'
}
const getGroup = ({ project, phase, activity }) => {
if (project === 'Sysart' && phase === 'Training') {
return 'training'
}
return project === 'Sysart' ? 'waste' : 'billing'
}