- Introduced BetStatStore, BranchStatStore, and WalletStatStore interfaces for handling statistics. - Implemented repository methods for fetching and updating bet, branch, and wallet statistics. - Created reporting services for generating interval reports for bets, branches, companies, and wallets. - Enhanced CSV writing functionality to support dynamic struct to CSV conversion. - Added cron jobs for periodic updates of branch and wallet statistics. - Updated wallet handler to include transaction statistics in the response.
100 lines
3.0 KiB
Go
100 lines
3.0 KiB
Go
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")
|
|
}
|