From 60257ce40b7da20c45c77bbbaa1db19d1c1368b0 Mon Sep 17 00:00:00 2001 From: Jonas Zeiger Date: Sun, 17 Mar 2024 23:19:33 +0100 Subject: [PATCH] util.FilterTimeOffs(): function to filter timeOffs --- CHANGELOG.md | 4 ++++ util.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a5139c..e163dcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `util.FilterTimeOffs()` function + ## [0.3.0] - 2023-07-05 ### Added diff --git a/util.go b/util.go index 62285fa..21f73d6 100644 --- a/util.go +++ b/util.go @@ -2,6 +2,8 @@ package util import ( "time" + + v1 "github.com/giantswarm/personio-go/v1" ) // PersonioDateMax is the maximum representable time.Time value for the Personio API @@ -22,3 +24,56 @@ func GetTimeIntersection(start1 time.Time, end1 time.Time, start2 time.Time, end return endMin.Sub(startMax) } + +// FilterTimeOffs returns a slice of timeOffs that overlap with the given bounds and optionally matches minimum length and email +// Specify a minLengthHours of 0 to disable length filtering +// Specify email as nil to disable email filtering +func FilterTimeOffs(timeOffs []*v1.TimeOff, start time.Time, end time.Time, minLengthHours float64, email *string) []*v1.TimeOff { + var matchedTimeOffs []*v1.TimeOff + + for _, timeOff := range timeOffs { + + timeOffEmail := timeOff.Employee.GetStringAttribute("email") + if email != nil && (timeOffEmail == nil || *email != *timeOffEmail) { + continue + } + + timeOffStart := timeOff.StartDate + timeOffEnd := timeOff.EndDate + // we need to adjust the wall-clock time according to other fields + if timeOff.DaysCount > 1 { + if timeOff.HalfDayStart { + timeOffStart = timeOffStart.Add(time.Hour * 12) + } + if timeOff.HalfDayEnd { + timeOffEnd = timeOffEnd.Add(time.Hour * 12) + } else { + timeOffEnd = timeOffEnd.Add(time.Hour * 24) + } + } else { + if timeOff.HalfDayStart && !timeOff.HalfDayEnd { + timeOffEnd = timeOffEnd.Add(time.Hour * 12) + } else if !timeOff.HalfDayStart && timeOff.HalfDayEnd { + timeOffStart = timeOffStart.Add(time.Hour * 12) + timeOffEnd = timeOffEnd.Add(time.Hour * 24) + } else { + timeOffEnd = timeOffEnd.Add(time.Hour * 24) + } + } + + if minLengthHours > 0 && timeOffEnd.Sub(timeOffStart).Hours() < minLengthHours { + // timeOff event too short, ignore + continue + } + + overlap := GetTimeIntersection(timeOffStart, timeOffEnd, start, end) + if overlap <= 0 { + // timeOff and bounds don't overlap + continue + } + + matchedTimeOffs = append(matchedTimeOffs, timeOff) + } + + return matchedTimeOffs +}