improvements and fixes
This commit is contained in:
parent
996efe5421
commit
c2b3152a01
6 changed files with 58 additions and 8 deletions
|
@ -7,9 +7,10 @@ simple workday recording with a basic rest api
|
||||||
|
|
||||||
| method | url | arguments | description |
|
| method | url | arguments | description |
|
||||||
| ------ | --- | --------- | ----------- |
|
| ------ | --- | --------- | ----------- |
|
||||||
| `get` | /csv| from=DD.MM.YYYY<br>to=DD.MM.YYYY | get recordings (in range) as csv |
|
| `get` | /csv| from=DD.MM.YYYY<br>to=DD.MM.YYYY | get recordings (for specified range) as csv |
|
||||||
| `get` | /json| from=DD.MM.YYYY<br>to=DD.MM.YYYY | get recordings (in range) as json |
|
| `get` | /json| from=DD.MM.YYYY<br>to=DD.MM.YYYY | get recordings (for specified range) as json |
|
||||||
| `get` | /today | | get aggregated recordings for today as json (if any) |
|
| `get` | /today | | get aggregated recordings for today as json (if any) |
|
||||||
|
| `get` | /overtime | | get aggregated overtime (for specified range) |
|
||||||
| `post` | /start | | start a new recording |
|
| `post` | /start | | start a new recording |
|
||||||
| `post` | /stop | | stop the current recording (if any) |
|
| `post` | /stop | | stop the current recording (if any) |
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ report:
|
||||||
- "Pause-Beginn"
|
- "Pause-Beginn"
|
||||||
- "Pause-Ende"
|
- "Pause-Ende"
|
||||||
- "Pause-Dauer"
|
- "Pause-Dauer"
|
||||||
|
- "Saldo"
|
||||||
|
|
||||||
users:
|
users:
|
||||||
exampleuser:
|
exampleuser:
|
||||||
|
|
|
@ -30,7 +30,7 @@ func handleRequests(writer http.ResponseWriter, request *http.Request) {
|
||||||
requestMethod := strings.ToLower(request.Method)
|
requestMethod := strings.ToLower(request.Method)
|
||||||
user, authorized := isAuthorized(request)
|
user, authorized := isAuthorized(request)
|
||||||
if !authorized {
|
if !authorized {
|
||||||
log.Info("denying unauthorized '"+requestMethod+"' request", "path: "+requestPath)
|
log.Info("denying unauthorized '"+requestMethod+"' request", "path: '"+requestPath+"'")
|
||||||
writer.WriteHeader(404)
|
writer.WriteHeader(404)
|
||||||
writer.Write([]byte("error: basic authorization failed\n"))
|
writer.Write([]byte("error: basic authorization failed\n"))
|
||||||
return
|
return
|
||||||
|
@ -43,10 +43,10 @@ func handleRequests(writer http.ResponseWriter, request *http.Request) {
|
||||||
handled = handlePost(user, writer, request)
|
handled = handlePost(user, writer, request)
|
||||||
}
|
}
|
||||||
if handled {
|
if handled {
|
||||||
log.Debug("handled '"+requestMethod+"' request", "path: "+requestPath, "user: "+user)
|
log.Debug("handled '"+requestMethod+"' request", "path: '"+requestPath+"'", "user: '"+user+"'")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("ignoring '"+requestMethod+"' request", "path: "+requestPath, "user: "+user)
|
log.Debug("ignoring '"+requestMethod+"' request", "path: '"+requestPath+"'", "user: '"+user+"'")
|
||||||
writer.WriteHeader(501)
|
writer.WriteHeader(501)
|
||||||
writer.Write([]byte("error: endpoint '" + requestPath + "' not implemented\n"))
|
writer.Write([]byte("error: endpoint '" + requestPath + "' not implemented\n"))
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,15 @@ func handleGet(user string, writer http.ResponseWriter, request *http.Request) b
|
||||||
}
|
}
|
||||||
writer.WriteHeader(200)
|
writer.WriteHeader(200)
|
||||||
writer.Write([]byte(json + "\n"))
|
writer.Write([]byte(json + "\n"))
|
||||||
|
case "/overtime":
|
||||||
|
from, to := getTimespan(request.URL.Query())
|
||||||
|
overtime := workday.GetOvertime(from, to, user)
|
||||||
|
if len(overtime) == 0 {
|
||||||
|
writer.WriteHeader(404)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
writer.WriteHeader(200)
|
||||||
|
writer.Write([]byte(overtime + "\n"))
|
||||||
case "/json":
|
case "/json":
|
||||||
from, to := getTimespan(request.URL.Query())
|
from, to := getTimespan(request.URL.Query())
|
||||||
json, error := workday.ToJSON(from, to, user)
|
json, error := workday.ToJSON(from, to, user)
|
||||||
|
|
|
@ -3,4 +3,4 @@ package tools
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
var ZeroDate = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
|
var ZeroDate = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
var ReportHeaders = []string{"date", "workday start", "workday end", "workday duration", "pause start", "pause end", "pause duration"}
|
var ReportHeaders = []string{"date", "workday start", "workday end", "workday duration", "pause start", "pause end", "pause duration", "balance"}
|
||||||
|
|
|
@ -48,6 +48,11 @@ func TimeToHHMMSS(time time.Time) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DurationToHHMMSS(duration time.Duration) string {
|
func DurationToHHMMSS(duration time.Duration) string {
|
||||||
|
negative := false
|
||||||
|
if duration < 0 {
|
||||||
|
duration = duration * -1
|
||||||
|
negative = true
|
||||||
|
}
|
||||||
durationSeconds := duration.Seconds()
|
durationSeconds := duration.Seconds()
|
||||||
durationHours := int(durationSeconds / 3600)
|
durationHours := int(durationSeconds / 3600)
|
||||||
if durationHours > 0 {
|
if durationHours > 0 {
|
||||||
|
@ -71,6 +76,9 @@ func DurationToHHMMSS(duration time.Duration) string {
|
||||||
for len(tmpDuration) < 8 {
|
for len(tmpDuration) < 8 {
|
||||||
tmpDuration = "0" + tmpDuration
|
tmpDuration = "0" + tmpDuration
|
||||||
}
|
}
|
||||||
|
if negative {
|
||||||
|
tmpDuration = "-" + tmpDuration
|
||||||
|
}
|
||||||
return tmpDuration
|
return tmpDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ func ToCSV(from time.Time, to time.Time, user string) string {
|
||||||
tools.DurationToHHMMSS(workday.Duration) + ";" +
|
tools.DurationToHHMMSS(workday.Duration) + ";" +
|
||||||
tools.TimeToHHMMSS(workday.Pause.Start) + ";" +
|
tools.TimeToHHMMSS(workday.Pause.Start) + ";" +
|
||||||
tools.TimeToHHMMSS(workday.Pause.Stop) + ";" +
|
tools.TimeToHHMMSS(workday.Pause.Stop) + ";" +
|
||||||
tools.DurationToHHMMSS(workday.Pause.Duration)
|
tools.DurationToHHMMSS(workday.Pause.Duration) + ";" +
|
||||||
|
tools.DurationToHHMMSS(workday.Balance)
|
||||||
}
|
}
|
||||||
return report
|
return report
|
||||||
}
|
}
|
||||||
|
@ -50,6 +51,9 @@ func ToJSON(from time.Time, to time.Time, user string) (string, error) {
|
||||||
}
|
}
|
||||||
workdayJson.Pause = pauseJson
|
workdayJson.Pause = pauseJson
|
||||||
}
|
}
|
||||||
|
if !workday.isOpen() {
|
||||||
|
workdayJson.Balance = tools.DurationToHHMMSS(workday.Balance)
|
||||||
|
}
|
||||||
jsonWorkdays = append(jsonWorkdays, workdayJson)
|
jsonWorkdays = append(jsonWorkdays, workdayJson)
|
||||||
}
|
}
|
||||||
bytes, error := json.Marshal(jsonWorkdays)
|
bytes, error := json.Marshal(jsonWorkdays)
|
||||||
|
@ -73,10 +77,25 @@ func (workday *Workday) ToJSON(user string) (string, error) {
|
||||||
}
|
}
|
||||||
workdayJson.Pause = pauseJson
|
workdayJson.Pause = pauseJson
|
||||||
}
|
}
|
||||||
|
if !workday.isOpen() {
|
||||||
|
workdayJson.Balance = tools.DurationToHHMMSS(workday.Balance)
|
||||||
|
}
|
||||||
bytes, error := json.Marshal(workdayJson)
|
bytes, error := json.Marshal(workdayJson)
|
||||||
return string(bytes), error
|
return string(bytes), error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetOvertime(from time.Time, to time.Time, user string) string {
|
||||||
|
workdays := getInRange(from, to, user)
|
||||||
|
if len(workdays) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var overtime time.Duration
|
||||||
|
for _, workday := range workdays {
|
||||||
|
overtime += workday.Balance
|
||||||
|
}
|
||||||
|
return tools.DurationToHHMMSS(overtime)
|
||||||
|
}
|
||||||
|
|
||||||
func GetToday(user string) (Workday, error) {
|
func GetToday(user string) (Workday, error) {
|
||||||
var workday Workday
|
var workday Workday
|
||||||
firstTimestamp := database.GetFirstTimestamp(user, time.Now())
|
firstTimestamp := database.GetFirstTimestamp(user, time.Now())
|
||||||
|
@ -94,6 +113,7 @@ func GetToday(user string) (Workday, error) {
|
||||||
} else {
|
} else {
|
||||||
workday.Duration = workday.Stop.Sub(workday.Start)
|
workday.Duration = workday.Stop.Sub(workday.Start)
|
||||||
}
|
}
|
||||||
|
workday.Balance = workday.Duration - time.Hour*8
|
||||||
return workday, nil
|
return workday, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +155,7 @@ func aggregatedTimestampsToWorkdays(aggregatedTimestamps map[string][]database.T
|
||||||
Start: tmpStart,
|
Start: tmpStart,
|
||||||
Stop: tmpEnd,
|
Stop: tmpEnd,
|
||||||
Duration: duration,
|
Duration: duration,
|
||||||
|
Balance: duration - time.Hour*8,
|
||||||
}
|
}
|
||||||
workday.insertFakePause()
|
workday.insertFakePause()
|
||||||
workdays = append(workdays, workday)
|
workdays = append(workdays, workday)
|
||||||
|
@ -154,13 +175,21 @@ func (workday *Workday) isOpen() bool {
|
||||||
return workday.Stop == tools.ZeroDate
|
return workday.Stop == tools.ZeroDate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (workday *Workday) calculateBalance() {
|
||||||
|
workday.Balance = workday.Duration - time.Hour*8
|
||||||
|
}
|
||||||
|
|
||||||
func (workday *Workday) insertFakePause() {
|
func (workday *Workday) insertFakePause() {
|
||||||
var pause Pause
|
var pause Pause
|
||||||
|
pauseLength := time.Minute * 30
|
||||||
|
if workday.Duration.Hours() >= 10 {
|
||||||
|
pauseLength = time.Minute * 60
|
||||||
|
}
|
||||||
deviationStart := rand.Intn(15-(-15)) + (-15)
|
deviationStart := rand.Intn(15-(-15)) + (-15)
|
||||||
pause.Start = workday.Start.Add(workday.Duration / 2)
|
pause.Start = workday.Start.Add(workday.Duration / 2)
|
||||||
pause.Start = pause.Start.Add(time.Minute * time.Duration(deviationStart))
|
pause.Start = pause.Start.Add(time.Minute * time.Duration(deviationStart))
|
||||||
deviationEnd := rand.Intn(300)
|
deviationEnd := rand.Intn(300)
|
||||||
pause.Stop = pause.Start.Add(time.Minute * 30).Add(time.Second * time.Duration(deviationEnd))
|
pause.Stop = pause.Start.Add(pauseLength).Add(time.Second * time.Duration(deviationEnd))
|
||||||
pause.Duration = pause.Stop.Sub(pause.Start)
|
pause.Duration = pause.Stop.Sub(pause.Start)
|
||||||
workday.Pause = pause
|
workday.Pause = pause
|
||||||
workday.Stop = workday.Stop.Add(workday.Pause.Duration)
|
workday.Stop = workday.Stop.Add(workday.Pause.Duration)
|
||||||
|
@ -173,6 +202,7 @@ type Workday struct {
|
||||||
Stop time.Time
|
Stop time.Time
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
Pause Pause
|
Pause Pause
|
||||||
|
Balance time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pause struct {
|
type Pause struct {
|
||||||
|
@ -189,6 +219,7 @@ type workdayJson struct {
|
||||||
Duration string
|
Duration string
|
||||||
Open bool
|
Open bool
|
||||||
Pause pauseJson
|
Pause pauseJson
|
||||||
|
Balance string
|
||||||
}
|
}
|
||||||
|
|
||||||
type pauseJson struct {
|
type pauseJson struct {
|
||||||
|
|
Loading…
Reference in a new issue