From c959cb7a87a2ee4f8b78bf6eabecc40f110c19c1 Mon Sep 17 00:00:00 2001 From: db123 Date: Wed, 24 Jun 2026 19:06:54 +0330 Subject: [PATCH] export: include all days, show Day Off in type column; menu: don't hide status on day off --- internal/bot/export.go | 71 ++++++++++++++++++++++++++++-------------- internal/bot/report.go | 1 - 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/internal/bot/export.go b/internal/bot/export.go index 719066d..c2b018e 100644 --- a/internal/bot/export.go +++ b/internal/bot/export.go @@ -123,24 +123,22 @@ func GenerateMonthlyReport(store *db.Store, userID int64, timezone, accent, cale dateStr := d.Format("2006-01-02") displayDate := formatDateForCalendar(dateStr, calendar) - day, exists := dayMap[dateStr] - if !exists { - continue - } - events, err := store.EventsForDayByDayID(day.ID) - if err != nil { - return nil, err - } - if len(events) == 0 { - continue + // Determine if this day exists, its events, and day-off status. + var ( + day *db.Day + events []db.Event + hasDayOff bool + ) + if existing, ok := dayMap[dateStr]; ok { + day = existing + events, err = store.EventsForDayByDayID(day.ID) + if err != nil { + return nil, err + } + hasDayOff = day.IsDayOff } - dayStart := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, loc).Unix() - dayEnd := time.Date(d.Year(), d.Month(), d.Day(), 23, 59, 59, 0, loc).Unix() - totals := ComputeDailyTotals(events, day.MinBreakThreshold, dayStart, dayEnd) - totalWork += totals.TotalSeconds - totalBreak += totals.BreakSeconds - + // Write the date cell for every day. cellDate, _ := excelize.CoordinatesToCellName(1, row) f.SetCellValue(sheet, cellDate, displayDate) f.SetCellStyle(sheet, cellDate, cellDate, dataStyle) @@ -150,23 +148,48 @@ func GenerateMonthlyReport(store *db.Store, userID int64, timezone, accent, cale f.SetCellValue(sheet, cellIn, time.Unix(events[0].OccurredAt, 0).In(loc).Format("15:04")) f.SetCellStyle(sheet, cellIn, cellIn, dataStyle) } - if lastEvent := events[len(events)-1]; lastEvent.EventType == "out" { - cellOut, _ := excelize.CoordinatesToCellName(3, row) - f.SetCellValue(sheet, cellOut, time.Unix(lastEvent.OccurredAt, 0).In(loc).Format("15:04")) - f.SetCellStyle(sheet, cellOut, cellOut, dataStyle) + if len(events) > 0 { + lastEvent := events[len(events)-1] + if lastEvent.EventType == "out" { + cellOut, _ := excelize.CoordinatesToCellName(3, row) + f.SetCellValue(sheet, cellOut, time.Unix(lastEvent.OccurredAt, 0).In(loc).Format("15:04")) + f.SetCellStyle(sheet, cellOut, cellOut, dataStyle) + } } - wtLabel := workTypeLabel(store, day, events) + // Type column: day-off, work-type label, or empty. + var typeLabel string + if hasDayOff { + if day.DayOffReason != "" { + typeLabel = "Day Off (" + day.DayOffReason + ")" + } else { + typeLabel = "Day Off" + } + } else if len(events) > 0 { + typeLabel = workTypeLabel(store, day, events) + } cellType, _ := excelize.CoordinatesToCellName(4, row) - f.SetCellValue(sheet, cellType, wtLabel) + f.SetCellValue(sheet, cellType, typeLabel) f.SetCellStyle(sheet, cellType, cellType, dataStyle) + // Work and Break columns — compute totals only when there are events. + var workSec, breakSec int64 + if len(events) > 0 && day != nil { + dayStart := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, loc).Unix() + dayEnd := time.Date(d.Year(), d.Month(), d.Day(), 23, 59, 59, 0, loc).Unix() + totals := ComputeDailyTotals(events, day.MinBreakThreshold, dayStart, dayEnd) + workSec = totals.TotalSeconds + breakSec = totals.BreakSeconds + totalWork += workSec + totalBreak += breakSec + } + cellWork, _ := excelize.CoordinatesToCellName(5, row) - f.SetCellValue(sheet, cellWork, fmtHHMM(totals.TotalSeconds)) + f.SetCellValue(sheet, cellWork, fmtHHMM(workSec)) f.SetCellStyle(sheet, cellWork, cellWork, dataStyle) cellBreak, _ := excelize.CoordinatesToCellName(6, row) - f.SetCellValue(sheet, cellBreak, fmtHHMM(totals.BreakSeconds)) + f.SetCellValue(sheet, cellBreak, fmtHHMM(breakSec)) f.SetCellStyle(sheet, cellBreak, cellBreak, dataStyle) row++ diff --git a/internal/bot/report.go b/internal/bot/report.go index 010d453..0fc207e 100644 --- a/internal/bot/report.go +++ b/internal/bot/report.go @@ -23,7 +23,6 @@ func (h *Handler) buildStatusText(chatID int64) string { if day.IsDayOff { text += "\nDay Off" - return text + "\n\nChoose an action:" } wt, _ := h.DB.GetWorkType(day.CurrentWorkTypeID)