Yimaru-BackEnd/internal/services/report/csv.go
Samuel Tariku 0ffba57ec5 feat: Refactor report generation and management
- Removed detailed event routes from the API.
- Added new report request routes for creating and fetching report requests.
- Introduced new domain models for report requests, including metadata and status handling.
- Implemented report request processing logic, including CSV generation for event interval reports.
- Enhanced company statistics handling with new domain models and service methods.
- Updated repository interfaces and implementations to support new report functionalities.
- Added error handling and logging for report file operations and notifications.
2025-10-28 00:51:52 +03:00

105 lines
2.8 KiB
Go

package report
import (
"context"
"encoding/csv"
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/google/uuid"
"go.uber.org/zap"
)
var (
ErrReportFileNotFound = errors.New("failed to find report file")
ErrReportFileError = errors.New("unknown error with report file")
ErrReportNotComplete = errors.New("report is not completed")
ErrReportFilePathInvalid = errors.New("report file path is invalid")
)
func (s *Service) WriteCSV(rows [][]string, filePrefix string) (string, error) {
if len(rows) == 0 {
s.mongoLogger.Error("[WriteCSV] CSV with no data",
zap.String("file_prefix", filePrefix),
)
return "", errors.New("no data to write")
}
filename := fmt.Sprintf("%s_%s_%s.csv",
filePrefix,
time.Now().Format("2006-01-02_15-04-05"),
uuid.NewString()[:8],
)
filePath := filepath.Join(s.cfg.ReportExportPath, filename)
file, err := os.Create(filePath)
if err != nil {
s.mongoLogger.Error("[WriteCSV] Failed to create file",
zap.String("file", filename),
zap.String("path", s.cfg.ReportExportPath),
zap.Error(err),
)
return "", fmt.Errorf("create csv: %w", err)
}
defer file.Close()
writer := csv.NewWriter(file)
if err := writer.WriteAll(rows); err != nil {
s.mongoLogger.Error("[WriteCSV] Error while writing csv",
zap.String("file", filename),
zap.String("path", s.cfg.ReportExportPath),
zap.Error(err),
)
return "", fmt.Errorf("write csv: %w", err)
}
return filePath, nil
}
func (s *Service) CheckAndFetchReportFile(ctx context.Context, ID int64) (string, error) {
report, err := s.GetReportRequestByID(ctx, ID)
if err != nil {
s.mongoLogger.Error("[CheckAndFetchReportFile] Failed to get report request by id",
zap.Error(err),
)
return "", fmt.Errorf("failed to get report request:%w", err)
}
if report.Status != domain.SuccessReportRequest {
s.mongoLogger.Error("[CheckAndFetchReportFile] Attempted download of report that isn't completed",
zap.String("status", string(report.Status)),
)
return "", ErrReportNotComplete
}
if !report.FilePath.Valid {
s.mongoLogger.Error("[CheckAndFetchReportFile] File Path is invalid even though the report is a success",
zap.String("file path", report.FilePath.Value),
)
return "", ErrReportFilePathInvalid
}
// Check if the report file exists
if _, err := os.Stat(report.FilePath.Value); err != nil {
if os.IsNotExist(err) {
s.mongoLogger.Error("[CheckAndFetchReportFile] Unable to find report file",
zap.String("file path", report.FilePath.Value),
)
return "", ErrReportFileNotFound
}
s.mongoLogger.Error("[CheckAndFetchReportFile] Unable to check report file",
zap.String("file path", report.FilePath.Value),
zap.Error(err),
)
return "", ErrReportFileError
}
return report.FilePath.Value, nil
}