package report import ( "context" "fmt" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "go.uber.org/zap" ) type BranchIntervalRow struct { Period string `csv:"Period"` BranchName string `csv:"CompanyName"` CompanyName string `csv:"CompanyName"` TotalBets int64 `csv:"Total Bets"` TotalStake float32 `csv:"Total Stake"` DeductedStake float32 `csv:"Deducted Stake"` TotalCashOut float32 `csv:"Total CashOut"` TotalCashBacks float32 `csv:"Total CashBacks"` NumberOfUnsettled int64 `csv:"Number Of Unsettled"` TotalUnsettledAmount float32 `csv:"Total Unsettled Amount"` TotalCashiers int64 `csv:"Total Cashiers"` } func (s *Service) GenerateBranchIntervalReport(ctx context.Context, request domain.ReportRequestDetail) (string, error) { if request.Metadata.Interval == nil { s.mongoLogger.Error("[GenerateBranchIntervalReport] Metadata interval is empty") return "", domain.ErrInvalidInterval } interval, err := domain.ParseDateInterval(*request.Metadata.Interval) if err != nil { s.mongoLogger.Error("[GenerateBranchIntervalReport] Failed to parse date interval", zap.String("interval", *request.Metadata.Interval), zap.Error(err), ) return "", domain.ErrInvalidInterval } stats, err := s.statService.GetBranchStatsByInterval(ctx, domain.BranchStatFilter{ Interval: domain.ValidDateInterval{ Value: interval, Valid: true, }, CompanyID: request.CompanyID, BranchID: domain.ConvertInt64Ptr(request.Metadata.BranchID), }) if err != nil { s.mongoLogger.Error("[GenerateBranchIntervalReport] Failed to fetch branch stats", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("fetching branch stats: %w", err) } var rows [][]string var headers []string for _, stat := range stats { endDate, err := domain.GetEndDateFromInterval(interval, stat.IntervalStart) if err != nil { s.mongoLogger.Error("[GenerateBranchIntervalReport] Failed to get end date from interval", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("invalid interval end date: %w", err) } period := fmt.Sprintf("%s to %s", stat.IntervalStart.Format("2006-01-02"), endDate.Format("2006-01-02"), ) r := BranchIntervalRow{ Period: period, BranchName: stat.BranchName, CompanyName: stat.CompanyName, TotalBets: stat.TotalBets, TotalStake: stat.TotalStake.Float32(), DeductedStake: stat.DeductedStake.Float32(), TotalCashOut: stat.TotalCashOut.Float32(), TotalCashBacks: stat.TotalCashBacks.Float32(), NumberOfUnsettled: stat.NumberOfUnsettled, TotalUnsettledAmount: stat.TotalUnsettledAmount.Float32(), TotalCashiers: stat.TotalCashiers, } if headers == nil { headers, _ = StructToCSVRow(r) rows = append(rows, headers) } _, row := StructToCSVRow(r) rows = append(rows, row) } return s.WriteCSV(rows, "branch_interval") }