CHANGE: added team view, with submitted bookings for team members and send form for own bookings
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"arbeitszeitmessung/helper"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/alexedwards/scs/v2"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
@@ -138,7 +144,26 @@ func (u *User) ChangePass(password, newPassword string) (bool, error) {
|
||||
|
||||
func (u *User) GetTeamMembers() ([]User, error) {
|
||||
var teamMembers []User
|
||||
teamMembers = append(teamMembers, *u)
|
||||
qStr, err := DB.Prepare(`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM personal_daten WHERE vorgesetzter_pers_nr = $1`)
|
||||
if err != nil {
|
||||
return teamMembers, err
|
||||
}
|
||||
defer qStr.Close()
|
||||
rows, err := qStr.Query(u.PersonalNummer)
|
||||
if err != nil {
|
||||
log.Println("Error getting rows!")
|
||||
return teamMembers, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
user, err := parseUser(rows)
|
||||
if err != nil {
|
||||
log.Println("Error parsing user!")
|
||||
return teamMembers, err
|
||||
}
|
||||
teamMembers = append(teamMembers, user)
|
||||
}
|
||||
|
||||
return teamMembers, nil
|
||||
}
|
||||
|
||||
@@ -159,3 +184,27 @@ func (u *User) GetNextWeek() WorkWeek {
|
||||
return week
|
||||
|
||||
}
|
||||
|
||||
func parseUser(rows *sql.Rows) (User, error) {
|
||||
var user User
|
||||
if err := rows.Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.Arbeitszeit); err != nil {
|
||||
log.Println("Error scanning row!", err)
|
||||
return user, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (u *User) GetLastSubmission() time.Time {
|
||||
var lastSub time.Time
|
||||
qStr, err := DB.Prepare("SELECT woche_start FROM buchung_wochen WHERE personal_nummer = $1 ORDER BY woche_start DESC LIMIT 1")
|
||||
if err != nil {
|
||||
log.Println("Error preparing statement!", err)
|
||||
return lastSub
|
||||
}
|
||||
err = qStr.QueryRow(u.PersonalNummer).Scan(&lastSub)
|
||||
if err != nil {
|
||||
log.Println("Error executing query!", err)
|
||||
return lastSub
|
||||
}
|
||||
return lastSub
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -12,8 +13,102 @@ type WorkDay struct {
|
||||
pauseTime time.Duration
|
||||
}
|
||||
|
||||
func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay {
|
||||
var workDays []WorkDay
|
||||
var workSec, pauseSec float64
|
||||
qStr, err := DB.Prepare(`
|
||||
WITH ordered_bookings AS (
|
||||
SELECT
|
||||
timestamp::DATE AS work_date, -- Extract date for grouping
|
||||
timestamp,
|
||||
check_in_out,
|
||||
LAG(timestamp) OVER (
|
||||
PARTITION BY card_uid, timestamp::DATE -- Reset for each day
|
||||
ORDER BY timestamp
|
||||
) AS prev_timestamp,
|
||||
LAG(check_in_out) OVER (
|
||||
PARTITION BY card_uid, timestamp::DATE
|
||||
ORDER BY timestamp
|
||||
) AS prev_check
|
||||
FROM anwesenheit
|
||||
WHERE card_uid = $1 -- Replace with actual card_uid
|
||||
AND timestamp::DATE >= $2 -- Set date range
|
||||
AND timestamp::DATE <= $3
|
||||
)
|
||||
SELECT
|
||||
work_date,
|
||||
|
||||
-- Total work time per day
|
||||
COALESCE(
|
||||
EXTRACT(EPOCH FROM SUM(
|
||||
CASE
|
||||
WHEN prev_check IN (1, 3) AND check_in_out IN (2, 4, 254)
|
||||
THEN timestamp - prev_timestamp
|
||||
ELSE INTERVAL '0'
|
||||
END
|
||||
)), 0
|
||||
) AS total_work,
|
||||
|
||||
-- Extract total pause time in seconds
|
||||
COALESCE(
|
||||
EXTRACT(EPOCH FROM SUM(
|
||||
CASE
|
||||
WHEN prev_check IN (2, 4, 254) AND check_in_out IN (1, 3)
|
||||
THEN timestamp - prev_timestamp
|
||||
ELSE INTERVAL '0'
|
||||
END
|
||||
)), 0
|
||||
) AS total_pause
|
||||
|
||||
FROM ordered_bookings
|
||||
GROUP BY work_date
|
||||
ORDER BY work_date;`)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error preparing SQL statement", err)
|
||||
return workDays
|
||||
}
|
||||
|
||||
defer qStr.Close()
|
||||
rows, err := qStr.Query(card_uid, tsFrom, tsTo)
|
||||
if err != nil {
|
||||
log.Println("Error getting rows!")
|
||||
return workDays
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var workDay WorkDay
|
||||
if err := rows.Scan(&workDay.Day, &workSec, &pauseSec); err != nil {
|
||||
log.Println("Error scanning row!", err)
|
||||
return workDays
|
||||
}
|
||||
workDay.workTime = time.Duration(workSec * float64(time.Second))
|
||||
workDay.pauseTime = time.Duration(pauseSec * float64(time.Second))
|
||||
workDay.calcPauseTime()
|
||||
workDays = append(workDays, workDay)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return workDays
|
||||
}
|
||||
return workDays
|
||||
}
|
||||
|
||||
func (d *WorkDay) calcPauseTime() {
|
||||
if d.workTime > 6*time.Hour && d.pauseTime < 45*time.Minute {
|
||||
if d.workTime < 9*time.Hour && d.pauseTime < 30*time.Minute {
|
||||
diff := 30*time.Minute - d.pauseTime
|
||||
d.workTime -= diff
|
||||
d.pauseTime += diff
|
||||
} else if d.pauseTime < 45*time.Minute {
|
||||
diff := 45*time.Minute - d.pauseTime
|
||||
d.workTime -= diff
|
||||
d.pauseTime += diff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the duration someone worked that day
|
||||
func (d *WorkDay) GetWorkTime() time.Duration {
|
||||
func (d *WorkDay) GetWorkTime() {
|
||||
var workTime, pauseTime time.Duration
|
||||
var lastBooking Booking
|
||||
for _, booking := range d.Bookings {
|
||||
@@ -30,26 +125,15 @@ func (d *WorkDay) GetWorkTime() time.Duration {
|
||||
if d.Day.Day() == time.Now().Day() && len(d.Bookings)%2 == 1 {
|
||||
workTime += time.Since(lastBooking.Timestamp.Local())
|
||||
}
|
||||
|
||||
if workTime > 6*time.Hour && pauseTime < 45*time.Minute {
|
||||
if workTime < 9*time.Hour && pauseTime < 30*time.Minute {
|
||||
diff := 30*time.Minute - pauseTime
|
||||
workTime -= diff
|
||||
pauseTime += diff
|
||||
} else if pauseTime < 45*time.Minute {
|
||||
diff := 45*time.Minute - pauseTime
|
||||
workTime -= diff
|
||||
pauseTime += diff
|
||||
}
|
||||
}
|
||||
d.workTime = workTime
|
||||
d.pauseTime = pauseTime
|
||||
return workTime
|
||||
|
||||
d.calcPauseTime()
|
||||
}
|
||||
|
||||
func formatDuration(d time.Duration) string {
|
||||
hours := int(d.Hours())
|
||||
minutes := int(d.Minutes()) % 60
|
||||
hours := int(d.Abs().Hours())
|
||||
minutes := int(d.Abs().Minutes()) % 60
|
||||
switch {
|
||||
case hours > 0:
|
||||
return fmt.Sprintf("%dh %dmin", hours, minutes)
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WorkWeek struct {
|
||||
WorkDays []WorkDay
|
||||
WorkDays []WorkDay
|
||||
User User
|
||||
WeekStart time.Time
|
||||
}
|
||||
|
||||
func (w *WorkWeek) GetWeek(user User, tsMonday time.Time) WorkWeek {
|
||||
var week WorkWeek
|
||||
week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour))
|
||||
week.User = user
|
||||
week.WeekStart = tsMonday
|
||||
return week
|
||||
}
|
||||
|
||||
func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek {
|
||||
var weeks []WorkWeek
|
||||
qStr, err := DB.Prepare(`SELECT woche_start::DATE FROM buchung_wochen WHERE bestaetigt = FALSE AND personal_nummer = $1;`)
|
||||
if err != nil {
|
||||
log.Println("Error preparing SQL statement", err)
|
||||
return weeks
|
||||
}
|
||||
defer qStr.Close()
|
||||
|
||||
rows, err := qStr.Query(user.PersonalNummer)
|
||||
if err != nil {
|
||||
log.Println("Error querining db!", err)
|
||||
return weeks
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var week WorkWeek
|
||||
week.User = user
|
||||
if err := rows.Scan(&week.WeekStart); err != nil {
|
||||
log.Println("Error scanning row!", err)
|
||||
return weeks
|
||||
}
|
||||
week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, week.WeekStart, week.WeekStart.Add(7*24*time.Hour))
|
||||
weeks = append(weeks, week)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return weeks
|
||||
}
|
||||
|
||||
return weeks
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user