package excelread import ( "business-engine/internal/database" "fmt" "os" "slices" "strings" "time" "github.com/gocarina/gocsv" ) func sortSliceByDate[T any](slice []T, getDate func(T) time.Time) { compare := func(a, b T) int { aDate := getDate(a) bDate := getDate(b) if aDate.Before(bDate) { return -1 } if aDate.After(bDate) { return 1 } return 0 } slices.SortFunc(slice, compare) } // Zu kalkulieren // - Puenktlichkeitspraemie // - Tourengeld Anzahl // - Tourengeld Bonus func GeneratePayrollStatement(data EmployeeDataRow, input PayrollInputData) PayrollStatement { isKTW := slices.IndexFunc(input.Plannedtimes, func(pt database.ListPlannedTimesForEmployeeInPeriodRow) bool { return strings.Contains(pt.Department.String, "KTW") }) >= 0 && slices.IndexFunc(input.Plannedtimes, func(pt database.ListPlannedTimesForEmployeeInPeriodRow) bool { return strings.Contains(pt.Department.String, "Leitstelle") }) == -1 statement := PayrollStatement{ Nachname: data.Nachname, Vorname: data.Vorname, Verpflegungspauschale: data.AuszahlenVerpflegungspauschaleTage, VertragStundenlohn: input.ContractSalaryHour, Vertragsstunden: data.IstSollVertragsStunden, GearbeiteteStunden: data.GearbeiteteStunden, GearbeiteteTage: data.GearbeiteteTage, Krankheitstage: data.Krankheitstage, Ueberstunden: data.IstSollPlusMinusStunden, Wochenendzuschlag15: data.AuszahlenZuschlag15Stunden, Sonntagszuschlag50: data.AuszahlenZuschlag50Stunden, Nachtzuschlag25: data.AuszahlenZuschlag25Stunden, Nachtzuschlag40: data.AuszahlenZuschlag40Stunden, } if data.Krankheitstage > 0 || !isKTW { statement.GesundheitsbonusAbzug = "ja" } if isKTW && data.GenommeneUrlaubstage > 0 { statement.Urlaubsgeld = data.GenommeneUrlaubstage } if isKTW && data.AuszahlenAnzahlPSchein > 0 { statement.PScheinZulage = data.AuszahlenAnzahlPSchein } if isKTW && input.Tourengeld > 0 { statement.Tourengeld = float64(input.Tourengeld) } if isKTW && len(input.Worktimes) > 0 && len(input.Plannedtimes) > 0 { ptGetStartDate := func(pt database.ListPlannedTimesForEmployeeInPeriodRow) time.Time { return *pt.StartDate } wtGetStartDate := func(pt database.WorkTime) time.Time { return *pt.StartDate } sortSliceByDate(input.Plannedtimes, ptGetStartDate) sortSliceByDate(input.Worktimes, wtGetStartDate) var employeeOnTime []EmployeeOnTime for _, pt := range input.Plannedtimes { for _, wt := range input.Worktimes { if isSameDay(ptGetStartDate(pt), wtGetStartDate(wt)) && (wtGetStartDate(wt).Before(ptGetStartDate(pt)) || wtGetStartDate(wt) == ptGetStartDate(pt)) { statement.PuenktlichkeitspraemieAnzahl++ employeeOnTime = append(employeeOnTime, EmployeeOnTime{ EmployeeId: fmt.Sprintf("%s %s", data.Vorname, data.Nachname), WorkTime: *wt.StartDate, PlannedTime: *pt.StartDate, IsOnTime: true, }) } } } if data.Vorname == "David" && data.Nachname == "Hastedt" { GenerateEmployeesOnTime(employeeOnTime) } } return statement } func GenerateEmployeesOnTime(employeesontime []EmployeeOnTime) error { file, err := os.Create("employees_on_time.csv") if err != nil { return err } defer file.Close() if err := gocsv.MarshalFile(&employeesontime, file); err != nil { return err } return nil } // isSameDay prüft, ob zwei Zeitpunkte am selben Kalendertag liegen. func isSameDay(t1, t2 time.Time) bool { return t1.Year() == t2.Year() && t1.Month() == t2.Month() && t1.Day() == t2.Day() }