fixed #61, #62 refactored getTime variants
Some checks failed
Tests / Run Go Tests (push) Failing after 1m20s
Some checks failed
Tests / Run Go Tests (push) Failing after 1m20s
This commit is contained in:
@@ -20,13 +20,21 @@ func convertDaysToTypst(days []models.IWorkDay, u models.User) ([]typstDay, erro
|
||||
var typstDays []typstDay
|
||||
for _, day := range days {
|
||||
var thisTypstDay typstDay
|
||||
work, pause, overtime := day.GetTimes(u, models.WorktimeBaseWeek, true)
|
||||
work, pause, overtime := day.GetTimes(u, models.WorktimeBaseDay, false)
|
||||
workVirtual := day.GetWorktime(u, models.WorktimeBaseDay, true)
|
||||
overtime = workVirtual - u.ArbeitszeitProWocheFrac(0.2)
|
||||
thisTypstDay.Date = day.Date().Format(DE_DATE)
|
||||
thisTypstDay.Worktime = helper.FormatDurationFill(work, true)
|
||||
thisTypstDay.Worktime = helper.FormatDurationFill(workVirtual, true)
|
||||
thisTypstDay.Pausetime = helper.FormatDurationFill(pause, true)
|
||||
thisTypstDay.Overtime = helper.FormatDurationFill(overtime, true)
|
||||
thisTypstDay.IsFriday = day.Date().Weekday() == time.Friday
|
||||
|
||||
if workVirtual > work {
|
||||
thisTypstDay.Kurzarbeit = helper.FormatDurationFill(workVirtual-work, true)
|
||||
} else {
|
||||
thisTypstDay.Kurzarbeit = helper.FormatDurationFill(0, true)
|
||||
}
|
||||
|
||||
thisTypstDay.DayParts = convertDayToTypstDayParts(day, u)
|
||||
typstDays = append(typstDays, thisTypstDay)
|
||||
}
|
||||
@@ -45,7 +53,7 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay
|
||||
typstDayPart.IsWorkDay = true
|
||||
typstDayParts = append(typstDayParts, typstDayPart)
|
||||
}
|
||||
if day.IsKurzArbeit() {
|
||||
if day.IsKurzArbeit() && len(workDay.Bookings) > 0 {
|
||||
tsFrom, tsTo := workDay.GenerateKurzArbeitBookings(user)
|
||||
typstDayParts = append(typstDayParts, typstDayPart{
|
||||
BookingFrom: tsFrom.Format("15:04"),
|
||||
@@ -54,6 +62,9 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay
|
||||
IsWorkDay: true,
|
||||
})
|
||||
}
|
||||
if workdayAbsence := workDay.GetWorktimeAbsence(); (workdayAbsence != models.Absence{}) {
|
||||
typstDayParts = append(typstDayParts, typstDayPart{IsWorkDay: false, WorkType: workdayAbsence.AbwesenheitTyp.Name})
|
||||
}
|
||||
|
||||
} else {
|
||||
absentDay, _ := day.(*models.Absence)
|
||||
@@ -62,6 +73,90 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay
|
||||
return typstDayParts
|
||||
}
|
||||
|
||||
func PDFCreateController(w http.ResponseWriter, r *http.Request) {
|
||||
helper.RequiresLogin(Session, w, r)
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
user, err := models.GetUserFromSession(Session, r.Context())
|
||||
if err != nil {
|
||||
log.Println("Error getting user!")
|
||||
return
|
||||
}
|
||||
pp := paramParser.New(r.URL.Query())
|
||||
startDate := pp.ParseTimestampFallback("start_date", time.DateOnly, time.Now())
|
||||
personalNumbers := pp.ParseIntListFallback("employe_list", ",", make([]int, 0))
|
||||
|
||||
employes, err := models.GetUserByPersonalNrMulti(personalNumbers)
|
||||
if err != nil {
|
||||
slog.Warn("Error getting employes!", slog.Any("Error", err))
|
||||
return
|
||||
}
|
||||
|
||||
output, err := createReports(user, employes, startDate)
|
||||
if err != nil {
|
||||
slog.Warn("Could not create pdf report", slog.Any("Error", err))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-type", "application/pdf")
|
||||
output.WriteTo(w)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
default:
|
||||
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func createReports(user models.User, employes []models.User, startDate time.Time) (bytes.Buffer, error) {
|
||||
startDate = helper.GetFirstOfMonth(startDate)
|
||||
endDate := startDate.AddDate(0, 1, -1)
|
||||
|
||||
var employeData []typstData
|
||||
for _, employe := range employes {
|
||||
if data, err := createEmployeReport(employe, startDate, endDate); err != nil {
|
||||
slog.Warn("Error when creating employeReport", slog.Any("user", employe), slog.Any("error", err))
|
||||
} else {
|
||||
employeData = append(employeData, data)
|
||||
}
|
||||
}
|
||||
return renderPDF(employeData)
|
||||
}
|
||||
|
||||
func createEmployeReport(employee models.User, startDate, endDate time.Time) (typstData, error) {
|
||||
targetHoursThisMonth := employee.ArbeitszeitProWocheFrac(.2) * time.Duration(helper.GetWorkingDays(startDate, endDate))
|
||||
workDaysThisMonth := models.GetDays(employee, startDate, endDate.AddDate(0, 0, 1), false)
|
||||
|
||||
slog.Debug("Baseline Working hours", "targetHours", targetHoursThisMonth.Hours())
|
||||
|
||||
var workHours, kurzarbeitHours time.Duration
|
||||
for _, day := range workDaysThisMonth {
|
||||
tmpvirtualHours := day.GetWorktime(employee, models.WorktimeBaseDay, true)
|
||||
tmpactualHours := day.GetWorktime(employee, models.WorktimeBaseDay, false)
|
||||
if day.IsKurzArbeit() && tmpvirtualHours > tmpactualHours {
|
||||
slog.Debug("Adding kurzarbeit to workday", "day", day.Date())
|
||||
kurzarbeitHours += tmpvirtualHours - tmpactualHours
|
||||
}
|
||||
workHours += tmpvirtualHours
|
||||
}
|
||||
worktimeBalance := workHours - targetHoursThisMonth
|
||||
|
||||
typstDays, err := convertDaysToTypst(workDaysThisMonth, employee)
|
||||
if err != nil {
|
||||
slog.Warn("Failed to convert to days", slog.Any("error", err))
|
||||
return typstData{}, err
|
||||
}
|
||||
|
||||
metadata := typstMetadata{
|
||||
EmployeeName: fmt.Sprintf("%s %s", employee.Vorname, employee.Name),
|
||||
TimeRange: fmt.Sprintf("%s - %s", startDate.Format(DE_DATE), endDate.Format(DE_DATE)),
|
||||
Overtime: helper.FormatDurationFill(worktimeBalance, true),
|
||||
WorkTime: helper.FormatDurationFill(workHours, true),
|
||||
Kurzarbeit: helper.FormatDurationFill(kurzarbeitHours, true),
|
||||
OvertimeTotal: "",
|
||||
CurrentTimestamp: time.Now().Format("02.01.2006 - 15:04 Uhr"),
|
||||
}
|
||||
return typstData{Meta: metadata, Days: typstDays}, nil
|
||||
}
|
||||
|
||||
func renderPDF(data []typstData) (bytes.Buffer, error) {
|
||||
var markup bytes.Buffer
|
||||
var output bytes.Buffer
|
||||
@@ -90,115 +185,6 @@ func renderPDF(data []typstData) (bytes.Buffer, error) {
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func PDFCreateController(w http.ResponseWriter, r *http.Request) {
|
||||
helper.RequiresLogin(Session, w, r)
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
user, err := models.GetUserFromSession(Session, r.Context())
|
||||
if err != nil {
|
||||
log.Println("Error getting user!")
|
||||
return
|
||||
}
|
||||
pp := paramParser.New(r.URL.Query())
|
||||
startDate := pp.ParseTimestampFallback("start_date", time.DateOnly, time.Now())
|
||||
var members []models.User = make([]models.User, 0)
|
||||
output, err := createReports(user, members, startDate)
|
||||
if err != nil {
|
||||
slog.Warn("Could not create pdf report", slog.Any("Error", err))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-type", "application/pdf")
|
||||
output.WriteTo(w)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
default:
|
||||
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func createReports(user models.User, employes []models.User, startDate time.Time) (bytes.Buffer, error) {
|
||||
if startDate.Day() > 1 {
|
||||
startDate = startDate.AddDate(0, 0, -(startDate.Day() - 1))
|
||||
}
|
||||
endDate := startDate.AddDate(0, 1, -1)
|
||||
return createEmployeReport(user, startDate, endDate)
|
||||
}
|
||||
|
||||
func createEmployeReport(employee models.User, startDate, endDate time.Time) (bytes.Buffer, error) {
|
||||
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.GetWorktime(employee, models.WorktimeBaseDay, true)
|
||||
}
|
||||
worktimeBalance := actualHours - targetHours
|
||||
|
||||
typstDays, err := convertDaysToTypst(workingDays, employee)
|
||||
if err != nil {
|
||||
log.Panicf("Failed to convert days!")
|
||||
}
|
||||
|
||||
metadata := typstMetadata{
|
||||
EmployeeName: fmt.Sprintf("%s %s", employee.Vorname, employee.Name),
|
||||
TimeRange: fmt.Sprintf("%s - %s", startDate.Format(DE_DATE), endDate.Format(DE_DATE)),
|
||||
Overtime: helper.FormatDurationFill(worktimeBalance, true),
|
||||
WorkTime: helper.FormatDurationFill(actualHours, true),
|
||||
OvertimeTotal: "",
|
||||
CurrentTimestamp: time.Now().Format("02.01.2006 - 15:04 Uhr"),
|
||||
}
|
||||
|
||||
return renderPDF([]typstData{{Meta: metadata, Days: typstDays}, {Meta: metadata, Days: typstDays}})
|
||||
}
|
||||
|
||||
func PDFHandler(w http.ResponseWriter, r *http.Request) {
|
||||
helper.RequiresLogin(Session, w, r)
|
||||
startDate := time.Now()
|
||||
|
||||
if startDate.Day() > 1 {
|
||||
startDate = startDate.AddDate(0, 0, -(startDate.Day() - 1))
|
||||
}
|
||||
endDate := startDate.AddDate(0, 1, -1)
|
||||
|
||||
user, err := models.GetUserFromSession(Session, r.Context())
|
||||
if err != nil {
|
||||
log.Println("Error getting user!")
|
||||
}
|
||||
|
||||
//TODO: only accepted weeks
|
||||
|
||||
weeks := models.GetDays(user, startDate, endDate, false)
|
||||
var aggregatedOvertime, aggregatedWorkTime time.Duration
|
||||
for _, day := range weeks {
|
||||
aggregatedOvertime += day.GetOvertime(user, models.WorktimeBaseWeek, false)
|
||||
aggregatedWorkTime += day.GetWorktime(user, models.WorktimeBaseWeek, true)
|
||||
}
|
||||
|
||||
typstDays, err := convertDaysToTypst(weeks, user)
|
||||
if err != nil {
|
||||
log.Panicf("Failed to convert days!")
|
||||
}
|
||||
metadata := typstMetadata{
|
||||
EmployeeName: fmt.Sprintf("%s %s", user.Vorname, user.Name),
|
||||
TimeRange: fmt.Sprintf("%s - %s", startDate.Format(DE_DATE), endDate.Format(DE_DATE)),
|
||||
Overtime: helper.FormatDurationFill(aggregatedOvertime, true),
|
||||
WorkTime: helper.FormatDurationFill(aggregatedWorkTime, true),
|
||||
OvertimeTotal: "",
|
||||
CurrentTimestamp: time.Now().Format("02.01.2006 - 15:04 Uhr"),
|
||||
}
|
||||
|
||||
output, err := renderPDF([]typstData{{Meta: metadata, Days: typstDays}})
|
||||
if err != nil {
|
||||
slog.Warn("Could not create pdf report", slog.Any("Error", err))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-type", "application/pdf")
|
||||
output.WriteTo(w)
|
||||
w.WriteHeader(200)
|
||||
}
|
||||
|
||||
type typstMetadata struct {
|
||||
TimeRange string `json:"time-range"`
|
||||
EmployeeName string `json:"employee-name"`
|
||||
@@ -217,12 +203,13 @@ type typstDayPart struct {
|
||||
}
|
||||
|
||||
type typstDay struct {
|
||||
Date string `json:"date"`
|
||||
DayParts []typstDayPart `json:"day-parts"`
|
||||
Worktime string `json:"worktime"`
|
||||
Pausetime string `json:"pausetime"`
|
||||
Overtime string `json:"overtime"`
|
||||
IsFriday bool `json:"is-weekend"`
|
||||
Date string `json:"date"`
|
||||
DayParts []typstDayPart `json:"day-parts"`
|
||||
Worktime string `json:"worktime"`
|
||||
Pausetime string `json:"pausetime"`
|
||||
Overtime string `json:"overtime"`
|
||||
Kurzarbeit string `json:"kurzarbeit"`
|
||||
IsFriday bool `json:"is-weekend"`
|
||||
}
|
||||
|
||||
type typstData struct {
|
||||
|
||||
Reference in New Issue
Block a user