avicenna/service/data-hub/business-engine/internal/excel_read/calculate.go

123 lines
3.5 KiB
Go

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()
}