refactor: break up large functions, add RPG/league/salary/burnout, fix bugs, add tests
- Refactor GenerateMonthlyReport (198→70), HandleCallback (128→85), handleHistoryCallback (131→38), handleExportCallback (100→25), checkAchievements (86→25) into extracted helper functions - Add RPG system (XP, levels, streak, achievements, burnout) - Add WorkTime League leaderboard - Add salary estimation with configurable currency/rate - Add input sanitization (SanitizeNote, SanitizeDisplayName) - Add settings select-style pickers for toggles (report, RPG, league) - Add break threshold inline picker UI - Add event notes with pending state and /note command - Add multi-calendar support (Jalali, Hijri) - Add Excel export with theme picker - Fix: getTodayBreakThreshold uses user's timezone (was UTC) - Fix: acknowledgeCallback passes real callback ID - Fix: currency symbol safety with currencySymbol() helper - Fix: count work hours in summary on day-off days - Fix: unsilence all error returns from SQL Exec/Bot API/migrations - Remove stale db/schema.sql and unreferenced computeWeekTotals - Extract constants: DateLayout, TimeLayout, secondsPerHour, etc. - Add 12 new tests (XP, salary, sanitize, currency, dateutil) - Remove duplicate package doc comment in totals.go
This commit is contained in:
@@ -108,6 +108,14 @@ func (h *Handler) buildMonthlySummary(user *db.User, calY, calM int, startStr, e
|
||||
if totalBreak > 0 {
|
||||
b.WriteString(fmt.Sprintf(", %s break", formatDuration(totalBreak)))
|
||||
}
|
||||
|
||||
st, _ := h.DB.GetOrCreateSettings(user.ID)
|
||||
if st.HourlyRate > 0 {
|
||||
est := computeMonthlySalary(days, h.DB, user.ID, st.HourlyRate, loc)
|
||||
b.WriteString(fmt.Sprintf("\nSalary: %s (%.1f hours, %d days)",
|
||||
est.formatSalary(st.Currency), est.WorkHours, est.WorkDays))
|
||||
}
|
||||
|
||||
b.WriteString("\n\nDetails:\n")
|
||||
for _, d := range dayDetails {
|
||||
b.WriteString(d)
|
||||
@@ -115,39 +123,3 @@ func (h *Handler) buildMonthlySummary(user *db.User, calY, calM int, startStr, e
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// computeWeekTotals returns the total work seconds for the current week (Mon-Sun containing today).
|
||||
func (h *Handler) computeWeekTotals(user *db.User, loc *time.Location) int64 {
|
||||
now := time.Now().In(loc)
|
||||
weekday := now.Weekday()
|
||||
if weekday == time.Sunday {
|
||||
weekday = 7
|
||||
}
|
||||
monday := now.AddDate(0, 0, -int(weekday-time.Monday))
|
||||
sunday := monday.AddDate(0, 0, 6)
|
||||
|
||||
startStr := monday.Format("2006-01-02")
|
||||
endStr := sunday.Format("2006-01-02")
|
||||
|
||||
days, err := h.DB.GetUserDaysInRange(user.ID, startStr, endStr)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
var total int64
|
||||
for _, day := range days {
|
||||
if day.IsDayOff {
|
||||
continue
|
||||
}
|
||||
events, err := h.DB.EventsForDayByDayID(day.ID)
|
||||
if err != nil || len(events) == 0 {
|
||||
continue
|
||||
}
|
||||
y, m, d := parseGregorianDateKey(day.Date)
|
||||
dayStart := time.Date(y, time.Month(m), d, 0, 0, 0, 0, loc).Unix()
|
||||
dayEnd := time.Date(y, time.Month(m), d, 23, 59, 59, 0, loc).Unix()
|
||||
totals := ComputeDailyTotals(events, day.MinBreakThreshold, dayStart, dayEnd)
|
||||
total += totals.TotalSeconds
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user