package report import ( "context" "fmt" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "go.uber.org/zap" ) type CompanyIntervalRow struct { Period string `csv:"Period"` 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"` TotalAdmins int64 `csv:"Total Admins"` TotalManagers int64 `csv:"Total Managers"` TotalCashiers int64 `csv:"Total Cashiers"` TotalCustomers int64 `csv:"Total Customers"` TotalApprovers int64 `csv:"Total Approvers"` TotalBranches int64 `csv:"Total Branches"` } func (s *Service) GenerateCompanyIntervalReport(ctx context.Context, request domain.ReportRequestDetail) (string, error) { // Only a super-admin is allowed to generate this type of report if request.RequesterRole.Valid && request.RequesterRole.Value != domain.RoleSuperAdmin { s.mongoLogger.Error("[GenerateCompanyIntervalReport] Unauthorized user report") return "", ErrUnauthorizedUserReport } if request.Metadata.Interval == nil { s.mongoLogger.Error("[GenerateCompanyIntervalReport] Metadata interval is empty") return "", domain.ErrInvalidInterval } interval, err := domain.ParseDateInterval(*request.Metadata.Interval) if err != nil { s.mongoLogger.Error("[GenerateCompanyIntervalReport] Failed to parse date interval", zap.String("interval", *request.Metadata.Interval), zap.Error(err), ) return "", domain.ErrInvalidInterval } stats, err := s.statService.GetCompanyStatsByInterval(ctx, domain.CompanyStatFilter{ Interval: domain.ValidDateInterval{ Value: interval, Valid: true, }, }) if err != nil { s.mongoLogger.Error("[GenerateCompanyIntervalReport] Failed to fetch company stats", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("fetching company 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("[GenerateCompanyIntervalReport] 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 := CompanyIntervalRow{ Period: period, 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(), TotalAdmins: stat.TotalAdmins, TotalManagers: stat.TotalManagers, TotalCashiers: stat.TotalCashiers, TotalCustomers: stat.TotalCustomers, TotalApprovers: stat.TotalApprovers, TotalBranches: stat.TotalBranches, } if headers == nil { headers, _ = StructToCSVRow(r) rows = append(rows, headers) } _, row := StructToCSVRow(r) rows = append(rows, row) } return s.WriteCSV(rows, "company_interval") }