dev/ui #35
47
Backend/models/booking_test.go
Normal file
47
Backend/models/booking_test.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package models_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"arbeitszeitmessung/models"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testBookingType = models.BookingType{
|
||||||
|
Id: 1,
|
||||||
|
Name: "Büro",
|
||||||
|
}
|
||||||
|
|
||||||
|
var testBookings8hrs = []models.Booking{models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 1,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}, models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 2,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 16:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}}
|
||||||
|
|
||||||
|
var testBookings6hrs = []models.Booking{models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 1,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}, models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 2,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 14:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}}
|
||||||
|
|
||||||
|
var testBookings10hrs = []models.Booking{models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 1,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}, models.Booking{
|
||||||
|
CardUID: "aaaa-aaaa",
|
||||||
|
CheckInOut: 2,
|
||||||
|
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 18:00")),
|
||||||
|
BookingType: testBookingType,
|
||||||
|
}}
|
||||||
@@ -19,7 +19,7 @@ type WorkDay struct {
|
|||||||
Absence Absence
|
Absence Absence
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay {
|
func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
|
||||||
var workDays []WorkDay
|
var workDays []WorkDay
|
||||||
var workSec, pauseSec float64
|
var workSec, pauseSec float64
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ ORDER BY d.work_date ASC;`)
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer qStr.Close()
|
defer qStr.Close()
|
||||||
rows, err := qStr.Query(card_uid, tsFrom, tsTo)
|
rows, err := qStr.Query(user.CardUID, tsFrom, tsTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error getting rows!")
|
log.Println("Error getting rows!")
|
||||||
return workDays
|
return workDays
|
||||||
@@ -125,21 +125,20 @@ ORDER BY d.work_date ASC;`)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if absenceType.Valid {
|
if absenceType.Valid {
|
||||||
workDay.Absence, err = NewAbsence(card_uid, int(absenceType.Int16), workDay.Day)
|
workDay.Absence, err = NewAbsence(user.CardUID, int(absenceType.Int16), workDay.Day)
|
||||||
// log.Println("Found absence", workDay.Absence)
|
workDay.CalcRealWorkTime(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if workDay.Day.Equal(time.Now().Truncate(24 * time.Hour)) {
|
if workDay.Day.Equal(time.Now().Truncate(24 * time.Hour)) {
|
||||||
workDay.getWorkTime()
|
workDay.CalcRealWorkTime(user)
|
||||||
|
workDay.CalcWorkPauseDiff(user)
|
||||||
} else {
|
} else {
|
||||||
workDay.calcPauseTime()
|
workDay.CalcWorkPauseDiff(user)
|
||||||
}
|
}
|
||||||
if emptyDays && workDay.Day.Weekday() >= 1 && workDay.Day.Weekday() <= 5 {
|
if emptyDays && workDay.Day.Weekday() >= 1 && workDay.Day.Weekday() <= 5 {
|
||||||
workDays = append(workDays, workDay)
|
workDays = append(workDays, workDay)
|
||||||
} else if len(workDay.Bookings) > 0 || (workDay.Absence != Absence{}) {
|
} else if len(workDay.Bookings) > 0 || (workDay.Absence != Absence{}) {
|
||||||
workDays = append(workDays, workDay)
|
workDays = append(workDays, workDay)
|
||||||
// } else {
|
|
||||||
// log.Println("no booking on day", workDay.Day.Format("02.01.2006"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
@@ -148,45 +147,56 @@ ORDER BY d.work_date ASC;`)
|
|||||||
return workDays
|
return workDays
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WorkDay) calcPauseTime() {
|
func (d *WorkDay) CalcWorkPauseDiff(user User) (work, pause time.Duration) {
|
||||||
if d.workTime > 6*time.Hour && d.pauseTime < 45*time.Minute {
|
if d.workTime == 0 {
|
||||||
if d.workTime <= (9*time.Hour) && d.pauseTime < 30*time.Minute {
|
d.CalcRealWorkTime(user)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if d.Absence.AbwesenheitTyp.WorkTime > 0 {
|
||||||
|
return d.workTime, d.pauseTime
|
||||||
|
}
|
||||||
|
if d.workTime <= 6*time.Hour || d.pauseTime > 45*time.Minute {
|
||||||
|
return d.workTime, d.pauseTime
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.workTime, d.pauseTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the duration someone worked that day
|
func (d *WorkDay) CalcRealWorkTime(user User) time.Duration {
|
||||||
func (d *WorkDay) getWorkTime() {
|
if (len(d.Bookings) < 1 && d.Absence == Absence{}) {
|
||||||
if len(d.Bookings) < 1 {
|
return 0
|
||||||
return
|
|
||||||
}
|
}
|
||||||
var workTime, pauseTime time.Duration
|
var realWorkTime, realPauseTime time.Duration
|
||||||
var lastBooking Booking
|
var lastBooking Booking
|
||||||
for _, booking := range d.Bookings {
|
for _, booking := range d.Bookings {
|
||||||
if booking.CheckInOut%2 == 1 {
|
if booking.CheckInOut%2 == 1 {
|
||||||
if !lastBooking.Timestamp.IsZero() {
|
if !lastBooking.Timestamp.IsZero() {
|
||||||
pauseTime += booking.Timestamp.Sub(lastBooking.Timestamp)
|
realPauseTime += booking.Timestamp.Sub(lastBooking.Timestamp)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
workTime += booking.Timestamp.Sub(lastBooking.Timestamp)
|
realWorkTime += booking.Timestamp.Sub(lastBooking.Timestamp)
|
||||||
}
|
}
|
||||||
lastBooking = booking
|
lastBooking = booking
|
||||||
}
|
}
|
||||||
// checks if booking is today and has no gehen yet, so the time since last kommen booking is added to workTime
|
if helper.IsSameDate(d.Day, time.Now()) && len(d.Bookings)%2 == 1 {
|
||||||
if d.Day.Day() == time.Now().Day() && len(d.Bookings)%2 == 1 {
|
realWorkTime += time.Since(lastBooking.Timestamp.Local())
|
||||||
workTime += time.Since(lastBooking.Timestamp.Local())
|
|
||||||
}
|
}
|
||||||
d.workTime = workTime
|
if d.Absence.AbwesenheitTyp.WorkTime > 0 {
|
||||||
d.pauseTime = pauseTime
|
realWorkTime = time.Duration(user.ArbeitszeitPerTag * float32(time.Hour)).Round(time.Minute)
|
||||||
|
log.Println("Rewriting worktime", realWorkTime)
|
||||||
|
}
|
||||||
|
d.workTime = realWorkTime
|
||||||
|
d.pauseTime = realPauseTime
|
||||||
|
|
||||||
d.calcPauseTime()
|
return realWorkTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WorkDay) GetWorkTimeString() (work string, pause string) {
|
func (d *WorkDay) GetWorkTimeString() (work string, pause string) {
|
||||||
@@ -195,6 +205,10 @@ func (d *WorkDay) GetWorkTimeString() (work string, pause string) {
|
|||||||
return workString, pauseString
|
return workString, pauseString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *WorkDay) GetAllWorkTimes(user User) (work, pause, overtime time.Duration) {
|
||||||
|
return d.workTime.Round(time.Minute), d.pauseTime.Round(time.Minute), d.CalcOvertime(user)
|
||||||
|
}
|
||||||
|
|
||||||
// returns bool wheter the workday was ended with an automatic logout
|
// returns bool wheter the workday was ended with an automatic logout
|
||||||
func (d *WorkDay) RequiresAction() bool {
|
func (d *WorkDay) RequiresAction() bool {
|
||||||
if len(d.Bookings) == 0 {
|
if len(d.Bookings) == 0 {
|
||||||
@@ -211,15 +225,13 @@ func (d *WorkDay) GetWorkDayProgress(user User) uint8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *WorkDay) CalcOvertime(user User) time.Duration {
|
func (d *WorkDay) CalcOvertime(user User) time.Duration {
|
||||||
|
if d.workTime == 0 {
|
||||||
|
d.CalcWorkPauseDiff(user)
|
||||||
|
}
|
||||||
if helper.IsWeekend(d.Day) && len(d.Bookings) == 0 {
|
if helper.IsWeekend(d.Day) && len(d.Bookings) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
var overtime time.Duration
|
var overtime time.Duration
|
||||||
overtime = d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute)
|
overtime = d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute)
|
||||||
// weekday is WE
|
|
||||||
if (d.Absence != Absence{}) {
|
|
||||||
overtime = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return overtime
|
return overtime
|
||||||
}
|
}
|
||||||
|
|||||||
82
Backend/models/workDay_test.go
Normal file
82
Backend/models/workDay_test.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package models_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"arbeitszeitmessung/helper"
|
||||||
|
"arbeitszeitmessung/models"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CatchError[T any](val T, err error) T {
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
var testWorkDay = models.WorkDay{
|
||||||
|
Day: CatchError(time.Parse("2006-01-02", "2025-01-01")),
|
||||||
|
Bookings: testBookings8hrs,
|
||||||
|
TimeFrom: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
|
||||||
|
TimeTo: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 16:30")),
|
||||||
|
Absence: models.Absence{},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalcRealWorkTime(t *testing.T) {
|
||||||
|
workTime := testWorkDay.CalcRealWorkTime(testUser)
|
||||||
|
if workTime != time.Hour*8 {
|
||||||
|
t.Errorf("Calc Worktime Default not working, time should be 8h, but was %s", helper.FormatDuration(workTime))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalcWorkPauseDiff(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
Name string
|
||||||
|
bookings []models.Booking
|
||||||
|
expectedWorkTime time.Duration
|
||||||
|
expectedPauseTime time.Duration
|
||||||
|
expectedOvertime time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{testCase{
|
||||||
|
Name: "6hrs no pause",
|
||||||
|
bookings: testBookings6hrs,
|
||||||
|
expectedWorkTime: 6 * time.Hour,
|
||||||
|
expectedPauseTime: 0,
|
||||||
|
expectedOvertime: -2 * time.Hour,
|
||||||
|
},
|
||||||
|
testCase{
|
||||||
|
Name: "8hrs - 30min pause",
|
||||||
|
bookings: testBookings8hrs,
|
||||||
|
expectedWorkTime: 7*time.Hour + 30*time.Minute,
|
||||||
|
expectedPauseTime: 30 * time.Minute,
|
||||||
|
expectedOvertime: -30 * time.Minute,
|
||||||
|
},
|
||||||
|
testCase{
|
||||||
|
Name: "10hrs - 45min pause",
|
||||||
|
bookings: testBookings10hrs,
|
||||||
|
expectedWorkTime: 9*time.Hour + 15*time.Minute,
|
||||||
|
expectedPauseTime: 45 * time.Minute,
|
||||||
|
expectedOvertime: 1*time.Hour + 15*time.Minute,
|
||||||
|
}}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.Name, func(t *testing.T) {
|
||||||
|
testWorkDay.Bookings = test.bookings
|
||||||
|
testWorkDay.CalcRealWorkTime(testUser)
|
||||||
|
testWorkDay.CalcWorkPauseDiff(testUser)
|
||||||
|
testWorkDay.CalcOvertime(testUser)
|
||||||
|
workTime, pauseTime, overTime := testWorkDay.GetAllWorkTimes(testUser)
|
||||||
|
if workTime != test.expectedWorkTime {
|
||||||
|
t.Errorf("Calculated wrong workTime: should be %s, but was %s", helper.FormatDuration(test.expectedWorkTime), helper.FormatDuration(workTime))
|
||||||
|
}
|
||||||
|
if pauseTime != test.expectedPauseTime {
|
||||||
|
t.Errorf("Calculated wrong pauseTime: should be %s, but was %s", helper.FormatDuration(test.expectedPauseTime), helper.FormatDuration(pauseTime))
|
||||||
|
}
|
||||||
|
if overTime != test.expectedOvertime {
|
||||||
|
t.Errorf("Calculated wrong overtime: should be %s, but was %s", helper.FormatDuration(test.expectedOvertime), helper.FormatDuration(overTime))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user