added worktime base to work time calculations
Some checks failed
Tests / Run Go Tests (push) Failing after 1m4s
Some checks failed
Tests / Run Go Tests (push) Failing after 1m4s
This commit is contained in:
@@ -20,7 +20,7 @@ func convertDaysToTypst(days []models.IWorkDay, u models.User) ([]typstDay, erro
|
||||
var typstDays []typstDay
|
||||
for _, day := range days {
|
||||
var thisTypstDay typstDay
|
||||
work, pause, overtime := day.GetAllWorkTimesVirtual(u)
|
||||
work, pause, overtime := day.GetTimesVirtual(u, models.WorktimeBaseWeek)
|
||||
thisTypstDay.Date = day.Date().Format(DE_DATE)
|
||||
thisTypstDay.Worktime = helper.FormatDurationFill(work, true)
|
||||
thisTypstDay.Pausetime = helper.FormatDurationFill(pause, true)
|
||||
@@ -129,6 +129,8 @@ func createEmployeReport(employee models.User, startDate, endDate time.Time) (by
|
||||
targetHours := (employee.ArbeitszeitProWoche() / 5) * time.Duration(helper.GetWorkingDays(startDate, endDate))
|
||||
workingDays := models.GetDays(employee, startDate, endDate, false)
|
||||
|
||||
slog.Debug("Baseline Working hours", "targetHours", targetHours.Hours())
|
||||
|
||||
var actualHours time.Duration
|
||||
for _, day := range workingDays {
|
||||
actualHours += day.TimeWorkVirtual(employee)
|
||||
|
||||
@@ -31,6 +31,7 @@ func FormatDuration(d time.Duration) string {
|
||||
|
||||
// Converts duration to string
|
||||
func FormatDurationFill(d time.Duration, fill bool) string {
|
||||
return fmt.Sprintf("%.1f", d.Hours())
|
||||
hours := int(d.Abs().Hours())
|
||||
minutes := int(d.Abs().Minutes()) % 60
|
||||
sign := ""
|
||||
|
||||
@@ -49,6 +49,55 @@ func (a *Absence) IsMultiDay() bool {
|
||||
return !a.DateFrom.Equal(a.DateTo)
|
||||
}
|
||||
|
||||
func (a *Absence) GetWorktimeReal(u User, base WorktimeBase) time.Duration {
|
||||
if a.AbwesenheitTyp.WorkTime <= 1 {
|
||||
return 0
|
||||
}
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
return u.ArbeitszeitProTag()
|
||||
case WorktimeBaseWeek:
|
||||
return u.ArbeitszeitProWoche() / 5
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (a *Absence) GetPausetimeReal(u User, base WorktimeBase) time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (a *Absence) GetOvertimeReal(u User, base WorktimeBase) time.Duration {
|
||||
if a.AbwesenheitTyp.WorkTime > 1 {
|
||||
return 0
|
||||
}
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
return -u.ArbeitszeitProTag()
|
||||
case WorktimeBaseWeek:
|
||||
return -u.ArbeitszeitProWoche() / 5
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (a *Absence) GetWorktimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
return a.GetWorktimeReal(u, base)
|
||||
}
|
||||
|
||||
func (a *Absence) GetPausetimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
return a.GetPausetimeReal(u, base)
|
||||
}
|
||||
|
||||
func (a *Absence) GetOvertimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
return a.GetOvertimeReal(u, base)
|
||||
}
|
||||
|
||||
func (a *Absence) GetTimesReal(u User, base WorktimeBase) (work, pause, overtime time.Duration) {
|
||||
return a.GetWorktimeReal(u, base), a.GetPausetimeReal(u, base), a.GetOvertimeReal(u, base)
|
||||
}
|
||||
|
||||
func (a *Absence) GetTimesVirtual(u User, base WorktimeBase) (work, pause, overtime time.Duration) {
|
||||
return a.GetWorktimeVirtual(u, base), a.GetPausetimeVirtual(u, base), a.GetOvertimeVirtual(u, base)
|
||||
}
|
||||
|
||||
func (a *Absence) TimeWorkVirtual(u User) time.Duration {
|
||||
return a.TimeWorkReal(u)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,14 @@ type IWorkDay interface {
|
||||
IsKurzArbeit() bool
|
||||
GetDayProgress(User) int8
|
||||
RequiresAction() bool
|
||||
GetWorktimeReal(User, WorktimeBase) time.Duration
|
||||
GetPausetimeReal(User, WorktimeBase) time.Duration
|
||||
GetOvertimeReal(User, WorktimeBase) time.Duration
|
||||
GetWorktimeVirtual(User, WorktimeBase) time.Duration
|
||||
GetPausetimeVirtual(User, WorktimeBase) time.Duration
|
||||
GetOvertimeVirtual(User, WorktimeBase) time.Duration
|
||||
GetTimesReal(User, WorktimeBase) (work, pause, overtime time.Duration)
|
||||
GetTimesVirtual(User, WorktimeBase) (work, pause, overtime time.Duration)
|
||||
}
|
||||
|
||||
type WorkDay struct {
|
||||
@@ -37,6 +45,13 @@ type WorkDay struct {
|
||||
kurzArbeitAbsence Absence
|
||||
}
|
||||
|
||||
type WorktimeBase string
|
||||
|
||||
const (
|
||||
WorktimeBaseWeek WorktimeBase = "week"
|
||||
WorktimeBaseDay WorktimeBase = "day"
|
||||
)
|
||||
|
||||
func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
|
||||
var allDays map[string]IWorkDay = make(map[string]IWorkDay)
|
||||
|
||||
@@ -66,6 +81,108 @@ func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay
|
||||
return sortedDays
|
||||
}
|
||||
|
||||
// Gets the time as is in the db (with corrected pause times)
|
||||
func (d *WorkDay) GetWorktimeReal(u User, base WorktimeBase) time.Duration {
|
||||
work, pause := calcWorkPause(d.Bookings)
|
||||
work, pause = correctWorkPause(work, pause)
|
||||
return work
|
||||
}
|
||||
|
||||
// Gets the corrected pause times based on db entries
|
||||
func (d *WorkDay) GetPausetimeReal(u User, base WorktimeBase) time.Duration {
|
||||
work, pause := calcWorkPause(d.Bookings)
|
||||
work, pause = correctWorkPause(work, pause)
|
||||
return pause
|
||||
}
|
||||
|
||||
// Returns the overtime based on the db entries
|
||||
func (d *WorkDay) GetOvertimeReal(u User, base WorktimeBase) time.Duration {
|
||||
work, pause := calcWorkPause(d.Bookings)
|
||||
work, pause = correctWorkPause(work, pause)
|
||||
|
||||
var targetHours time.Duration
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
targetHours = u.ArbeitszeitProTag()
|
||||
case WorktimeBaseWeek:
|
||||
targetHours = u.ArbeitszeitProWoche() / 5
|
||||
}
|
||||
return work - targetHours
|
||||
}
|
||||
|
||||
// Returns the worktime based on absence or kurzarbeit
|
||||
func (d *WorkDay) GetWorktimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
if !d.IsKurzArbeit() {
|
||||
return d.GetWorktimeReal(u, base)
|
||||
}
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
return u.ArbeitszeitProTag()
|
||||
case WorktimeBaseWeek:
|
||||
return u.ArbeitszeitProWoche() / 5
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (d *WorkDay) GetPausetimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
return d.GetPausetimeReal(u, base)
|
||||
}
|
||||
|
||||
func (d *WorkDay) GetOvertimeVirtual(u User, base WorktimeBase) time.Duration {
|
||||
work := d.GetWorktimeVirtual(u, base)
|
||||
|
||||
var targetHours time.Duration
|
||||
switch base {
|
||||
case WorktimeBaseDay:
|
||||
targetHours = u.ArbeitszeitProTag()
|
||||
case WorktimeBaseWeek:
|
||||
targetHours = u.ArbeitszeitProWoche() / 5
|
||||
}
|
||||
return work - targetHours
|
||||
}
|
||||
|
||||
func (d *WorkDay) GetTimesReal(u User, base WorktimeBase) (work, pause, overtime time.Duration) {
|
||||
return d.GetWorktimeReal(u, base), d.GetPausetimeReal(u, base), d.GetOvertimeReal(u, base)
|
||||
}
|
||||
|
||||
func (d *WorkDay) GetTimesVirtual(u User, base WorktimeBase) (work, pause, overtime time.Duration) {
|
||||
return d.GetWorktimeVirtual(u, base), d.GetPausetimeVirtual(u, base), d.GetOvertimeVirtual(u, base)
|
||||
}
|
||||
|
||||
func calcWorkPause(bookings []Booking) (work, pause time.Duration) {
|
||||
var lastBooking Booking
|
||||
for _, b := range bookings {
|
||||
if b.CheckInOut%2 == 1 {
|
||||
if !lastBooking.Timestamp.IsZero() {
|
||||
pause += b.Timestamp.Sub(lastBooking.Timestamp)
|
||||
}
|
||||
} else {
|
||||
work += b.Timestamp.Sub(lastBooking.Timestamp)
|
||||
}
|
||||
lastBooking = b
|
||||
}
|
||||
if len(bookings)%2 == 1 {
|
||||
work += time.Since(lastBooking.Timestamp.Local())
|
||||
}
|
||||
return work, pause
|
||||
}
|
||||
|
||||
func correctWorkPause(workIn, pauseIn time.Duration) (work, pause time.Duration) {
|
||||
if workIn <= 6*time.Hour || pauseIn > 45*time.Minute {
|
||||
return workIn, pauseIn
|
||||
}
|
||||
|
||||
var diff time.Duration
|
||||
if workIn <= (9*time.Hour) && pauseIn < 30*time.Minute {
|
||||
diff = 30*time.Minute - pauseIn
|
||||
} else if pauseIn < 45*time.Minute {
|
||||
diff = 45*time.Minute - pauseIn
|
||||
}
|
||||
work = workIn - diff
|
||||
pause = pauseIn + diff
|
||||
return work, pause
|
||||
}
|
||||
|
||||
func sortDays(days map[string]IWorkDay, forward bool) []IWorkDay {
|
||||
var sortedDays []IWorkDay
|
||||
for _, day := range days {
|
||||
@@ -127,7 +244,7 @@ func (d *WorkDay) TimeWorkReal(u User) time.Duration {
|
||||
if helper.IsSameDate(d.Date(), time.Now()) && len(d.Bookings)%2 == 1 {
|
||||
d.realWorkTime += time.Since(lastBooking.Timestamp.Local())
|
||||
}
|
||||
slog.Debug("Calculated RealWorkTime for user", "user", u, slog.String("worktime", d.realWorkTime.String()))
|
||||
// slog.Debug("Calculated RealWorkTime for user", "user", u, slog.String("worktime", d.realWorkTime.String()))
|
||||
return d.realWorkTime
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user