package bot import ( "fmt" "time" "github.com/xuri/excelize/v2" "worktimeBot/internal/db" ) // GenerateMonthlyReport creates an Excel spreadsheet for the given month. func GenerateMonthlyReport(store *db.Store, year int, month time.Month) ([]byte, error) { f := excelize.NewFile() defer func() { _ = f.Close() }() sheet := "Report" // Create a new sheet index, err := f.NewSheet(sheet) if err != nil { return nil, err } f.SetActiveSheet(index) // Header row headers := []string{"Date", "Work Duration (h)", "Pairs"} for i, h := range headers { cell, _ := excelize.CoordinatesToCellName(i+1, 1) if err := f.SetCellValue(sheet, cell, h); err != nil { return nil, err } } row := 2 loc := time.Now().Location() firstDay := time.Date(year, month, 1, 0, 0, 0, 0, loc) lastDay := firstDay.AddDate(0, 1, -1) for d := firstDay; d.Before(lastDay.AddDate(0, 0, 1)); d = d.AddDate(0, 0, 1) { dateStr := d.Format("2006-01-02") isOff, err := store.IsDayOff(dateStr) if err != nil { return nil, err } if isOff { continue // skip day‑offs } events, err := store.EventsForDay(dateStr) if err != nil { return nil, err } totals := ComputeDailyTotals(events) hours := float64(totals.TotalSeconds) / 3600.0 cellDate, _ := excelize.CoordinatesToCellName(1, row) cellHours, _ := excelize.CoordinatesToCellName(2, row) cellPairs, _ := excelize.CoordinatesToCellName(3, row) if err := f.SetCellValue(sheet, cellDate, dateStr); err != nil { return nil, err } if err := f.SetCellValue(sheet, cellHours, fmt.Sprintf("%.2f", hours)); err != nil { return nil, err } if err := f.SetCellValue(sheet, cellPairs, totals.PairCount); err != nil { return nil, err } row++ } buf, err := f.WriteToBuffer() if err != nil { return nil, err } return buf.Bytes(), nil }