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
|
var typstDays []typstDay
|
||||||
for _, day := range days {
|
for _, day := range days {
|
||||||
var thisTypstDay typstDay
|
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.Date = day.Date().Format(DE_DATE)
|
||||||
thisTypstDay.Worktime = helper.FormatDurationFill(work, true)
|
thisTypstDay.Worktime = helper.FormatDurationFill(work, true)
|
||||||
thisTypstDay.Pausetime = helper.FormatDurationFill(pause, 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))
|
targetHours := (employee.ArbeitszeitProWoche() / 5) * time.Duration(helper.GetWorkingDays(startDate, endDate))
|
||||||
workingDays := models.GetDays(employee, startDate, endDate, false)
|
workingDays := models.GetDays(employee, startDate, endDate, false)
|
||||||
|
|
||||||
|
slog.Debug("Baseline Working hours", "targetHours", targetHours.Hours())
|
||||||
|
|
||||||
var actualHours time.Duration
|
var actualHours time.Duration
|
||||||
for _, day := range workingDays {
|
for _, day := range workingDays {
|
||||||
actualHours += day.TimeWorkVirtual(employee)
|
actualHours += day.TimeWorkVirtual(employee)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ func FormatDuration(d time.Duration) string {
|
|||||||
|
|
||||||
// Converts duration to string
|
// Converts duration to string
|
||||||
func FormatDurationFill(d time.Duration, fill bool) string {
|
func FormatDurationFill(d time.Duration, fill bool) string {
|
||||||
|
return fmt.Sprintf("%.1f", d.Hours())
|
||||||
hours := int(d.Abs().Hours())
|
hours := int(d.Abs().Hours())
|
||||||
minutes := int(d.Abs().Minutes()) % 60
|
minutes := int(d.Abs().Minutes()) % 60
|
||||||
sign := ""
|
sign := ""
|
||||||
|
|||||||
@@ -49,6 +49,55 @@ func (a *Absence) IsMultiDay() bool {
|
|||||||
return !a.DateFrom.Equal(a.DateTo)
|
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 {
|
func (a *Absence) TimeWorkVirtual(u User) time.Duration {
|
||||||
return a.TimeWorkReal(u)
|
return a.TimeWorkReal(u)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ type IWorkDay interface {
|
|||||||
IsKurzArbeit() bool
|
IsKurzArbeit() bool
|
||||||
GetDayProgress(User) int8
|
GetDayProgress(User) int8
|
||||||
RequiresAction() bool
|
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 {
|
type WorkDay struct {
|
||||||
@@ -37,6 +45,13 @@ type WorkDay struct {
|
|||||||
kurzArbeitAbsence Absence
|
kurzArbeitAbsence Absence
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WorktimeBase string
|
||||||
|
|
||||||
|
const (
|
||||||
|
WorktimeBaseWeek WorktimeBase = "week"
|
||||||
|
WorktimeBaseDay WorktimeBase = "day"
|
||||||
|
)
|
||||||
|
|
||||||
func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
|
func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
|
||||||
var allDays map[string]IWorkDay = make(map[string]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
|
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 {
|
func sortDays(days map[string]IWorkDay, forward bool) []IWorkDay {
|
||||||
var sortedDays []IWorkDay
|
var sortedDays []IWorkDay
|
||||||
for _, day := range days {
|
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 {
|
if helper.IsSameDate(d.Date(), time.Now()) && len(d.Bookings)%2 == 1 {
|
||||||
d.realWorkTime += time.Since(lastBooking.Timestamp.Local())
|
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
|
return d.realWorkTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user