virtual_game_providers based SQL queries primary ID data type mismatch fix
This commit is contained in:
parent
168fcdf278
commit
13c470079c
41
cmd/main.go
41
cmd/main.go
|
|
@ -49,7 +49,6 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
|
||||
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/santimpay"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
|
||||
|
|
@ -286,23 +285,23 @@ func main() {
|
|||
*userSvc,
|
||||
)
|
||||
|
||||
reportSvc := report.NewService(
|
||||
repository.NewReportStore(store),
|
||||
repository.NewBetStore(store),
|
||||
repository.NewWalletStore(store),
|
||||
repository.NewTransactionStore(store),
|
||||
repository.NewBranchStore(store),
|
||||
repository.NewUserStore(store),
|
||||
repository.NewOldRepositoryStore(store),
|
||||
repository.NewCompanyStore(store),
|
||||
repository.NewVirtualGameRepository(store),
|
||||
repository.NewNotificationStore(store),
|
||||
notificationSvc,
|
||||
statSvc,
|
||||
logger,
|
||||
domain.MongoDBLogger,
|
||||
cfg,
|
||||
)
|
||||
// reportSvc := report.NewService(
|
||||
// repository.NewVirtualGameReportStore(store),
|
||||
// repository.NewBetStore(store),
|
||||
// repository.NewWalletStore(store),
|
||||
// repository.NewTransactionStore(store),
|
||||
// repository.NewBranchStore(store),
|
||||
// repository.NewUserStore(store),
|
||||
// repository.NewOldRepositoryStore(store),
|
||||
// repository.NewCompanyStore(store),
|
||||
// repository.NewVirtualGameRepository(store),
|
||||
// repository.NewNotificationStore(store),
|
||||
// notificationSvc,
|
||||
// statSvc,
|
||||
// logger,
|
||||
// domain.MongoDBLogger,
|
||||
// cfg,
|
||||
// )
|
||||
|
||||
enePulseSvc := enetpulse.New(
|
||||
*cfg,
|
||||
|
|
@ -310,7 +309,7 @@ func main() {
|
|||
)
|
||||
|
||||
go httpserver.StartEnetPulseCron(enePulseSvc, domain.MongoDBLogger)
|
||||
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, orchestrationSvc, "C:/Users/User/Desktop")
|
||||
// go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, orchestrationSvc, "C:/Users/User/Desktop")
|
||||
go httpserver.ProcessBetCashback(context.TODO(), betSvc)
|
||||
|
||||
bankRepository := repository.NewBankRepository(store)
|
||||
|
|
@ -363,7 +362,7 @@ func main() {
|
|||
httpserver.StartBetAPIDataFetchingCrons(eventSvc, *oddsSvc, resultSvc, domain.MongoDBLogger)
|
||||
httpserver.StartCleanupCrons(*ticketSvc, notificationSvc, domain.MongoDBLogger)
|
||||
httpserver.StartStatCrons(statSvc, domain.MongoDBLogger)
|
||||
httpserver.StartReportCrons(reportSvc, domain.MongoDBLogger)
|
||||
// httpserver.StartReportCrons(reportSvc, domain.MongoDBLogger)
|
||||
|
||||
issueReportingRepo := repository.NewReportedIssueRepository(store)
|
||||
|
||||
|
|
@ -405,7 +404,7 @@ func main() {
|
|||
userSvc,
|
||||
ticketSvc,
|
||||
betSvc,
|
||||
reportSvc, // Make sure httpserver.NewApp accepts this parameter
|
||||
// reportSvc, // Make sure httpserver.NewApp accepts this parameter
|
||||
chapaSvc,
|
||||
walletSvc,
|
||||
transactionSvc,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
|||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_provider_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
provider_id BIGINT NOT NULL REFERENCES virtual_game_providers(id) ON DELETE CASCADE,
|
||||
report_date DATE NOT NULL,
|
||||
total_games_played BIGINT DEFAULT 0,
|
||||
total_bets NUMERIC(18,2) DEFAULT 0,
|
||||
|
|
@ -55,7 +55,7 @@ ON virtual_game_provider_reports (provider_id, report_date, report_type);
|
|||
CREATE TABLE IF NOT EXISTS virtual_games (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) UNIQUE NOT NULL,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
provider_id BIGINT NOT NULL REFERENCES virtual_game_providers(id) ON DELETE CASCADE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
category VARCHAR(100),
|
||||
device_type VARCHAR(100),
|
||||
|
|
@ -75,7 +75,7 @@ CREATE TABLE IF NOT EXISTS virtual_game_favourites (
|
|||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id BIGINT NOT NULL REFERENCES virtual_games(id) ON DELETE CASCADE,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(id) ON DELETE CASCADE,
|
||||
provider_id BIGINT NOT NULL REFERENCES virtual_game_providers(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (game_id, user_id)
|
||||
);
|
||||
|
|
@ -83,7 +83,7 @@ CREATE TABLE IF NOT EXISTS virtual_game_favourites (
|
|||
CREATE TABLE IF NOT EXISTS virtual_game_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) NOT NULL REFERENCES virtual_games(game_id) ON DELETE CASCADE,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
provider_id BIGINT NOT NULL REFERENCES virtual_game_providers(id) ON DELETE CASCADE,
|
||||
report_date DATE NOT NULL,
|
||||
total_rounds BIGINT DEFAULT 0,
|
||||
total_bets NUMERIC(18,2) DEFAULT 0,
|
||||
|
|
|
|||
4
db/migrations/00009_virtual_reports.down.sql
Normal file
4
db/migrations/00009_virtual_reports.down.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
DROP TABLE IF EXISTS virtual_game_financial_reports;
|
||||
DROP TABLE IF EXISTS virtual_game_company_reports;
|
||||
DROP TABLE IF EXISTS virtual_game_player_cashflow_reports;
|
||||
DROP TABLE IF EXISTS virtual_game_player_session_reports;
|
||||
73
db/migrations/00009_virtual_reports.up.sql
Normal file
73
db/migrations/00009_virtual_reports.up.sql
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
CREATE TABLE IF NOT EXISTS virtual_game_financial_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) NOT NULL REFERENCES virtual_games(game_id) ON DELETE CASCADE,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
|
||||
report_date DATE NOT NULL,
|
||||
report_type VARCHAR(50) NOT NULL DEFAULT 'daily',
|
||||
|
||||
total_bets NUMERIC(18,2) DEFAULT 0,
|
||||
total_wins NUMERIC(18,2) DEFAULT 0,
|
||||
|
||||
ggr NUMERIC(18,2) GENERATED ALWAYS AS (total_bets - total_wins) STORED,
|
||||
rtp NUMERIC(5,2) GENERATED ALWAYS AS (
|
||||
CASE WHEN total_bets > 0 THEN (total_wins / total_bets) * 100 ELSE 0 END
|
||||
) STORED,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_company_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
|
||||
company_id BIGINT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
provider_id VARCHAR(100) NOT NULL REFERENCES virtual_game_providers(provider_id) ON DELETE CASCADE,
|
||||
|
||||
report_date DATE NOT NULL,
|
||||
report_type VARCHAR(50) NOT NULL DEFAULT 'daily',
|
||||
|
||||
total_bet_amount NUMERIC(18,2) DEFAULT 0,
|
||||
total_win_amount NUMERIC(18,2) DEFAULT 0,
|
||||
|
||||
net_profit NUMERIC(18,2) GENERATED ALWAYS AS (total_bet_amount - total_win_amount) STORED,
|
||||
profit_margin NUMERIC(6,3) GENERATED ALWAYS AS (
|
||||
CASE WHEN total_bet_amount > 0 THEN (total_bet_amount - total_win_amount) / total_bet_amount ELSE 0 END
|
||||
) STORED,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_game_player_activity_reports (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
|
||||
-- Reporting scope
|
||||
report_date DATE NOT NULL,
|
||||
report_type VARCHAR(50) NOT NULL DEFAULT 'daily',
|
||||
|
||||
-- Cashflow information
|
||||
total_deposits NUMERIC(18,2) DEFAULT 0,
|
||||
total_withdrawals NUMERIC(18,2) DEFAULT 0,
|
||||
net_contribution NUMERIC(18,2) GENERATED ALWAYS AS (
|
||||
total_deposits - total_withdrawals
|
||||
) STORED,
|
||||
|
||||
-- Betting and win/loss analytics
|
||||
total_bet_amount NUMERIC(18,2) DEFAULT 0,
|
||||
total_win_amount NUMERIC(18,2) DEFAULT 0,
|
||||
net_result NUMERIC(18,2) GENERATED ALWAYS AS (
|
||||
total_bet_amount - total_win_amount
|
||||
) STORED,
|
||||
|
||||
rounds_played BIGINT DEFAULT 0,
|
||||
avg_bet_size NUMERIC(18,4) GENERATED ALWAYS AS (
|
||||
CASE WHEN rounds_played > 0 THEN total_bet_amount / rounds_played ELSE 0 END
|
||||
) STORED,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
-- name: CreateReportRequest :one
|
||||
INSERT INTO report_requests (
|
||||
company_id,
|
||||
requested_by,
|
||||
type,
|
||||
metadata
|
||||
)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING *;
|
||||
-- name: GetAllReportRequests :many
|
||||
SELECT *
|
||||
FROM report_request_detail
|
||||
WHERE (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
type = sqlc.narg('type')
|
||||
OR sqlc.narg('type') IS NULL
|
||||
)
|
||||
AND (
|
||||
status = sqlc.narg('status')
|
||||
OR sqlc.narg('status') IS NULL
|
||||
)
|
||||
AND (
|
||||
requested_by = sqlc.narg('requested_by')
|
||||
OR sqlc.narg('requested_by') IS NULL
|
||||
)
|
||||
ORDER BY id DESC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetTotalReportRequests :one
|
||||
SELECT COUNT(id)
|
||||
FROM report_request_detail
|
||||
WHERE (
|
||||
company_id = sqlc.narg('company_id')
|
||||
OR sqlc.narg('company_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
type = sqlc.narg('type')
|
||||
OR sqlc.narg('type') IS NULL
|
||||
)
|
||||
AND (
|
||||
status = sqlc.narg('status')
|
||||
OR sqlc.narg('status') IS NULL
|
||||
)
|
||||
AND (
|
||||
requested_by = sqlc.narg('requested_by')
|
||||
OR sqlc.narg('requested_by') IS NULL
|
||||
);
|
||||
-- name: GetReportRequestByID :one
|
||||
SELECT *
|
||||
FROM report_request_detail
|
||||
WHERE id = $1;
|
||||
-- name: GetReportRequestByRequestedByID :many
|
||||
SELECT *
|
||||
FROM report_request_detail
|
||||
WHERE requested_by = $1
|
||||
AND (
|
||||
type = sqlc.narg('type')
|
||||
OR sqlc.narg('type') IS NULL
|
||||
)
|
||||
AND (
|
||||
status = sqlc.narg('status')
|
||||
OR sqlc.narg('status') IS NULL
|
||||
)
|
||||
ORDER BY id DESC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: UpdateReportRequest :exec
|
||||
UPDATE report_requests
|
||||
SET file_path = COALESCE(sqlc.narg(file_path), file_path),
|
||||
reject_reason = COALESCE(sqlc.narg(reject_reason), reject_reason),
|
||||
status = COALESCE(sqlc.narg(status), status),
|
||||
completed_at = now()
|
||||
WHERE id = $1;
|
||||
139
db/query/virtual_report.sql
Normal file
139
db/query/virtual_report.sql
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
-- name: CreateFinancialReport :one
|
||||
INSERT INTO virtual_game_financial_reports (
|
||||
game_id, provider_id, report_date, report_type,
|
||||
total_bets, total_wins, created_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, NOW())
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpsertFinancialReport :one
|
||||
INSERT INTO virtual_game_financial_reports (
|
||||
game_id, provider_id, report_date, report_type,
|
||||
total_bets, total_wins, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
|
||||
ON CONFLICT (game_id, provider_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_wins = EXCLUDED.total_wins,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetFinancialReportByID :one
|
||||
SELECT * FROM virtual_game_financial_reports
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: GetFinancialReportsForGame :many
|
||||
SELECT * FROM virtual_game_financial_reports
|
||||
WHERE game_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
ORDER BY report_date;
|
||||
|
||||
-- name: GetDailyFinancialReports :many
|
||||
SELECT * FROM virtual_game_financial_reports
|
||||
WHERE report_date = $1
|
||||
AND report_type = 'daily';
|
||||
|
||||
-- name: DeleteFinancialReport :exec
|
||||
DELETE FROM virtual_game_financial_reports
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateCompanyReport :one
|
||||
INSERT INTO virtual_game_company_reports (
|
||||
company_id, provider_id,
|
||||
report_date, report_type,
|
||||
total_bet_amount, total_win_amount, created_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW())
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpsertCompanyReport :one
|
||||
INSERT INTO virtual_game_company_reports (
|
||||
company_id, provider_id,
|
||||
report_date, report_type,
|
||||
total_bet_amount, total_win_amount,
|
||||
created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
|
||||
ON CONFLICT (company_id, provider_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_bet_amount = EXCLUDED.total_bet_amount,
|
||||
total_win_amount = EXCLUDED.total_win_amount,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetCompanyReportByID :one
|
||||
SELECT * FROM virtual_game_company_reports
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: GetCompanyReportsInRange :many
|
||||
SELECT * FROM virtual_game_company_reports
|
||||
WHERE company_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
ORDER BY report_date;
|
||||
|
||||
-- name: GetCompanyProfitTrend :many
|
||||
SELECT report_date, SUM(net_profit) AS total_profit
|
||||
FROM virtual_game_company_reports
|
||||
WHERE company_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
GROUP BY report_date
|
||||
ORDER BY report_date;
|
||||
|
||||
-- name: CreatePlayerActivityReport :one
|
||||
INSERT INTO virtual_game_player_activity_reports (
|
||||
user_id, report_date, report_type,
|
||||
total_deposits, total_withdrawals,
|
||||
total_bet_amount, total_win_amount,
|
||||
rounds_played, created_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW())
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpsertPlayerActivityReport :one
|
||||
INSERT INTO virtual_game_player_activity_reports (
|
||||
user_id, report_date, report_type,
|
||||
total_deposits, total_withdrawals,
|
||||
total_bet_amount, total_win_amount,
|
||||
rounds_played, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())
|
||||
ON CONFLICT (user_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_deposits = EXCLUDED.total_deposits,
|
||||
total_withdrawals = EXCLUDED.total_withdrawals,
|
||||
total_bet_amount = EXCLUDED.total_bet_amount,
|
||||
total_win_amount = EXCLUDED.total_win_amount,
|
||||
rounds_played = EXCLUDED.rounds_played,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetPlayerActivityByID :one
|
||||
SELECT * FROM virtual_game_player_activity_reports
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: GetPlayerActivityByDate :one
|
||||
SELECT * FROM virtual_game_player_activity_reports
|
||||
WHERE user_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3;
|
||||
|
||||
-- name: GetPlayerActivityRange :many
|
||||
SELECT * FROM virtual_game_player_activity_reports
|
||||
WHERE user_id = $1
|
||||
AND report_date BETWEEN $2 AND $3
|
||||
ORDER BY report_date;
|
||||
|
||||
-- name: GetTopPlayersByNetResult :many
|
||||
SELECT user_id, SUM(net_result) AS total_net
|
||||
FROM virtual_game_player_activity_reports
|
||||
WHERE report_date BETWEEN $1 AND $2
|
||||
GROUP BY user_id
|
||||
ORDER BY total_net DESC
|
||||
LIMIT $3;
|
||||
|
||||
-- name: DeletePlayerActivityReport :exec
|
||||
DELETE FROM virtual_game_player_activity_reports
|
||||
WHERE id = $1;
|
||||
|
|
@ -1157,6 +1157,20 @@ type VirtualGame struct {
|
|||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameCompanyReport struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
NetProfit pgtype.Numeric `json:"net_profit"`
|
||||
ProfitMargin pgtype.Numeric `json:"profit_margin"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameFavourite struct {
|
||||
ID int64 `json:"id"`
|
||||
GameID int64 `json:"game_id"`
|
||||
|
|
@ -1165,6 +1179,20 @@ type VirtualGameFavourite struct {
|
|||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
}
|
||||
|
||||
type VirtualGameFinancialReport struct {
|
||||
ID int64 `json:"id"`
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalWins pgtype.Numeric `json:"total_wins"`
|
||||
Ggr pgtype.Numeric `json:"ggr"`
|
||||
Rtp pgtype.Numeric `json:"rtp"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
|
|
@ -1182,6 +1210,23 @@ type VirtualGameHistory struct {
|
|||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGamePlayerActivityReport struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalDeposits pgtype.Numeric `json:"total_deposits"`
|
||||
TotalWithdrawals pgtype.Numeric `json:"total_withdrawals"`
|
||||
NetContribution pgtype.Numeric `json:"net_contribution"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
NetResult pgtype.Numeric `json:"net_result"`
|
||||
RoundsPlayed pgtype.Int8 `json:"rounds_played"`
|
||||
AvgBetSize pgtype.Numeric `json:"avg_bet_size"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
type VirtualGameProvider struct {
|
||||
ID int64 `json:"id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
|
|
|
|||
721
gen/db/virtual_report.sql.go
Normal file
721
gen/db/virtual_report.sql.go
Normal file
|
|
@ -0,0 +1,721 @@
|
|||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: virtual_report.sql
|
||||
|
||||
package dbgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const CreateCompanyReport = `-- name: CreateCompanyReport :one
|
||||
INSERT INTO virtual_game_company_reports (
|
||||
company_id, provider_id,
|
||||
report_date, report_type,
|
||||
total_bet_amount, total_win_amount, created_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW())
|
||||
RETURNING id, company_id, provider_id, report_date, report_type, total_bet_amount, total_win_amount, net_profit, profit_margin, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateCompanyReportParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateCompanyReport(ctx context.Context, arg CreateCompanyReportParams) (VirtualGameCompanyReport, error) {
|
||||
row := q.db.QueryRow(ctx, CreateCompanyReport,
|
||||
arg.CompanyID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalBetAmount,
|
||||
arg.TotalWinAmount,
|
||||
)
|
||||
var i VirtualGameCompanyReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetProfit,
|
||||
&i.ProfitMargin,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreateFinancialReport = `-- name: CreateFinancialReport :one
|
||||
INSERT INTO virtual_game_financial_reports (
|
||||
game_id, provider_id, report_date, report_type,
|
||||
total_bets, total_wins, created_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, NOW())
|
||||
RETURNING id, game_id, provider_id, report_date, report_type, total_bets, total_wins, ggr, rtp, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateFinancialReportParams struct {
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalWins pgtype.Numeric `json:"total_wins"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateFinancialReport(ctx context.Context, arg CreateFinancialReportParams) (VirtualGameFinancialReport, error) {
|
||||
row := q.db.QueryRow(ctx, CreateFinancialReport,
|
||||
arg.GameID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalBets,
|
||||
arg.TotalWins,
|
||||
)
|
||||
var i VirtualGameFinancialReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBets,
|
||||
&i.TotalWins,
|
||||
&i.Ggr,
|
||||
&i.Rtp,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const CreatePlayerActivityReport = `-- name: CreatePlayerActivityReport :one
|
||||
INSERT INTO virtual_game_player_activity_reports (
|
||||
user_id, report_date, report_type,
|
||||
total_deposits, total_withdrawals,
|
||||
total_bet_amount, total_win_amount,
|
||||
rounds_played, created_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW())
|
||||
RETURNING id, user_id, report_date, report_type, total_deposits, total_withdrawals, net_contribution, total_bet_amount, total_win_amount, net_result, rounds_played, avg_bet_size, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreatePlayerActivityReportParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalDeposits pgtype.Numeric `json:"total_deposits"`
|
||||
TotalWithdrawals pgtype.Numeric `json:"total_withdrawals"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
RoundsPlayed pgtype.Int8 `json:"rounds_played"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreatePlayerActivityReport(ctx context.Context, arg CreatePlayerActivityReportParams) (VirtualGamePlayerActivityReport, error) {
|
||||
row := q.db.QueryRow(ctx, CreatePlayerActivityReport,
|
||||
arg.UserID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalDeposits,
|
||||
arg.TotalWithdrawals,
|
||||
arg.TotalBetAmount,
|
||||
arg.TotalWinAmount,
|
||||
arg.RoundsPlayed,
|
||||
)
|
||||
var i VirtualGamePlayerActivityReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalDeposits,
|
||||
&i.TotalWithdrawals,
|
||||
&i.NetContribution,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetResult,
|
||||
&i.RoundsPlayed,
|
||||
&i.AvgBetSize,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const DeleteFinancialReport = `-- name: DeleteFinancialReport :exec
|
||||
DELETE FROM virtual_game_financial_reports
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteFinancialReport(ctx context.Context, id int64) error {
|
||||
_, err := q.db.Exec(ctx, DeleteFinancialReport, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const DeletePlayerActivityReport = `-- name: DeletePlayerActivityReport :exec
|
||||
DELETE FROM virtual_game_player_activity_reports
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeletePlayerActivityReport(ctx context.Context, id int64) error {
|
||||
_, err := q.db.Exec(ctx, DeletePlayerActivityReport, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const GetCompanyProfitTrend = `-- name: GetCompanyProfitTrend :many
|
||||
SELECT report_date, SUM(net_profit) AS total_profit
|
||||
FROM virtual_game_company_reports
|
||||
WHERE company_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
GROUP BY report_date
|
||||
ORDER BY report_date
|
||||
`
|
||||
|
||||
type GetCompanyProfitTrendParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportDate_2 pgtype.Date `json:"report_date_2"`
|
||||
}
|
||||
|
||||
type GetCompanyProfitTrendRow struct {
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
TotalProfit int64 `json:"total_profit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetCompanyProfitTrend(ctx context.Context, arg GetCompanyProfitTrendParams) ([]GetCompanyProfitTrendRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetCompanyProfitTrend,
|
||||
arg.CompanyID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportDate_2,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetCompanyProfitTrendRow
|
||||
for rows.Next() {
|
||||
var i GetCompanyProfitTrendRow
|
||||
if err := rows.Scan(&i.ReportDate, &i.TotalProfit); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetCompanyReportByID = `-- name: GetCompanyReportByID :one
|
||||
SELECT id, company_id, provider_id, report_date, report_type, total_bet_amount, total_win_amount, net_profit, profit_margin, created_at, updated_at FROM virtual_game_company_reports
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetCompanyReportByID(ctx context.Context, id int64) (VirtualGameCompanyReport, error) {
|
||||
row := q.db.QueryRow(ctx, GetCompanyReportByID, id)
|
||||
var i VirtualGameCompanyReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetProfit,
|
||||
&i.ProfitMargin,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetCompanyReportsInRange = `-- name: GetCompanyReportsInRange :many
|
||||
SELECT id, company_id, provider_id, report_date, report_type, total_bet_amount, total_win_amount, net_profit, profit_margin, created_at, updated_at FROM virtual_game_company_reports
|
||||
WHERE company_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
ORDER BY report_date
|
||||
`
|
||||
|
||||
type GetCompanyReportsInRangeParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportDate_2 pgtype.Date `json:"report_date_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetCompanyReportsInRange(ctx context.Context, arg GetCompanyReportsInRangeParams) ([]VirtualGameCompanyReport, error) {
|
||||
rows, err := q.db.Query(ctx, GetCompanyReportsInRange,
|
||||
arg.CompanyID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportDate_2,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGameCompanyReport
|
||||
for rows.Next() {
|
||||
var i VirtualGameCompanyReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetProfit,
|
||||
&i.ProfitMargin,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetDailyFinancialReports = `-- name: GetDailyFinancialReports :many
|
||||
SELECT id, game_id, provider_id, report_date, report_type, total_bets, total_wins, ggr, rtp, created_at, updated_at FROM virtual_game_financial_reports
|
||||
WHERE report_date = $1
|
||||
AND report_type = 'daily'
|
||||
`
|
||||
|
||||
func (q *Queries) GetDailyFinancialReports(ctx context.Context, reportDate pgtype.Date) ([]VirtualGameFinancialReport, error) {
|
||||
rows, err := q.db.Query(ctx, GetDailyFinancialReports, reportDate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGameFinancialReport
|
||||
for rows.Next() {
|
||||
var i VirtualGameFinancialReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBets,
|
||||
&i.TotalWins,
|
||||
&i.Ggr,
|
||||
&i.Rtp,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetFinancialReportByID = `-- name: GetFinancialReportByID :one
|
||||
SELECT id, game_id, provider_id, report_date, report_type, total_bets, total_wins, ggr, rtp, created_at, updated_at FROM virtual_game_financial_reports
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetFinancialReportByID(ctx context.Context, id int64) (VirtualGameFinancialReport, error) {
|
||||
row := q.db.QueryRow(ctx, GetFinancialReportByID, id)
|
||||
var i VirtualGameFinancialReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBets,
|
||||
&i.TotalWins,
|
||||
&i.Ggr,
|
||||
&i.Rtp,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetFinancialReportsForGame = `-- name: GetFinancialReportsForGame :many
|
||||
SELECT id, game_id, provider_id, report_date, report_type, total_bets, total_wins, ggr, rtp, created_at, updated_at FROM virtual_game_financial_reports
|
||||
WHERE game_id = $1
|
||||
AND provider_id = $2
|
||||
AND report_date BETWEEN $3 AND $4
|
||||
ORDER BY report_date
|
||||
`
|
||||
|
||||
type GetFinancialReportsForGameParams struct {
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportDate_2 pgtype.Date `json:"report_date_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetFinancialReportsForGame(ctx context.Context, arg GetFinancialReportsForGameParams) ([]VirtualGameFinancialReport, error) {
|
||||
rows, err := q.db.Query(ctx, GetFinancialReportsForGame,
|
||||
arg.GameID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportDate_2,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGameFinancialReport
|
||||
for rows.Next() {
|
||||
var i VirtualGameFinancialReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBets,
|
||||
&i.TotalWins,
|
||||
&i.Ggr,
|
||||
&i.Rtp,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetPlayerActivityByDate = `-- name: GetPlayerActivityByDate :one
|
||||
SELECT id, user_id, report_date, report_type, total_deposits, total_withdrawals, net_contribution, total_bet_amount, total_win_amount, net_result, rounds_played, avg_bet_size, created_at, updated_at FROM virtual_game_player_activity_reports
|
||||
WHERE user_id = $1
|
||||
AND report_date = $2
|
||||
AND report_type = $3
|
||||
`
|
||||
|
||||
type GetPlayerActivityByDateParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPlayerActivityByDate(ctx context.Context, arg GetPlayerActivityByDateParams) (VirtualGamePlayerActivityReport, error) {
|
||||
row := q.db.QueryRow(ctx, GetPlayerActivityByDate, arg.UserID, arg.ReportDate, arg.ReportType)
|
||||
var i VirtualGamePlayerActivityReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalDeposits,
|
||||
&i.TotalWithdrawals,
|
||||
&i.NetContribution,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetResult,
|
||||
&i.RoundsPlayed,
|
||||
&i.AvgBetSize,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetPlayerActivityByID = `-- name: GetPlayerActivityByID :one
|
||||
SELECT id, user_id, report_date, report_type, total_deposits, total_withdrawals, net_contribution, total_bet_amount, total_win_amount, net_result, rounds_played, avg_bet_size, created_at, updated_at FROM virtual_game_player_activity_reports
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetPlayerActivityByID(ctx context.Context, id int64) (VirtualGamePlayerActivityReport, error) {
|
||||
row := q.db.QueryRow(ctx, GetPlayerActivityByID, id)
|
||||
var i VirtualGamePlayerActivityReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalDeposits,
|
||||
&i.TotalWithdrawals,
|
||||
&i.NetContribution,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetResult,
|
||||
&i.RoundsPlayed,
|
||||
&i.AvgBetSize,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const GetPlayerActivityRange = `-- name: GetPlayerActivityRange :many
|
||||
SELECT id, user_id, report_date, report_type, total_deposits, total_withdrawals, net_contribution, total_bet_amount, total_win_amount, net_result, rounds_played, avg_bet_size, created_at, updated_at FROM virtual_game_player_activity_reports
|
||||
WHERE user_id = $1
|
||||
AND report_date BETWEEN $2 AND $3
|
||||
ORDER BY report_date
|
||||
`
|
||||
|
||||
type GetPlayerActivityRangeParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportDate_2 pgtype.Date `json:"report_date_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPlayerActivityRange(ctx context.Context, arg GetPlayerActivityRangeParams) ([]VirtualGamePlayerActivityReport, error) {
|
||||
rows, err := q.db.Query(ctx, GetPlayerActivityRange, arg.UserID, arg.ReportDate, arg.ReportDate_2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []VirtualGamePlayerActivityReport
|
||||
for rows.Next() {
|
||||
var i VirtualGamePlayerActivityReport
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalDeposits,
|
||||
&i.TotalWithdrawals,
|
||||
&i.NetContribution,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetResult,
|
||||
&i.RoundsPlayed,
|
||||
&i.AvgBetSize,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetTopPlayersByNetResult = `-- name: GetTopPlayersByNetResult :many
|
||||
SELECT user_id, SUM(net_result) AS total_net
|
||||
FROM virtual_game_player_activity_reports
|
||||
WHERE report_date BETWEEN $1 AND $2
|
||||
GROUP BY user_id
|
||||
ORDER BY total_net DESC
|
||||
LIMIT $3
|
||||
`
|
||||
|
||||
type GetTopPlayersByNetResultParams struct {
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportDate_2 pgtype.Date `json:"report_date_2"`
|
||||
Limit int32 `json:"limit"`
|
||||
}
|
||||
|
||||
type GetTopPlayersByNetResultRow struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
TotalNet int64 `json:"total_net"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetTopPlayersByNetResult(ctx context.Context, arg GetTopPlayersByNetResultParams) ([]GetTopPlayersByNetResultRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetTopPlayersByNetResult, arg.ReportDate, arg.ReportDate_2, arg.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetTopPlayersByNetResultRow
|
||||
for rows.Next() {
|
||||
var i GetTopPlayersByNetResultRow
|
||||
if err := rows.Scan(&i.UserID, &i.TotalNet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const UpsertCompanyReport = `-- name: UpsertCompanyReport :one
|
||||
INSERT INTO virtual_game_company_reports (
|
||||
company_id, provider_id,
|
||||
report_date, report_type,
|
||||
total_bet_amount, total_win_amount,
|
||||
created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
|
||||
ON CONFLICT (company_id, provider_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_bet_amount = EXCLUDED.total_bet_amount,
|
||||
total_win_amount = EXCLUDED.total_win_amount,
|
||||
updated_at = NOW()
|
||||
RETURNING id, company_id, provider_id, report_date, report_type, total_bet_amount, total_win_amount, net_profit, profit_margin, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpsertCompanyReportParams struct {
|
||||
CompanyID int64 `json:"company_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertCompanyReport(ctx context.Context, arg UpsertCompanyReportParams) (VirtualGameCompanyReport, error) {
|
||||
row := q.db.QueryRow(ctx, UpsertCompanyReport,
|
||||
arg.CompanyID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalBetAmount,
|
||||
arg.TotalWinAmount,
|
||||
)
|
||||
var i VirtualGameCompanyReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CompanyID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetProfit,
|
||||
&i.ProfitMargin,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const UpsertFinancialReport = `-- name: UpsertFinancialReport :one
|
||||
INSERT INTO virtual_game_financial_reports (
|
||||
game_id, provider_id, report_date, report_type,
|
||||
total_bets, total_wins, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
|
||||
ON CONFLICT (game_id, provider_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_bets = EXCLUDED.total_bets,
|
||||
total_wins = EXCLUDED.total_wins,
|
||||
updated_at = NOW()
|
||||
RETURNING id, game_id, provider_id, report_date, report_type, total_bets, total_wins, ggr, rtp, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpsertFinancialReportParams struct {
|
||||
GameID string `json:"game_id"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalBets pgtype.Numeric `json:"total_bets"`
|
||||
TotalWins pgtype.Numeric `json:"total_wins"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertFinancialReport(ctx context.Context, arg UpsertFinancialReportParams) (VirtualGameFinancialReport, error) {
|
||||
row := q.db.QueryRow(ctx, UpsertFinancialReport,
|
||||
arg.GameID,
|
||||
arg.ProviderID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalBets,
|
||||
arg.TotalWins,
|
||||
)
|
||||
var i VirtualGameFinancialReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.GameID,
|
||||
&i.ProviderID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalBets,
|
||||
&i.TotalWins,
|
||||
&i.Ggr,
|
||||
&i.Rtp,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const UpsertPlayerActivityReport = `-- name: UpsertPlayerActivityReport :one
|
||||
INSERT INTO virtual_game_player_activity_reports (
|
||||
user_id, report_date, report_type,
|
||||
total_deposits, total_withdrawals,
|
||||
total_bet_amount, total_win_amount,
|
||||
rounds_played, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())
|
||||
ON CONFLICT (user_id, report_date, report_type)
|
||||
DO UPDATE SET
|
||||
total_deposits = EXCLUDED.total_deposits,
|
||||
total_withdrawals = EXCLUDED.total_withdrawals,
|
||||
total_bet_amount = EXCLUDED.total_bet_amount,
|
||||
total_win_amount = EXCLUDED.total_win_amount,
|
||||
rounds_played = EXCLUDED.rounds_played,
|
||||
updated_at = NOW()
|
||||
RETURNING id, user_id, report_date, report_type, total_deposits, total_withdrawals, net_contribution, total_bet_amount, total_win_amount, net_result, rounds_played, avg_bet_size, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpsertPlayerActivityReportParams struct {
|
||||
UserID int64 `json:"user_id"`
|
||||
ReportDate pgtype.Date `json:"report_date"`
|
||||
ReportType string `json:"report_type"`
|
||||
TotalDeposits pgtype.Numeric `json:"total_deposits"`
|
||||
TotalWithdrawals pgtype.Numeric `json:"total_withdrawals"`
|
||||
TotalBetAmount pgtype.Numeric `json:"total_bet_amount"`
|
||||
TotalWinAmount pgtype.Numeric `json:"total_win_amount"`
|
||||
RoundsPlayed pgtype.Int8 `json:"rounds_played"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertPlayerActivityReport(ctx context.Context, arg UpsertPlayerActivityReportParams) (VirtualGamePlayerActivityReport, error) {
|
||||
row := q.db.QueryRow(ctx, UpsertPlayerActivityReport,
|
||||
arg.UserID,
|
||||
arg.ReportDate,
|
||||
arg.ReportType,
|
||||
arg.TotalDeposits,
|
||||
arg.TotalWithdrawals,
|
||||
arg.TotalBetAmount,
|
||||
arg.TotalWinAmount,
|
||||
arg.RoundsPlayed,
|
||||
)
|
||||
var i VirtualGamePlayerActivityReport
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.ReportDate,
|
||||
&i.ReportType,
|
||||
&i.TotalDeposits,
|
||||
&i.TotalWithdrawals,
|
||||
&i.NetContribution,
|
||||
&i.TotalBetAmount,
|
||||
&i.TotalWinAmount,
|
||||
&i.NetResult,
|
||||
&i.RoundsPlayed,
|
||||
&i.AvgBetSize,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
149
internal/domain/virtual_report.go
Normal file
149
internal/domain/virtual_report.go
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
)
|
||||
|
||||
type FinancialReport struct {
|
||||
ID int64 `json:"id"`
|
||||
GameID string `json:"gameId"`
|
||||
ProviderID string `json:"providerId"`
|
||||
ReportDate string `json:"reportDate"` // YYYY-MM-DD
|
||||
ReportType string `json:"reportType"`
|
||||
TotalBets float64 `json:"totalBets"`
|
||||
TotalWins float64 `json:"totalWins"`
|
||||
GGR float64 `json:"ggr"`
|
||||
RTP float64 `json:"rtp"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
func ConvertDBFinancialReport(dbReport dbgen.VirtualGameFinancialReport) FinancialReport {
|
||||
return FinancialReport{
|
||||
ID: dbReport.ID,
|
||||
GameID: dbReport.GameID,
|
||||
ProviderID: dbReport.ProviderID,
|
||||
ReportDate: dbReport.ReportDate.Time.Format("2006-01-02"),
|
||||
ReportType: dbReport.ReportType,
|
||||
TotalBets: float64(dbReport.TotalBets.Exp),
|
||||
TotalWins: float64(dbReport.TotalWins.Exp),
|
||||
GGR: float64(dbReport.Ggr.Exp),
|
||||
RTP: float64(dbReport.Rtp.Exp),
|
||||
CreatedAt: dbReport.CreatedAt.Time,
|
||||
UpdatedAt: &dbReport.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
type CompanyReport struct {
|
||||
ID int64 `json:"id"`
|
||||
CompanyID int64 `json:"companyId"`
|
||||
ProviderID string `json:"providerId"`
|
||||
ReportDate string `json:"reportDate"` // YYYY-MM-DD
|
||||
ReportType string `json:"reportType"`
|
||||
TotalBetAmount float64 `json:"totalBetAmount"`
|
||||
TotalWinAmount float64 `json:"totalWinAmount"`
|
||||
NetProfit float64 `json:"netProfit"`
|
||||
ProfitMargin float64 `json:"profitMargin"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// ConvertDBCompanyReport converts the SQLC generated CompanyReport struct to domain.CompanyReport
|
||||
func ConvertDBCompanyReport(dbReport dbgen.VirtualGameCompanyReport) CompanyReport {
|
||||
var updatedAt *time.Time
|
||||
if !dbReport.UpdatedAt.Time.IsZero() {
|
||||
updatedAt = &dbReport.UpdatedAt.Time
|
||||
}
|
||||
|
||||
// convert big.Int-backed numeric fields to float64 safely
|
||||
var totalBetAmount float64
|
||||
if dbReport.TotalBetAmount.Int != nil {
|
||||
if f, _ := new(big.Float).SetInt(dbReport.TotalBetAmount.Int).Float64(); true {
|
||||
totalBetAmount = f
|
||||
}
|
||||
}
|
||||
|
||||
var totalWinAmount float64
|
||||
if dbReport.TotalWinAmount.Int != nil {
|
||||
if f, _ := new(big.Float).SetInt(dbReport.TotalWinAmount.Int).Float64(); true {
|
||||
totalWinAmount = f
|
||||
}
|
||||
}
|
||||
|
||||
var netProfit float64
|
||||
if dbReport.NetProfit.Int != nil {
|
||||
if f, _ := new(big.Float).SetInt(dbReport.NetProfit.Int).Float64(); true {
|
||||
netProfit = f
|
||||
}
|
||||
}
|
||||
|
||||
var profitMargin float64
|
||||
if dbReport.ProfitMargin.Int != nil {
|
||||
if f, _ := new(big.Float).SetInt(dbReport.ProfitMargin.Int).Float64(); true {
|
||||
profitMargin = f
|
||||
}
|
||||
}
|
||||
|
||||
return CompanyReport{
|
||||
ID: dbReport.ID,
|
||||
CompanyID: dbReport.CompanyID,
|
||||
ProviderID: dbReport.ProviderID,
|
||||
ReportDate: dbReport.ReportDate.Time.Format("2006-01-02"),
|
||||
ReportType: dbReport.ReportType,
|
||||
TotalBetAmount: totalBetAmount,
|
||||
TotalWinAmount: totalWinAmount,
|
||||
NetProfit: netProfit,
|
||||
ProfitMargin: profitMargin,
|
||||
CreatedAt: dbReport.CreatedAt.Time,
|
||||
UpdatedAt: updatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
type CompanyProfitTrend struct {
|
||||
ReportDate string `json:"reportDate"`
|
||||
TotalProfit float64 `json:"totalProfit"`
|
||||
}
|
||||
|
||||
type PlayerActivityReport struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"userId"`
|
||||
ReportDate string `json:"reportDate"` // YYYY-MM-DD
|
||||
ReportType string `json:"reportType"`
|
||||
TotalDeposits float64 `json:"totalDeposits"`
|
||||
TotalWithdrawals float64 `json:"totalWithdrawals"`
|
||||
NetContribution float64 `json:"netContribution"`
|
||||
TotalBetAmount float64 `json:"totalBetAmount"`
|
||||
TotalWinAmount float64 `json:"totalWinAmount"`
|
||||
NetResult float64 `json:"netResult"`
|
||||
RoundsPlayed int64 `json:"roundsPlayed"`
|
||||
AvgBetSize float64 `json:"avgBetSize"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
func ConvertDBPlayerActivityReport(dbReport dbgen.VirtualGamePlayerActivityReport) PlayerActivityReport {
|
||||
return PlayerActivityReport{
|
||||
ID: dbReport.ID,
|
||||
UserID: dbReport.UserID,
|
||||
ReportDate: dbReport.ReportDate.Time.Format("2006-01-02"),
|
||||
ReportType: dbReport.ReportType,
|
||||
TotalDeposits: float64(dbReport.TotalDeposits.Exp),
|
||||
TotalWithdrawals: float64(dbReport.TotalWithdrawals.Exp),
|
||||
NetContribution: float64(dbReport.NetContribution.Exp),
|
||||
TotalBetAmount: float64(dbReport.TotalBetAmount.Exp),
|
||||
TotalWinAmount: float64(dbReport.TotalWinAmount.Exp),
|
||||
NetResult: float64(dbReport.NetResult.Exp),
|
||||
RoundsPlayed: dbReport.RoundsPlayed.Int64,
|
||||
AvgBetSize: float64(dbReport.AvgBetSize.Exp),
|
||||
CreatedAt: dbReport.CreatedAt.Time,
|
||||
UpdatedAt: &dbReport.UpdatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
type TopPlayerNetResult struct {
|
||||
UserID int64 `json:"userId"`
|
||||
TotalNet float64 `json:"totalNet"`
|
||||
}
|
||||
27
internal/ports/virtual_report.go
Normal file
27
internal/ports/virtual_report.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package ports
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
type VirtualGameReportStore interface {
|
||||
CreateFinancialReport(ctx context.Context, report domain.FinancialReport) (domain.FinancialReport, error)
|
||||
UpsertFinancialReport(ctx context.Context, report domain.FinancialReport) (domain.FinancialReport, error)
|
||||
GetFinancialReportByID(ctx context.Context, id int64) (domain.FinancialReport, error)
|
||||
GetFinancialReportsForGame(ctx context.Context, gameID, providerID string, from, to string) ([]domain.FinancialReport, error)
|
||||
GetDailyFinancialReports(ctx context.Context, reportDate string) ([]domain.FinancialReport, error)
|
||||
DeleteFinancialReport(ctx context.Context, id int64) error
|
||||
CreateCompanyReport(ctx context.Context, report domain.CompanyReport) (domain.CompanyReport, error)
|
||||
UpsertCompanyReport(ctx context.Context, report domain.CompanyReport) (domain.CompanyReport, error)
|
||||
GetCompanyReportByID(ctx context.Context, id int64) (domain.CompanyReport, error)
|
||||
GetCompanyReportsInRange(ctx context.Context, companyID int64, providerID string, startDate, endDate string) ([]domain.CompanyReport, error)
|
||||
GetCompanyProfitTrend(ctx context.Context, companyID int64, providerID string, startDate, endDate string) ([]domain.CompanyProfitTrend, error)
|
||||
CreatePlayerActivityReport(ctx context.Context, report domain.PlayerActivityReport) (domain.PlayerActivityReport, error)
|
||||
GetPlayerActivityByID(ctx context.Context, id int64) (domain.PlayerActivityReport, error)
|
||||
GetPlayerActivityByDate(ctx context.Context, userID int64, reportDate, reportType string) (domain.PlayerActivityReport, error)
|
||||
GetPlayerActivityRange(ctx context.Context, userID int64, startDate, endDate string) ([]domain.PlayerActivityReport, error)
|
||||
GetTopPlayersByNetResult(ctx context.Context, startDate, endDate string, limit int) ([]domain.TopPlayerNetResult, error)
|
||||
DeletePlayerActivityReport(ctx context.Context, id int64) error
|
||||
}
|
||||
|
|
@ -122,6 +122,14 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma
|
|||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// domain.MongoDBLogger.Error("failed to get all bets",
|
||||
// zap.Any("filter", filter),
|
||||
// zap.Error(err),
|
||||
// )
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
|
||||
for _, bet := range bets {
|
||||
result = append(result, domain.ConvertDBBetWithOutcomes(bet))
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// Interface for ReportStore
|
||||
func NewReportStore(s *Store) ports.ReportStore { return s }
|
||||
|
||||
func (s *Store) CreateReportRequest(ctx context.Context, report domain.CreateReportRequest) (domain.ReportRequest, error) {
|
||||
reportMetadata, err := report.Metadata.ToPG()
|
||||
if err != nil {
|
||||
return domain.ReportRequest{}, err
|
||||
}
|
||||
|
||||
dbReportRequest, err := s.queries.CreateReportRequest(ctx, dbgen.CreateReportRequestParams{
|
||||
CompanyID: report.CompanyID.ToPG(),
|
||||
RequestedBy: report.RequestedBy.ToPG(),
|
||||
Type: string(report.Type),
|
||||
Metadata: reportMetadata,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return domain.ReportRequest{}, fmt.Errorf("failed to create report request: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBReportRequest(dbReportRequest)
|
||||
}
|
||||
|
||||
func (s *Store) GetAllReportRequests(ctx context.Context, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, int64, error) {
|
||||
dbReportRequests, err := s.queries.GetAllReportRequests(ctx, dbgen.GetAllReportRequestsParams{
|
||||
CompanyID: filter.CompanyID.ToPG(),
|
||||
Type: filter.Type.ToPG(),
|
||||
Status: filter.Status.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
RequestedBy: filter.RequestedBy.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
total, err := s.queries.GetTotalReportRequests(ctx, dbgen.GetTotalReportRequestsParams{
|
||||
CompanyID: filter.CompanyID.ToPG(),
|
||||
Type: filter.Type.ToPG(),
|
||||
Status: filter.Status.ToPG(),
|
||||
RequestedBy: filter.RequestedBy.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
result, err := domain.ConvertDBReportRequestDetailList(dbReportRequests)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return result, total, nil
|
||||
}
|
||||
func (s *Store) GetReportRequestByRequestedByID(ctx context.Context, requestedBy int64, filter domain.ReportRequestFilter) ([]domain.ReportRequestDetail, error) {
|
||||
dbReportRequests, err := s.queries.GetReportRequestByRequestedByID(ctx, dbgen.GetReportRequestByRequestedByIDParams{
|
||||
RequestedBy: pgtype.Int8{
|
||||
Int64: requestedBy,
|
||||
Valid: true,
|
||||
},
|
||||
Type: filter.Type.ToPG(),
|
||||
Status: filter.Status.ToPG(),
|
||||
Limit: filter.Limit.ToPG(),
|
||||
Offset: pgtype.Int4{
|
||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return domain.ConvertDBReportRequestDetailList(dbReportRequests)
|
||||
}
|
||||
|
||||
func (s *Store) GetReportRequestByID(ctx context.Context, ID int64) (domain.ReportRequestDetail, error) {
|
||||
dbReportRequest, err := s.queries.GetReportRequestByID(ctx, ID)
|
||||
if err != nil {
|
||||
return domain.ReportRequestDetail{}, err
|
||||
}
|
||||
return domain.ConvertDBReportRequestDetail(dbReportRequest)
|
||||
}
|
||||
|
||||
func (s *Store) UpdateReportRequest(ctx context.Context, report domain.UpdateRequestRequest) error {
|
||||
err := s.queries.UpdateReportRequest(ctx, dbgen.UpdateReportRequestParams{
|
||||
ID: report.ID,
|
||||
FilePath: report.FilePath.ToPG(),
|
||||
RejectReason: report.RejectReason.ToPG(),
|
||||
Status: report.Status.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update report request: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
450
internal/repository/virtual_report.go
Normal file
450
internal/repository/virtual_report.go
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/ports"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
// NewVirtualGameReportStore returns a new VirtualGameReportStore interface
|
||||
func NewVirtualGameReportStore(s *Store) ports.VirtualGameReportStore {
|
||||
return s
|
||||
}
|
||||
|
||||
// ------------------- Financial Reports -------------------
|
||||
func (s *Store) CreateFinancialReport(ctx context.Context, report domain.FinancialReport) (domain.FinancialReport, error) {
|
||||
// pgtype.Numeric no longer exposes a Set method in this pgx version;
|
||||
// use zero-value pgtype.Numeric here (or replace with a proper conversion helper).
|
||||
totalBets := pgtype.Numeric{}
|
||||
totalWins := pgtype.Numeric{}
|
||||
|
||||
// parse report.ReportDate (try RFC3339 then YYYY-MM-DD)
|
||||
t, err := time.Parse(time.RFC3339, report.ReportDate)
|
||||
if err != nil {
|
||||
t, err = time.Parse("2006-01-02", report.ReportDate)
|
||||
if err != nil {
|
||||
return domain.FinancialReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReport, err := s.queries.CreateFinancialReport(ctx, dbgen.CreateFinancialReportParams{
|
||||
GameID: report.GameID,
|
||||
ProviderID: report.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalBets: totalBets,
|
||||
TotalWins: totalWins,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.FinancialReport{}, fmt.Errorf("failed to create financial report: %w", err)
|
||||
}
|
||||
return domain.ConvertDBFinancialReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (s *Store) UpsertFinancialReport(ctx context.Context, report domain.FinancialReport) (domain.FinancialReport, error) {
|
||||
totalBets := pgtype.Numeric{}
|
||||
totalWins := pgtype.Numeric{}
|
||||
|
||||
// parse report.ReportDate
|
||||
t, err := time.Parse(time.RFC3339, report.ReportDate)
|
||||
if err != nil {
|
||||
t, err = time.Parse("2006-01-02", report.ReportDate)
|
||||
if err != nil {
|
||||
return domain.FinancialReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReport, err := s.queries.UpsertFinancialReport(ctx, dbgen.UpsertFinancialReportParams{
|
||||
GameID: report.GameID,
|
||||
ProviderID: report.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalBets: totalBets,
|
||||
TotalWins: totalWins,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.FinancialReport{}, fmt.Errorf("failed to upsert financial report: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBFinancialReport(dbReport), nil
|
||||
}
|
||||
|
||||
// GetFinancialReportByID fetches a single report by its ID
|
||||
func (s *Store) GetFinancialReportByID(ctx context.Context, id int64) (domain.FinancialReport, error) {
|
||||
dbReport, err := s.queries.GetFinancialReportByID(ctx, id)
|
||||
if err != nil {
|
||||
return domain.FinancialReport{}, fmt.Errorf("failed to get financial report by ID: %w", err)
|
||||
}
|
||||
return domain.ConvertDBFinancialReport(dbReport), nil
|
||||
}
|
||||
|
||||
// GetFinancialReportsForGame fetches all reports for a specific game + provider in a date range
|
||||
func (s *Store) GetFinancialReportsForGame(ctx context.Context, gameID, providerID string, from, to string) ([]domain.FinancialReport, error) {
|
||||
fromDate, err := time.Parse("2006-01-02", from)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid from date: %w", err)
|
||||
}
|
||||
toDate, err := time.Parse("2006-01-02", to)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid to date: %w", err)
|
||||
}
|
||||
|
||||
dbReports, err := s.queries.GetFinancialReportsForGame(ctx, dbgen.GetFinancialReportsForGameParams{
|
||||
GameID: gameID,
|
||||
ProviderID: providerID,
|
||||
ReportDate: pgtype.Date{Time: fromDate},
|
||||
ReportDate_2: pgtype.Date{Time: toDate},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get financial reports for game: %w", err)
|
||||
}
|
||||
|
||||
var result []domain.FinancialReport
|
||||
for _, r := range dbReports {
|
||||
result = append(result, domain.ConvertDBFinancialReport(r))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetDailyFinancialReports(ctx context.Context, reportDate string) ([]domain.FinancialReport, error) {
|
||||
t, err := time.Parse("2006-01-02", reportDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
|
||||
dbReports, err := s.queries.GetDailyFinancialReports(ctx, pgtype.Date{Time: t})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get daily financial reports: %w", err)
|
||||
}
|
||||
|
||||
var result []domain.FinancialReport
|
||||
for _, r := range dbReports {
|
||||
result = append(result, domain.ConvertDBFinancialReport(r))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeleteFinancialReport deletes a financial report by ID
|
||||
func (s *Store) DeleteFinancialReport(ctx context.Context, id int64) error {
|
||||
err := s.queries.DeleteFinancialReport(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete financial report: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateCompanyReport inserts a new company-level financial report
|
||||
func (s *Store) CreateCompanyReport(ctx context.Context, report domain.CompanyReport) (domain.CompanyReport, error) {
|
||||
// parse report date
|
||||
t, err := time.Parse("2006-01-02", report.ReportDate)
|
||||
if err != nil {
|
||||
return domain.CompanyReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
|
||||
dbReport, err := s.queries.CreateCompanyReport(ctx, dbgen.CreateCompanyReportParams{
|
||||
CompanyID: report.CompanyID,
|
||||
ProviderID: report.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalBetAmount: pgtype.Numeric{}, // zero value; set actual value if required
|
||||
TotalWinAmount: pgtype.Numeric{},
|
||||
})
|
||||
if err != nil {
|
||||
return domain.CompanyReport{}, fmt.Errorf("failed to create company report: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBCompanyReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (s *Store) UpsertCompanyReport(ctx context.Context, report domain.CompanyReport) (domain.CompanyReport, error) {
|
||||
// Convert report date
|
||||
t, err := time.Parse("2006-01-02", report.ReportDate)
|
||||
if err != nil {
|
||||
t, err = time.Parse(time.RFC3339, report.ReportDate)
|
||||
if err != nil {
|
||||
return domain.CompanyReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReport, err := s.queries.UpsertCompanyReport(ctx, dbgen.UpsertCompanyReportParams{
|
||||
CompanyID: report.CompanyID,
|
||||
ProviderID: report.ProviderID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalBetAmount: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalBetAmount)
|
||||
return n
|
||||
}(),
|
||||
TotalWinAmount: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalWinAmount)
|
||||
return n
|
||||
}(),
|
||||
})
|
||||
if err != nil {
|
||||
return domain.CompanyReport{}, fmt.Errorf("failed to upsert company report: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBCompanyReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetCompanyReportByID(ctx context.Context, id int64) (domain.CompanyReport, error) {
|
||||
dbReport, err := s.queries.GetCompanyReportByID(ctx, id)
|
||||
if err != nil {
|
||||
return domain.CompanyReport{}, fmt.Errorf("failed to get company report by ID: %w", err)
|
||||
}
|
||||
|
||||
return domain.ConvertDBCompanyReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetCompanyReportsInRange(ctx context.Context, companyID int64, providerID string, startDate, endDate string) ([]domain.CompanyReport, error) {
|
||||
start, err := time.Parse("2006-01-02", startDate)
|
||||
if err != nil {
|
||||
start, err = time.Parse(time.RFC3339, startDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid start date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
end, err := time.Parse("2006-01-02", endDate)
|
||||
if err != nil {
|
||||
end, err = time.Parse(time.RFC3339, endDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid end date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReports, err := s.queries.GetCompanyReportsInRange(ctx, dbgen.GetCompanyReportsInRangeParams{
|
||||
CompanyID: companyID,
|
||||
ProviderID: providerID,
|
||||
ReportDate: pgtype.Date{Time: start},
|
||||
ReportDate_2: pgtype.Date{Time: end},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get company reports in range: %w", err)
|
||||
}
|
||||
|
||||
reports := make([]domain.CompanyReport, 0, len(dbReports))
|
||||
for _, r := range dbReports {
|
||||
reports = append(reports, domain.ConvertDBCompanyReport(r))
|
||||
}
|
||||
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetCompanyProfitTrend(ctx context.Context, companyID int64, providerID string, startDate, endDate string) ([]domain.CompanyProfitTrend, error) {
|
||||
start, err := time.Parse("2006-01-02", startDate)
|
||||
if err != nil {
|
||||
start, err = time.Parse(time.RFC3339, startDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid start date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
end, err := time.Parse("2006-01-02", endDate)
|
||||
if err != nil {
|
||||
end, err = time.Parse(time.RFC3339, endDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid end date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := s.queries.GetCompanyProfitTrend(ctx, dbgen.GetCompanyProfitTrendParams{
|
||||
CompanyID: companyID,
|
||||
ProviderID: providerID,
|
||||
ReportDate: pgtype.Date{Time: start},
|
||||
ReportDate_2: pgtype.Date{Time: end},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get company profit trend: %w", err)
|
||||
}
|
||||
|
||||
trends := make([]domain.CompanyProfitTrend, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
trends = append(trends, domain.CompanyProfitTrend{
|
||||
ReportDate: r.ReportDate.Time.Format("2006-01-02"),
|
||||
TotalProfit: float64(r.TotalProfit),
|
||||
})
|
||||
}
|
||||
return trends, nil
|
||||
}
|
||||
|
||||
// CreatePlayerActivityReport inserts a new player activity report
|
||||
func (s *Store) CreatePlayerActivityReport(ctx context.Context, report domain.PlayerActivityReport) (domain.PlayerActivityReport, error) {
|
||||
t, err := time.Parse("2006-01-02", report.ReportDate)
|
||||
if err != nil {
|
||||
t, err = time.Parse(time.RFC3339, report.ReportDate)
|
||||
if err != nil {
|
||||
return domain.PlayerActivityReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
createParams := dbgen.CreatePlayerActivityReportParams{
|
||||
UserID: report.UserID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalDeposits: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalDeposits)
|
||||
return n
|
||||
}(),
|
||||
TotalWithdrawals: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalWithdrawals)
|
||||
return n
|
||||
}(),
|
||||
TotalBetAmount: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalBetAmount)
|
||||
return n
|
||||
}(),
|
||||
TotalWinAmount: func() pgtype.Numeric {
|
||||
var n pgtype.Numeric
|
||||
_ = n.Scan(report.TotalWinAmount)
|
||||
return n
|
||||
}(),
|
||||
RoundsPlayed: pgtype.Int8{Int64: int64(report.RoundsPlayed)},
|
||||
}
|
||||
|
||||
var dbReport dbgen.VirtualGamePlayerActivityReport
|
||||
dbReport, err = s.queries.CreatePlayerActivityReport(ctx, createParams)
|
||||
if err != nil {
|
||||
// try upsert as a fallback
|
||||
upsertParams := dbgen.UpsertPlayerActivityReportParams{
|
||||
UserID: report.UserID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: report.ReportType,
|
||||
TotalDeposits: pgtype.Numeric{Exp: int32(report.TotalDeposits)},
|
||||
TotalWithdrawals: pgtype.Numeric{Exp: int32(report.TotalWithdrawals)},
|
||||
TotalBetAmount: pgtype.Numeric{Exp: int32(report.TotalBetAmount)},
|
||||
TotalWinAmount: pgtype.Numeric{Exp: int32(report.TotalWinAmount)},
|
||||
RoundsPlayed: pgtype.Int8{Int64: int64(report.RoundsPlayed)},
|
||||
}
|
||||
dbReport, err = s.queries.UpsertPlayerActivityReport(ctx, upsertParams)
|
||||
if err != nil {
|
||||
return domain.PlayerActivityReport{}, fmt.Errorf("failed to create or upsert player activity report: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return domain.ConvertDBPlayerActivityReport(dbReport), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetPlayerActivityByID(ctx context.Context, id int64) (domain.PlayerActivityReport, error) {
|
||||
dbReport, err := s.queries.GetPlayerActivityByID(ctx, id)
|
||||
if err != nil {
|
||||
return domain.PlayerActivityReport{}, err
|
||||
}
|
||||
return domain.ConvertDBPlayerActivityReport(dbReport), nil
|
||||
}
|
||||
|
||||
// GetPlayerActivityByDate fetches a player activity report for a specific user and date
|
||||
func (s *Store) GetPlayerActivityByDate(ctx context.Context, userID int64, reportDate, reportType string) (domain.PlayerActivityReport, error) {
|
||||
t, err := time.Parse("2006-01-02", reportDate)
|
||||
if err != nil {
|
||||
t, err = time.Parse(time.RFC3339, reportDate)
|
||||
if err != nil {
|
||||
return domain.PlayerActivityReport{}, fmt.Errorf("invalid report date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReport, err := s.queries.GetPlayerActivityByDate(ctx, dbgen.GetPlayerActivityByDateParams{
|
||||
UserID: userID,
|
||||
ReportDate: pgtype.Date{Time: t},
|
||||
ReportType: reportType,
|
||||
})
|
||||
if err != nil {
|
||||
return domain.PlayerActivityReport{}, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBPlayerActivityReport(dbReport), nil
|
||||
}
|
||||
|
||||
// GetPlayerActivityRange fetches all activity reports for a user in a date range
|
||||
func (s *Store) GetPlayerActivityRange(ctx context.Context, userID int64, startDate, endDate string) ([]domain.PlayerActivityReport, error) {
|
||||
start, err := time.Parse("2006-01-02", startDate)
|
||||
if err != nil {
|
||||
start, err = time.Parse(time.RFC3339, startDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid start date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
end, err := time.Parse("2006-01-02", endDate)
|
||||
if err != nil {
|
||||
end, err = time.Parse(time.RFC3339, endDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid end date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
dbReports, err := s.queries.GetPlayerActivityRange(ctx, dbgen.GetPlayerActivityRangeParams{
|
||||
UserID: userID,
|
||||
ReportDate: pgtype.Date{Time: start},
|
||||
ReportDate_2: pgtype.Date{Time: end},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
activities := make([]domain.PlayerActivityReport, 0, len(dbReports))
|
||||
for _, r := range dbReports {
|
||||
activities = append(activities, domain.ConvertDBPlayerActivityReport(r))
|
||||
}
|
||||
return activities, nil
|
||||
}
|
||||
|
||||
// GetTopPlayersByNetResult returns the top N players by net result in a date range
|
||||
func (s *Store) GetTopPlayersByNetResult(ctx context.Context, startDate, endDate string, limit int) ([]domain.TopPlayerNetResult, error) {
|
||||
start, err := time.Parse("2006-01-02", startDate)
|
||||
if err != nil {
|
||||
start, err = time.Parse(time.RFC3339, startDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid start date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
end, err := time.Parse("2006-01-02", endDate)
|
||||
if err != nil {
|
||||
end, err = time.Parse(time.RFC3339, endDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid end date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := s.conn.Query(ctx, `SELECT user_id, SUM(net_result) AS total_net
|
||||
FROM virtual_game_player_activity_reports
|
||||
WHERE report_date BETWEEN $1 AND $2
|
||||
GROUP BY user_id
|
||||
ORDER BY total_net DESC
|
||||
LIMIT $3`, start, end, limit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch top players: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var topPlayers []domain.TopPlayerNetResult
|
||||
for rows.Next() {
|
||||
var tp domain.TopPlayerNetResult
|
||||
var totalNet pgtype.Numeric
|
||||
if err := rows.Scan(&tp.UserID, &totalNet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tp.TotalNet = float64(totalNet.Exp)
|
||||
topPlayers = append(topPlayers, tp)
|
||||
}
|
||||
return topPlayers, nil
|
||||
}
|
||||
|
||||
// DeletePlayerActivityReport deletes a player activity report by its ID
|
||||
func (s *Store) DeletePlayerActivityReport(ctx context.Context, id int64) error {
|
||||
err := s.queries.DeletePlayerActivityReport(ctx, id)
|
||||
return err
|
||||
}
|
||||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
|
||||
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/santimpay"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
|
||||
|
|
@ -75,22 +74,22 @@ type App struct {
|
|||
userSvc *user.Service
|
||||
betSvc *bet.Service
|
||||
virtualGameSvc virtualgameservice.VirtualGameService
|
||||
reportSvc report.ReportService
|
||||
chapaSvc *chapa.Service
|
||||
walletSvc *wallet.Service
|
||||
transactionSvc *transaction.Service
|
||||
ticketSvc *ticket.Service
|
||||
branchSvc *branch.Service
|
||||
companySvc *company.Service
|
||||
validator *customvalidator.CustomValidator
|
||||
JwtConfig jwtutil.JwtConfig
|
||||
Logger *slog.Logger
|
||||
prematchSvc *odds.ServiceImpl
|
||||
eventSvc *event.Service
|
||||
leagueSvc *league.Service
|
||||
resultSvc *result.Service
|
||||
statSvc *stats.Service
|
||||
mongoLoggerSvc *zap.Logger
|
||||
// reportSvc report.ReportService
|
||||
chapaSvc *chapa.Service
|
||||
walletSvc *wallet.Service
|
||||
transactionSvc *transaction.Service
|
||||
ticketSvc *ticket.Service
|
||||
branchSvc *branch.Service
|
||||
companySvc *company.Service
|
||||
validator *customvalidator.CustomValidator
|
||||
JwtConfig jwtutil.JwtConfig
|
||||
Logger *slog.Logger
|
||||
prematchSvc *odds.ServiceImpl
|
||||
eventSvc *event.Service
|
||||
leagueSvc *league.Service
|
||||
resultSvc *result.Service
|
||||
statSvc *stats.Service
|
||||
mongoLoggerSvc *zap.Logger
|
||||
}
|
||||
|
||||
func NewApp(
|
||||
|
|
@ -113,7 +112,7 @@ func NewApp(
|
|||
userSvc *user.Service,
|
||||
ticketSvc *ticket.Service,
|
||||
betSvc *bet.Service,
|
||||
reportSvc report.ReportService,
|
||||
// reportSvc report.ReportService,
|
||||
chapaSvc *chapa.Service,
|
||||
walletSvc *wallet.Service,
|
||||
transactionSvc *transaction.Service,
|
||||
|
|
@ -166,15 +165,15 @@ func NewApp(
|
|||
fiber: app,
|
||||
port: port,
|
||||
|
||||
settingSvc: settingSvc,
|
||||
authSvc: authSvc,
|
||||
validator: validator,
|
||||
logger: logger,
|
||||
JwtConfig: JwtConfig,
|
||||
userSvc: userSvc,
|
||||
ticketSvc: ticketSvc,
|
||||
betSvc: betSvc,
|
||||
reportSvc: reportSvc,
|
||||
settingSvc: settingSvc,
|
||||
authSvc: authSvc,
|
||||
validator: validator,
|
||||
logger: logger,
|
||||
JwtConfig: JwtConfig,
|
||||
userSvc: userSvc,
|
||||
ticketSvc: ticketSvc,
|
||||
betSvc: betSvc,
|
||||
// reportSvc: reportSvc,
|
||||
chapaSvc: chapaSvc,
|
||||
walletSvc: walletSvc,
|
||||
transactionSvc: transactionSvc,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/raffle"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/recommendation"
|
||||
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/santimpay"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
|
||||
|
|
@ -44,23 +43,23 @@ import (
|
|||
)
|
||||
|
||||
type Handler struct {
|
||||
directDepositSvc *directdeposit.Service
|
||||
orchestrationSvc *orchestration.Service
|
||||
enetPulseSvc *enetpulse.Service
|
||||
telebirrSvc *telebirr.TelebirrService
|
||||
arifpaySvc *arifpay.ArifpayService
|
||||
santimpaySvc *santimpay.SantimPayService
|
||||
issueReportingSvc *issuereporting.Service
|
||||
instSvc *institutions.Service
|
||||
currSvc *currency.Service
|
||||
logger *slog.Logger
|
||||
settingSvc *settings.Service
|
||||
notificationSvc *notificationservice.Service
|
||||
userSvc *user.Service
|
||||
referralSvc *referralservice.Service
|
||||
raffleSvc *raffle.Service
|
||||
bonusSvc *bonus.Service
|
||||
reportSvc report.ReportService
|
||||
directDepositSvc *directdeposit.Service
|
||||
orchestrationSvc *orchestration.Service
|
||||
enetPulseSvc *enetpulse.Service
|
||||
telebirrSvc *telebirr.TelebirrService
|
||||
arifpaySvc *arifpay.ArifpayService
|
||||
santimpaySvc *santimpay.SantimPayService
|
||||
issueReportingSvc *issuereporting.Service
|
||||
instSvc *institutions.Service
|
||||
currSvc *currency.Service
|
||||
logger *slog.Logger
|
||||
settingSvc *settings.Service
|
||||
notificationSvc *notificationservice.Service
|
||||
userSvc *user.Service
|
||||
referralSvc *referralservice.Service
|
||||
raffleSvc *raffle.Service
|
||||
bonusSvc *bonus.Service
|
||||
// reportSvc report.ReportService
|
||||
chapaSvc *chapa.Service
|
||||
walletSvc *wallet.Service
|
||||
transactionSvc *transaction.Service
|
||||
|
|
@ -99,7 +98,7 @@ func New(
|
|||
settingSvc *settings.Service,
|
||||
notificationSvc *notificationservice.Service,
|
||||
validator *customvalidator.CustomValidator,
|
||||
reportSvc report.ReportService,
|
||||
// reportSvc report.ReportService,
|
||||
chapaSvc *chapa.Service,
|
||||
walletSvc *wallet.Service,
|
||||
referralSvc *referralservice.Service,
|
||||
|
|
@ -127,19 +126,19 @@ func New(
|
|||
mongoLoggerSvc *zap.Logger,
|
||||
) *Handler {
|
||||
return &Handler{
|
||||
directDepositSvc: directDepositSvc,
|
||||
orchestrationSvc: orchestrationSvc,
|
||||
enetPulseSvc: enetPulseSvc,
|
||||
telebirrSvc: telebirrSvc,
|
||||
arifpaySvc: arifpaySvc,
|
||||
santimpaySvc: santimpaySvc,
|
||||
issueReportingSvc: issueReportingSvc,
|
||||
instSvc: instSvc,
|
||||
currSvc: currSvc,
|
||||
logger: logger,
|
||||
settingSvc: settingSvc,
|
||||
notificationSvc: notificationSvc,
|
||||
reportSvc: reportSvc,
|
||||
directDepositSvc: directDepositSvc,
|
||||
orchestrationSvc: orchestrationSvc,
|
||||
enetPulseSvc: enetPulseSvc,
|
||||
telebirrSvc: telebirrSvc,
|
||||
arifpaySvc: arifpaySvc,
|
||||
santimpaySvc: santimpaySvc,
|
||||
issueReportingSvc: issueReportingSvc,
|
||||
instSvc: instSvc,
|
||||
currSvc: currSvc,
|
||||
logger: logger,
|
||||
settingSvc: settingSvc,
|
||||
notificationSvc: notificationSvc,
|
||||
// reportSvc: reportSvc,
|
||||
chapaSvc: chapaSvc,
|
||||
walletSvc: walletSvc,
|
||||
referralSvc: referralSvc,
|
||||
|
|
|
|||
|
|
@ -1,481 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GetDashboardReport returns a comprehensive dashboard report
|
||||
// @Summary Get dashboard report
|
||||
// @Description Returns a comprehensive dashboard report with key metrics
|
||||
// @Tags Reports
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param company_id query int false "Company ID filter"
|
||||
// @Param branch_id query int false "Branch ID filter"
|
||||
// @Param user_id query int false "User ID filter"
|
||||
// @Param start_time query string false "Start time filter (RFC3339 format)"
|
||||
// @Param end_time query string false "End time filter (RFC3339 format)"
|
||||
// @Param sport_id query string false "Sport ID filter"
|
||||
// @Param status query int false "Status filter (0=Pending, 1=Win, 2=Loss, 3=Half, 4=Void, 5=Error)"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} domain.DashboardSummary
|
||||
// @Failure 400 {object} domain.ErrorResponse
|
||||
// @Failure 401 {object} domain.ErrorResponse
|
||||
// @Failure 500 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/reports/dashboard [get]
|
||||
func (h *Handler) GetDashboardReport(c *fiber.Ctx) error {
|
||||
role := c.Locals("role").(domain.Role)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Parse query parameters
|
||||
filter, err := parseReportFilter(c, role)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid filter parameters",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// Get report data
|
||||
summary, err := h.reportSvc.GetDashboardSummary(ctx, filter)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to get dashboard report", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to generate report",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
res := domain.ConvertDashboardSummaryToRes(summary)
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Dashboard reports generated successfully",
|
||||
Success: true,
|
||||
StatusCode: 200,
|
||||
Data: res,
|
||||
})
|
||||
|
||||
// return c.Status(fiber.StatusOK).JSON(summary)
|
||||
}
|
||||
|
||||
// parseReportFilter parses query parameters into ReportFilter
|
||||
func parseReportFilter(c *fiber.Ctx, role domain.Role) (domain.ReportFilter, error) {
|
||||
var filter domain.ReportFilter
|
||||
var err error
|
||||
|
||||
if c.Query("company_id") != "" && role == domain.RoleSuperAdmin {
|
||||
|
||||
companyID, err := strconv.ParseInt(c.Query("company_id"), 10, 64)
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid company_id: %w", err)
|
||||
}
|
||||
filter.CompanyID = domain.ValidInt64{Value: companyID, Valid: true}
|
||||
} else {
|
||||
filter.CompanyID = c.Locals("company_id").(domain.ValidInt64)
|
||||
|
||||
}
|
||||
|
||||
if c.Query("branch_id") != "" && role == domain.RoleSuperAdmin {
|
||||
branchID, err := strconv.ParseInt(c.Query("branch_id"), 10, 64)
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid branch_id: %w", err)
|
||||
}
|
||||
filter.BranchID = domain.ValidInt64{Value: branchID, Valid: true}
|
||||
} else {
|
||||
filter.BranchID = c.Locals("branch_id").(domain.ValidInt64)
|
||||
}
|
||||
|
||||
if c.Query("user_id") != "" {
|
||||
userID, err := strconv.ParseInt(c.Query("user_id"), 10, 64)
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid user_id: %w", err)
|
||||
}
|
||||
filter.UserID = domain.ValidInt64{Value: userID, Valid: true}
|
||||
}
|
||||
|
||||
if c.Query("start_time") != "" {
|
||||
startTime, err := time.Parse(time.RFC3339, c.Query("start_time"))
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid start_time: %w", err)
|
||||
}
|
||||
filter.StartTime = domain.ValidTime{Value: startTime, Valid: true}
|
||||
}
|
||||
|
||||
if c.Query("end_time") != "" {
|
||||
endTime, err := time.Parse(time.RFC3339, c.Query("end_time"))
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid end_time: %w", err)
|
||||
}
|
||||
filter.EndTime = domain.ValidTime{Value: endTime, Valid: true}
|
||||
}
|
||||
|
||||
if c.Query("sport_id") != "" {
|
||||
filter.SportID = domain.ValidString{Value: c.Query("sport_id"), Valid: true}
|
||||
}
|
||||
|
||||
if c.Query("status") != "" {
|
||||
status, err := strconv.ParseInt(c.Query("status"), 10, 32)
|
||||
if err != nil {
|
||||
return domain.ReportFilter{}, fmt.Errorf("invalid status: %w", err)
|
||||
}
|
||||
filter.Status = domain.ValidOutcomeStatus{Value: domain.OutcomeStatus(status), Valid: true}
|
||||
}
|
||||
|
||||
return filter, err
|
||||
}
|
||||
|
||||
// DownloadReportFile godoc
|
||||
// @Summary Download a CSV report file
|
||||
// @Description Downloads a generated report CSV file from the server
|
||||
// @Tags Reports
|
||||
// @Param filename path string true "Name of the report file to download (e.g., report_daily_2025-06-21.csv)"
|
||||
// @Produce text/csv
|
||||
// @Success 200 {file} file "CSV file will be downloaded"
|
||||
// @Failure 400 {object} domain.ErrorResponse "Missing or invalid filename"
|
||||
// @Failure 404 {object} domain.ErrorResponse "Report file not found"
|
||||
// @Failure 500 {object} domain.ErrorResponse "Internal server error while serving the file"
|
||||
// @Router /api/v1/report-files/download/{filename} [get]
|
||||
func (h *Handler) DownloadReportFile(c *fiber.Ctx) error {
|
||||
filename := c.Params("filename")
|
||||
if filename == "" || strings.Contains(filename, "..") {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid filename parameter",
|
||||
Error: "filename is required and must not contain '..'",
|
||||
})
|
||||
}
|
||||
|
||||
reportDir := "C:/Users/User/Desktop/reports"
|
||||
|
||||
// Ensure reports directory exists
|
||||
if _, err := os.Stat(reportDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(reportDir, os.ModePerm); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to create report directory",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
filePath := fmt.Sprintf("%s/%s", reportDir, filename)
|
||||
|
||||
// Check if the report file exists
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{
|
||||
Message: "Report file not found",
|
||||
Error: "no such file",
|
||||
})
|
||||
}
|
||||
|
||||
// Set download headers
|
||||
c.Set("Content-Type", "text/csv")
|
||||
c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
|
||||
|
||||
// Serve the file
|
||||
if err := c.SendFile(filePath); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to serve file",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListReportFiles godoc
|
||||
// @Summary List available report CSV files
|
||||
// @Description Returns a paginated list of generated report CSV files with search capability
|
||||
// @Tags Reports
|
||||
// @Produce json
|
||||
// @Param search query string false "Search term to filter filenames"
|
||||
// @Param page query int false "Page number (default: 1)" default(1)
|
||||
// @Param limit query int false "Items per page (default: 20, max: 100)" default(20)
|
||||
// @Success 200 {object} domain.PaginatedFileResponse "Paginated list of CSV report filenames"
|
||||
// @Failure 400 {object} domain.ErrorResponse "Invalid pagination parameters"
|
||||
// @Failure 500 {object} domain.ErrorResponse "Failed to read report directory"
|
||||
// @Router /api/v1/report-files/list [get]
|
||||
func (h *Handler) ListReportFiles(c *fiber.Ctx) error {
|
||||
reportDir := "C:/Users/User/Desktop/reports"
|
||||
searchTerm := c.Query("search")
|
||||
page := c.QueryInt("page", 1)
|
||||
limit := c.QueryInt("limit", 20)
|
||||
|
||||
// Validate pagination parameters
|
||||
if page < 1 {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid page number",
|
||||
Error: "Page must be greater than 0",
|
||||
})
|
||||
}
|
||||
|
||||
if limit < 1 || limit > 100 {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid limit value",
|
||||
Error: "Limit must be between 1 and 100",
|
||||
})
|
||||
}
|
||||
|
||||
// Create the reports directory if it doesn't exist
|
||||
if _, err := os.Stat(reportDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(reportDir, os.ModePerm); err != nil {
|
||||
h.mongoLoggerSvc.Error("failed to create report directory",
|
||||
zap.Int64("status_code", fiber.StatusInternalServerError),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to create report directory",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
files, err := os.ReadDir(reportDir)
|
||||
if err != nil {
|
||||
h.mongoLoggerSvc.Error("failed to read report directory",
|
||||
zap.Int64("status_code", fiber.StatusInternalServerError),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Message: "Failed to read report directory",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
var allFiles []string
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.HasSuffix(file.Name(), ".csv") {
|
||||
// Apply search filter if provided
|
||||
if searchTerm == "" || strings.Contains(strings.ToLower(file.Name()), strings.ToLower(searchTerm)) {
|
||||
allFiles = append(allFiles, file.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort files by name (descending to show newest first)
|
||||
sort.Slice(allFiles, func(i, j int) bool {
|
||||
return allFiles[i] > allFiles[j]
|
||||
})
|
||||
|
||||
// Calculate pagination values
|
||||
total := len(allFiles)
|
||||
startIdx := (page - 1) * limit
|
||||
endIdx := startIdx + limit
|
||||
|
||||
// Adjust end index if it exceeds the slice length
|
||||
if endIdx > total {
|
||||
endIdx = total
|
||||
}
|
||||
|
||||
// Handle case where start index is beyond available items
|
||||
if startIdx >= total {
|
||||
return c.Status(fiber.StatusOK).JSON(domain.PaginatedFileResponse{
|
||||
Response: domain.Response{
|
||||
StatusCode: fiber.StatusOK,
|
||||
Message: "No files found for the requested page",
|
||||
Success: true,
|
||||
},
|
||||
Data: []string{},
|
||||
Pagination: domain.Pagination{
|
||||
Total: total,
|
||||
TotalPages: int(math.Ceil(float64(total) / float64(limit))),
|
||||
CurrentPage: page,
|
||||
Limit: limit,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
paginatedFiles := allFiles[startIdx:endIdx]
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.PaginatedFileResponse{
|
||||
Response: domain.Response{
|
||||
StatusCode: fiber.StatusOK,
|
||||
Message: "Report files retrieved successfully",
|
||||
Success: true,
|
||||
},
|
||||
Data: paginatedFiles,
|
||||
Pagination: domain.Pagination{
|
||||
Total: total,
|
||||
TotalPages: int(math.Ceil(float64(total) / float64(limit))),
|
||||
CurrentPage: page,
|
||||
Limit: limit,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) CreateReportRequest(c *fiber.Ctx) error {
|
||||
userID := c.Locals("user_id").(int64)
|
||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||
|
||||
var req domain.CreateReportRequestReq
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
h.BadRequestLogger().Error(
|
||||
"Failed to parse CreateReportRequestReq",
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid request:", err.Error())
|
||||
}
|
||||
valErrs, ok := h.validator.Validate(c, req)
|
||||
if !ok {
|
||||
var errMsg string
|
||||
for field, msg := range valErrs {
|
||||
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
||||
}
|
||||
h.BadRequestLogger().Error(
|
||||
"Failed to validate CreateReportRequestReq",
|
||||
zap.String("errMsg", errMsg),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||
}
|
||||
|
||||
request, err := h.reportSvc.CreateReportRequest(c.Context(), domain.CreateReportRequest{
|
||||
CompanyID: companyID,
|
||||
RequestedBy: domain.ValidInt64{
|
||||
Value: userID,
|
||||
Valid: true,
|
||||
},
|
||||
Type: domain.ReportRequestType(req.Type),
|
||||
Metadata: req.Metadata,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to create report request", zap.Error(err))
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
res := domain.ConvertReportRequest(request)
|
||||
|
||||
return response.WriteJSON(c, fiber.StatusOK, "Report Request has been created", res, nil)
|
||||
}
|
||||
|
||||
func (h *Handler) GetAllReportRequests(c *fiber.Ctx) error {
|
||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||
|
||||
page := c.QueryInt("page", 1)
|
||||
pageSize := c.QueryInt("page_size", 10)
|
||||
limit := domain.ValidInt32{
|
||||
Value: int32(pageSize),
|
||||
Valid: true,
|
||||
}
|
||||
offset := domain.ValidInt32{
|
||||
Value: int32(page - 1),
|
||||
Valid: true,
|
||||
}
|
||||
|
||||
statusQuery := c.Query("status")
|
||||
var reportStatus domain.ValidReportRequestStatus
|
||||
if statusQuery != "" {
|
||||
reportStatusParsed, err := domain.ParseReportRequestStatus(statusQuery)
|
||||
if err != nil {
|
||||
h.BadRequestLogger().Error("Failed to parse statusQuery",
|
||||
zap.String("status", statusQuery),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid report status")
|
||||
}
|
||||
reportStatus = domain.ValidReportRequestStatus{
|
||||
Value: reportStatusParsed,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
typeQuery := c.Query("type")
|
||||
var reportType domain.ValidReportRequestType
|
||||
if typeQuery != "" {
|
||||
reportTypeParsed, err := domain.ParseReportRequestType(typeQuery)
|
||||
if err != nil {
|
||||
h.BadRequestLogger().Error("Failed to parse typeQuery",
|
||||
zap.String("type", typeQuery),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid report type")
|
||||
}
|
||||
reportType = domain.ValidReportRequestType{
|
||||
Value: reportTypeParsed,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
requesterQuery := c.Query("requester")
|
||||
var requestedBy domain.ValidInt64
|
||||
if requesterQuery != "" {
|
||||
parsedRequestedBy, err := strconv.ParseInt(requesterQuery, 10, 64)
|
||||
if err != nil {
|
||||
h.BadRequestLogger().Error("Failed to parse requester",
|
||||
zap.String("requester", requesterQuery),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid report requester")
|
||||
}
|
||||
requestedBy = domain.ValidInt64{
|
||||
Value: parsedRequestedBy,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
requests, total, err := h.reportSvc.GetAllReportRequests(c.Context(), domain.ReportRequestFilter{
|
||||
CompanyID: companyID,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Status: reportStatus,
|
||||
Type: reportType,
|
||||
RequestedBy: requestedBy,
|
||||
})
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to retrieve all report requests",
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
res := domain.ConvertReportRequestDetailList(requests)
|
||||
|
||||
return response.WritePaginatedJSON(c, fiber.StatusOK, "All Report Requests successfully retrieved", res, nil, page, int(total))
|
||||
}
|
||||
|
||||
func (h *Handler) DownloadReportByID(c *fiber.Ctx) error {
|
||||
requestID := c.Params("id")
|
||||
id, err := strconv.ParseInt(requestID, 10, 64)
|
||||
if err != nil {
|
||||
h.BadRequestLogger().Info("Invalid report request ID",
|
||||
zap.String("requestID", requestID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid request ID")
|
||||
}
|
||||
|
||||
file, err := h.reportSvc.CheckAndFetchReportFile(c.Context(), id)
|
||||
|
||||
if err != nil {
|
||||
h.InternalServerErrorLogger().Error("Failed to check and fetch report file",
|
||||
zap.Error(err),
|
||||
zap.String("requestID", requestID),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to check and fetch report file:%v", err.Error()))
|
||||
}
|
||||
|
||||
c.Set("Content-Type", "text/csv")
|
||||
c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file))
|
||||
|
||||
if err := c.SendFile(file); err != nil {
|
||||
h.InternalServerErrorLogger().Error("Unable to download report file",
|
||||
zap.Error(err),
|
||||
zap.String("requestID", requestID),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Unable to download report file:%v", err.Error()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ func (a *App) initAppRoutes() {
|
|||
a.settingSvc,
|
||||
a.NotidicationStore,
|
||||
a.validator,
|
||||
a.reportSvc,
|
||||
// a.reportSvc,
|
||||
a.chapaSvc,
|
||||
a.walletSvc,
|
||||
a.referralSvc,
|
||||
|
|
@ -408,13 +408,13 @@ func (a *App) initAppRoutes() {
|
|||
groupV1.Get("/currencies/convert", h.ConvertCurrency)
|
||||
|
||||
//Report Routes
|
||||
groupV1.Get("/reports/dashboard", a.authMiddleware, a.OnlyAdminAndAbove, h.GetDashboardReport)
|
||||
groupV1.Get("/report-files/download/:filename", h.DownloadReportFile)
|
||||
groupV1.Get("/report-files/list", a.authMiddleware, a.OnlyAdminAndAbove, h.ListReportFiles)
|
||||
// groupV1.Get("/reports/dashboard", a.authMiddleware, a.OnlyAdminAndAbove, h.GetDashboardReport)
|
||||
// groupV1.Get("/report-files/download/:filename", h.DownloadReportFile)
|
||||
// groupV1.Get("/report-files/list", a.authMiddleware, a.OnlyAdminAndAbove, h.ListReportFiles)
|
||||
|
||||
groupV1.Post("/reports/requests", a.authMiddleware, a.OnlyAdminAndAbove, h.CreateReportRequest)
|
||||
groupV1.Get("/reports/requests", a.authMiddleware, a.OnlyAdminAndAbove, h.GetAllReportRequests)
|
||||
groupV1.Get("/reports/download/:id", a.authMiddleware, a.OnlyAdminAndAbove, h.DownloadReportByID)
|
||||
// groupV1.Post("/reports/requests", a.authMiddleware, a.OnlyAdminAndAbove, h.CreateReportRequest)
|
||||
// groupV1.Get("/reports/requests", a.authMiddleware, a.OnlyAdminAndAbove, h.GetAllReportRequests)
|
||||
// groupV1.Get("/reports/download/:id", a.authMiddleware, a.OnlyAdminAndAbove, h.DownloadReportByID)
|
||||
|
||||
//Alea Play Virtual Game Routes
|
||||
groupV1.Get("/alea-play/launch", a.authMiddleware, h.LaunchAleaGame)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user