feat: add schoolyear based calculation
This commit is contained in:
parent
e65ba85c43
commit
c07019e3eb
5 changed files with 675 additions and 44 deletions
|
|
@ -66,6 +66,14 @@ func createTables(db *sql.DB) {
|
|||
details TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS school_years (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
}
|
||||
|
||||
for _, query := range queries {
|
||||
|
|
@ -92,6 +100,8 @@ func createIndexes(db *sql.DB) {
|
|||
`CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs(created_at)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_schedules_day ON schedules(day_of_week)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_school_years_active ON school_years(is_active)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_school_years_dates ON school_years(start_date, end_date)`,
|
||||
}
|
||||
|
||||
for _, idx := range indexes {
|
||||
|
|
@ -349,56 +359,56 @@ func GetWeeklyHours(db *sql.DB) ([]WeeklyHours, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func GetYearlyHoursSummary(db *sql.DB) ([]WeeklyHours, error) {
|
||||
users, err := GetAllUsers(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// func GetYearlyHoursSummary(db *sql.DB) ([]WeeklyHours, error) {
|
||||
// users, err := GetAllUsers(db)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
entries, err := GetAllTimeEntries(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// entries, err := GetAllTimeEntries(db)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
userTotals := make(map[int]float64)
|
||||
usernames := make(map[int]string)
|
||||
// userTotals := make(map[int]float64)
|
||||
// usernames := make(map[int]string)
|
||||
|
||||
for _, entry := range entries {
|
||||
var hours float64
|
||||
if entry.Type == "lesson" {
|
||||
hours = 1.0
|
||||
} else {
|
||||
hours = calculateHoursDiff(entry.StartTime, entry.EndTime)
|
||||
}
|
||||
userTotals[entry.UserID] += hours
|
||||
usernames[entry.UserID] = entry.Username
|
||||
}
|
||||
// for _, entry := range entries {
|
||||
// var hours float64
|
||||
// if entry.Type == "lesson" {
|
||||
// hours = 1.0
|
||||
// } else {
|
||||
// hours = calculateHoursDiff(entry.StartTime, entry.EndTime)
|
||||
// }
|
||||
// userTotals[entry.UserID] += hours
|
||||
// usernames[entry.UserID] = entry.Username
|
||||
// }
|
||||
|
||||
var result []WeeklyHours
|
||||
for _, user := range users {
|
||||
if !user.IsAdmin {
|
||||
total := userTotals[user.ID]
|
||||
remaining := user.YearlyHours - total
|
||||
// var result []WeeklyHours
|
||||
// for _, user := range users {
|
||||
// if !user.IsAdmin {
|
||||
// total := userTotals[user.ID]
|
||||
// remaining := user.YearlyHours - total
|
||||
|
||||
result = append(result, WeeklyHours{
|
||||
UserID: user.ID,
|
||||
Username: user.Username,
|
||||
Year: time.Now().Year(),
|
||||
Week: 0,
|
||||
TotalHours: total,
|
||||
YearlyTarget: user.YearlyHours,
|
||||
YearlyActual: total,
|
||||
RemainingYearly: remaining,
|
||||
})
|
||||
}
|
||||
}
|
||||
// result = append(result, WeeklyHours{
|
||||
// UserID: user.ID,
|
||||
// Username: user.Username,
|
||||
// Year: time.Now().Year(),
|
||||
// Week: 0,
|
||||
// TotalHours: total,
|
||||
// YearlyTarget: user.YearlyHours,
|
||||
// YearlyActual: total,
|
||||
// RemainingYearly: remaining,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].Username < result[j].Username
|
||||
})
|
||||
// sort.Slice(result, func(i, j int) bool {
|
||||
// return result[i].Username < result[j].Username
|
||||
// })
|
||||
|
||||
return result, nil
|
||||
}
|
||||
// return result, nil
|
||||
// }
|
||||
|
||||
func calculateHoursDiff(startTime, endTime string) float64 {
|
||||
parseTime := func(timeStr string) float64 {
|
||||
|
|
@ -469,3 +479,130 @@ func CheckUserHasEntriesForWeek(db *sql.DB, userID int, year int, week int) (boo
|
|||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func GetActiveSchoolYear(db *sql.DB) (*SchoolYear, error) {
|
||||
var sy SchoolYear
|
||||
err := db.QueryRow(`
|
||||
SELECT id, name, start_date, end_date, is_active, created_at
|
||||
FROM school_years
|
||||
WHERE is_active = 1
|
||||
`).Scan(&sy.ID, &sy.Name, &sy.StartDate, &sy.EndDate, &sy.IsActive, &sy.CreatedAt)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil // Kein aktives Schuljahr
|
||||
}
|
||||
return &sy, err
|
||||
}
|
||||
|
||||
func GetAllSchoolYears(db *sql.DB) ([]SchoolYear, error) {
|
||||
rows, err := db.Query(`
|
||||
SELECT id, name, start_date, end_date, is_active, created_at
|
||||
FROM school_years
|
||||
ORDER BY start_date DESC
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
years := []SchoolYear{}
|
||||
for rows.Next() {
|
||||
var sy SchoolYear
|
||||
if err := rows.Scan(&sy.ID, &sy.Name, &sy.StartDate, &sy.EndDate, &sy.IsActive, &sy.CreatedAt); err != nil {
|
||||
continue
|
||||
}
|
||||
years = append(years, sy)
|
||||
}
|
||||
return years, rows.Err()
|
||||
}
|
||||
|
||||
func CreateSchoolYear(db *sql.DB, name, startDate, endDate string) error {
|
||||
_, err := db.Exec(`
|
||||
INSERT INTO school_years (name, start_date, end_date, is_active)
|
||||
VALUES (?, ?, ?, 0)
|
||||
`, name, startDate, endDate)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetActiveSchoolYear(db *sql.DB, id int) error {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tx.Exec("UPDATE school_years SET is_active = 0"); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tx.Exec("UPDATE school_years SET is_active = 1 WHERE id = ?", id); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func GetYearlyHoursSummary(db *sql.DB) ([]WeeklyHours, error) {
|
||||
schoolYear, err := GetActiveSchoolYear(db)
|
||||
if err != nil || schoolYear == nil {
|
||||
return []WeeklyHours{}, err
|
||||
}
|
||||
|
||||
users, err := GetAllUsers(db)
|
||||
if err != nil {
|
||||
return []WeeklyHours{}, err
|
||||
}
|
||||
|
||||
rows, err := db.Query(`
|
||||
SELECT user_id, date, start_time, end_time, type
|
||||
FROM time_entries
|
||||
WHERE date >= ? AND date <= ?
|
||||
ORDER BY date DESC
|
||||
`, schoolYear.StartDate, schoolYear.EndDate)
|
||||
|
||||
if err != nil {
|
||||
return []WeeklyHours{}, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
userTotals := make(map[int]float64)
|
||||
|
||||
for rows.Next() {
|
||||
var userID int
|
||||
var date, startTime, endTime, entryType string
|
||||
|
||||
if err := rows.Scan(&userID, &date, &startTime, &endTime, &entryType); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var hours float64
|
||||
if entryType == "lesson" {
|
||||
hours = 1.0
|
||||
} else {
|
||||
hours = calculateHoursDiff(startTime, endTime)
|
||||
}
|
||||
userTotals[userID] += hours
|
||||
}
|
||||
|
||||
var result []WeeklyHours
|
||||
for _, user := range users {
|
||||
if !user.IsAdmin {
|
||||
total := userTotals[user.ID]
|
||||
remaining := user.YearlyHours - total
|
||||
|
||||
result = append(result, WeeklyHours{
|
||||
UserID: user.ID,
|
||||
Username: user.Username,
|
||||
Year: 0,
|
||||
Week: 0,
|
||||
TotalHours: total,
|
||||
YearlyTarget: user.YearlyHours,
|
||||
YearlyActual: total,
|
||||
RemainingYearly: remaining,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue