Enetpulse fixture and preodds
This commit is contained in:
commit
e429810ebc
18
cmd/main.go
18
cmd/main.go
|
|
@ -41,7 +41,6 @@ import (
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/institutions"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/institutions"
|
||||||
issuereporting "github.com/SamuelTariku/FortuneBet-Backend/internal/services/issue_reporting"
|
issuereporting "github.com/SamuelTariku/FortuneBet-Backend/internal/services/issue_reporting"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/kafka"
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/league"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
|
||||||
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
|
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
|
||||||
|
|
@ -122,10 +121,10 @@ func main() {
|
||||||
// var userStore user.UserStore
|
// var userStore user.UserStore
|
||||||
|
|
||||||
// Initialize producer
|
// Initialize producer
|
||||||
topic := "wallet-balance-topic"
|
// topic := "wallet-balance-topic"
|
||||||
producer := kafka.NewProducer(cfg.KafkaBrokers, topic)
|
// producer := kafka.NewProducer(cfg.KafkaBrokers, topic)
|
||||||
|
|
||||||
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc, cfg.KafkaBrokers)
|
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
|
||||||
|
|
||||||
walletSvc := wallet.NewService(
|
walletSvc := wallet.NewService(
|
||||||
wallet.WalletStore(store),
|
wallet.WalletStore(store),
|
||||||
|
|
@ -135,7 +134,6 @@ func main() {
|
||||||
userSvc,
|
userSvc,
|
||||||
domain.MongoDBLogger,
|
domain.MongoDBLogger,
|
||||||
logger,
|
logger,
|
||||||
producer,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
branchSvc := branch.NewService(store)
|
branchSvc := branch.NewService(store)
|
||||||
|
|
@ -195,8 +193,8 @@ func main() {
|
||||||
store,
|
store,
|
||||||
)
|
)
|
||||||
|
|
||||||
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, veliVirtualGameService, "C:/Users/User/Desktop")
|
|
||||||
go httpserver.StartEnetPulseCron(enePulseSvc, domain.MongoDBLogger)
|
go httpserver.StartEnetPulseCron(enePulseSvc, domain.MongoDBLogger)
|
||||||
|
go httpserver.SetupReportandVirtualGameCronJobs(context.Background(), reportSvc, veliVirtualGameService, "C:/Users/User/Desktop")
|
||||||
go httpserver.ProcessBetCashback(context.TODO(), betSvc)
|
go httpserver.ProcessBetCashback(context.TODO(), betSvc)
|
||||||
|
|
||||||
bankRepository := repository.NewBankRepository(store)
|
bankRepository := repository.NewBankRepository(store)
|
||||||
|
|
@ -233,13 +231,13 @@ func main() {
|
||||||
fixerFertcherSvc,
|
fixerFertcherSvc,
|
||||||
)
|
)
|
||||||
|
|
||||||
exchangeWorker := currency.NewExchangeRateWorker(fixerFertcherSvc, logger, cfg)
|
// exchangeWorker := currency.NewExchangeRateWorker(fixerFertcherSvc, logger, cfg)
|
||||||
exchangeWorker.Start(context.Background())
|
// exchangeWorker.Start(context.Background())
|
||||||
defer exchangeWorker.Stop()
|
// defer exchangeWorker.Stop()
|
||||||
go walletMonitorSvc.Start()
|
go walletMonitorSvc.Start()
|
||||||
|
|
||||||
httpserver.StartDataFetchingCrons(eventSvc, *oddsSvc, resultSvc, domain.MongoDBLogger)
|
httpserver.StartDataFetchingCrons(eventSvc, *oddsSvc, resultSvc, domain.MongoDBLogger)
|
||||||
httpserver.StartTicketCrons(*ticketSvc, domain.MongoDBLogger)
|
httpserver.StartCleanupCrons(*ticketSvc, notificationSvc, domain.MongoDBLogger)
|
||||||
|
|
||||||
issueReportingRepo := repository.NewReportedIssueRepository(store)
|
issueReportingRepo := repository.NewReportedIssueRepository(store)
|
||||||
|
|
||||||
|
|
|
||||||
221
db/dev_data/betfidel_data.sql
Normal file
221
db/dev_data/betfidel_data.sql
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
|
DO $$
|
||||||
|
DECLARE _admin_id bigint;
|
||||||
|
_manager_id bigint;
|
||||||
|
_company_wallet_id bigint;
|
||||||
|
_company_id bigint;
|
||||||
|
_branch_id bigint;
|
||||||
|
_branch_wallet_id bigint;
|
||||||
|
_cashier_id bigint;
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO users (
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
email,
|
||||||
|
phone_number,
|
||||||
|
password,
|
||||||
|
role,
|
||||||
|
email_verified,
|
||||||
|
phone_verified,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
suspended
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'Admin',
|
||||||
|
'BetFidel',
|
||||||
|
'admin.betfidel@gmail.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'admin',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE
|
||||||
|
) ON CONFLICT (email) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _admin_id;
|
||||||
|
INSERT INTO users (
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
email,
|
||||||
|
phone_number,
|
||||||
|
password,
|
||||||
|
role,
|
||||||
|
email_verified,
|
||||||
|
phone_verified,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
suspended,
|
||||||
|
company_id
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'Manager',
|
||||||
|
'BetFidel',
|
||||||
|
'manager.betfidel@gmail.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'branch_manager',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
_company_id
|
||||||
|
) ON CONFLICT (email) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _manager_id;
|
||||||
|
INSERT INTO wallets (
|
||||||
|
balance,
|
||||||
|
is_withdraw,
|
||||||
|
is_bettable,
|
||||||
|
is_transferable,
|
||||||
|
user_id,
|
||||||
|
type,
|
||||||
|
currency,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
10000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
_admin_id,
|
||||||
|
'company_wallet',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
) ON CONFLICT (user_id, type) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _company_wallet_id;
|
||||||
|
INSERT INTO companies (
|
||||||
|
name,
|
||||||
|
slug,
|
||||||
|
admin_id,
|
||||||
|
wallet_id,
|
||||||
|
deducted_percentage,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'FidelBet',
|
||||||
|
'betfidel',
|
||||||
|
_admin_id,
|
||||||
|
_company_wallet_id,
|
||||||
|
0.15,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
) ON CONFLICT (slug) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _company_id;
|
||||||
|
UPDATE users
|
||||||
|
SET company_id = _company_id
|
||||||
|
WHERE id = _admin_id;
|
||||||
|
INSERT INTO wallets (
|
||||||
|
balance,
|
||||||
|
is_withdraw,
|
||||||
|
is_bettable,
|
||||||
|
is_transferable,
|
||||||
|
user_id,
|
||||||
|
type,
|
||||||
|
currency,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
10000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
_admin_id,
|
||||||
|
'branch_wallet',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
) ON CONFLICT (user_id, type) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _branch_wallet_id;
|
||||||
|
INSERT INTO branches (
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
wallet_id,
|
||||||
|
branch_manager_id,
|
||||||
|
company_id,
|
||||||
|
is_self_owned,
|
||||||
|
profit_percent,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'Test Branch',
|
||||||
|
'addis_ababa',
|
||||||
|
_branch_wallet_id,
|
||||||
|
_manager_id,
|
||||||
|
_company_id,
|
||||||
|
TRUE,
|
||||||
|
0.10,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
) ON CONFLICT (wallet_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _branch_id;
|
||||||
|
INSERT INTO users (
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
email,
|
||||||
|
phone_number,
|
||||||
|
password,
|
||||||
|
role,
|
||||||
|
email_verified,
|
||||||
|
phone_verified,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
suspended,
|
||||||
|
company_id
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'Cashier',
|
||||||
|
'BetFidel',
|
||||||
|
'cashier.betfidel@gmail.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'cashier',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
_company_id
|
||||||
|
) ON CONFLICT (email) DO
|
||||||
|
UPDATE
|
||||||
|
SET updated_at = EXCLUDED.updated_at
|
||||||
|
RETURNING id INTO STRICT _cashier_id;
|
||||||
|
INSERT INTO branch_cashiers (user_id, branch_id)
|
||||||
|
VALUES (_cashier_id, _branch_id);
|
||||||
|
RAISE NOTICE 'BETFIDEL_DEV_DATA (Admin ID: %, Company Wallet ID: %, Company ID: %)',
|
||||||
|
_admin_id,
|
||||||
|
_company_wallet_id,
|
||||||
|
_company_id;
|
||||||
|
RAISE NOTICE 'BETFIDEL_DEV_DATA (Branch ID: %, Branch Wallet ID: %, Manager ID: %)',
|
||||||
|
_branch_id,
|
||||||
|
_branch_wallet_id,
|
||||||
|
_manager_id;
|
||||||
|
RAISE NOTICE 'BETFIDEL_DEV_DATA (Cashier ID: %)',
|
||||||
|
_cashier_id;
|
||||||
|
END $$;
|
||||||
|
|
@ -73,10 +73,9 @@ CREATE TABLE IF NOT EXISTS wallets (
|
||||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
UNIQUE(user_id, type)
|
UNIQUE(user_id, type),
|
||||||
|
CONSTRAINT balance_positve CHECK (balance >= 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE refresh_tokens (
|
CREATE TABLE refresh_tokens (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
user_id BIGINT NOT NULL,
|
user_id BIGINT NOT NULL,
|
||||||
|
|
@ -186,19 +185,19 @@ CREATE TABLE IF NOT EXISTS banks (
|
||||||
currency VARCHAR(10) NOT NULL,
|
currency VARCHAR(10) NOT NULL,
|
||||||
bank_logo TEXT -- URL or base64 string
|
bank_logo TEXT -- URL or base64 string
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS wallets (
|
-- CREATE TABLE IF NOT EXISTS wallets (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
-- id BIGSERIAL PRIMARY KEY,
|
||||||
balance BIGINT NOT NULL DEFAULT 0,
|
-- balance BIGINT NOT NULL DEFAULT 0,
|
||||||
is_withdraw BOOLEAN NOT NULL,
|
-- is_withdraw BOOLEAN NOT NULL,
|
||||||
is_bettable BOOLEAN NOT NULL,
|
-- is_bettable BOOLEAN NOT NULL,
|
||||||
is_transferable BOOLEAN NOT NULL,
|
-- is_transferable BOOLEAN NOT NULL,
|
||||||
user_id BIGINT NOT NULL,
|
-- user_id BIGINT NOT NULL,
|
||||||
type VARCHAR(255) NOT NULL,
|
-- type VARCHAR(255) NOT NULL,
|
||||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
-- is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
-- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
-- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
CONSTRAINT balance_positve CHECK (balance >= 0)
|
-- CONSTRAINT balance_positve CHECK (balance >= 0)
|
||||||
);
|
-- );
|
||||||
CREATE TABLE IF NOT EXISTS customer_wallets (
|
CREATE TABLE IF NOT EXISTS customer_wallets (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
customer_id BIGINT NOT NULL,
|
customer_id BIGINT NOT NULL,
|
||||||
|
|
@ -272,7 +271,7 @@ CREATE TABLE IF NOT EXISTS branches (
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
location TEXT NOT NULL,
|
location TEXT NOT NULL,
|
||||||
profit_percent REAL NOT NULL,
|
profit_percent REAL NOT NULL,
|
||||||
is_active BOOLEAN NOT NULL DEFAULT false,
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
wallet_id BIGINT NOT NULL,
|
wallet_id BIGINT NOT NULL,
|
||||||
branch_manager_id BIGINT NOT NULL,
|
branch_manager_id BIGINT NOT NULL,
|
||||||
company_id BIGINT NOT NULL,
|
company_id BIGINT NOT NULL,
|
||||||
|
|
@ -321,6 +320,7 @@ CREATE TABLE events (
|
||||||
is_live BOOLEAN NOT NULL DEFAULT false,
|
is_live BOOLEAN NOT NULL DEFAULT false,
|
||||||
status TEXT NOT NULL,
|
status TEXT NOT NULL,
|
||||||
fetched_at TIMESTAMP DEFAULT now (),
|
fetched_at TIMESTAMP DEFAULT now (),
|
||||||
|
updated_at TIMESTAMP DEFAULT now (),
|
||||||
source TEXT NOT NULL DEFAULT 'b365api' CHECK (
|
source TEXT NOT NULL DEFAULT 'b365api' CHECK (
|
||||||
source IN ('b365api', 'bfair', '1xbet', 'bwin', 'enetpulse')
|
source IN ('b365api', 'bfair', '1xbet', 'bwin', 'enetpulse')
|
||||||
),
|
),
|
||||||
|
|
@ -342,7 +342,7 @@ CREATE TABLE company_event_settings (
|
||||||
event_id BIGINT NOT NULL,
|
event_id BIGINT NOT NULL,
|
||||||
is_active BOOLEAN,
|
is_active BOOLEAN,
|
||||||
is_featured BOOLEAN,
|
is_featured BOOLEAN,
|
||||||
winning_upper_limit INT,
|
winning_upper_limit BIGINT,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
UNIQUE (company_id, event_id)
|
UNIQUE (company_id, event_id)
|
||||||
);
|
);
|
||||||
|
|
@ -354,6 +354,7 @@ CREATE TABLE odds_market (
|
||||||
market_category TEXT NOT NULL,
|
market_category TEXT NOT NULL,
|
||||||
market_id BIGINT NOT NULL,
|
market_id BIGINT NOT NULL,
|
||||||
raw_odds JSONB NOT NULL,
|
raw_odds JSONB NOT NULL,
|
||||||
|
number_of_outcomes BIGINT NOT NULL,
|
||||||
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
fetched_at TIMESTAMP DEFAULT now (),
|
fetched_at TIMESTAMP DEFAULT now (),
|
||||||
expires_at TIMESTAMP NOT NULL,
|
expires_at TIMESTAMP NOT NULL,
|
||||||
|
|
@ -408,11 +409,11 @@ CREATE TABLE companies (
|
||||||
admin_id BIGINT NOT NULL,
|
admin_id BIGINT NOT NULL,
|
||||||
wallet_id BIGINT NOT NULL,
|
wallet_id BIGINT NOT NULL,
|
||||||
deducted_percentage REAL NOT NULL,
|
deducted_percentage REAL NOT NULL,
|
||||||
is_active BOOLEAN NOT NULL DEFAULT false,
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
CONSTRAINT deducted_percentage_check CHECK (
|
CONSTRAINT deducted_percentage_check CHECK (
|
||||||
deducted_percentage >= 0
|
deducted_percentage > 0
|
||||||
AND deducted_percentage < 1
|
AND deducted_percentage < 1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
@ -511,6 +512,8 @@ CREATE TABLE IF NOT EXISTS raffles (
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
expires_at TIMESTAMP NOT NULL,
|
expires_at TIMESTAMP NOT NULL,
|
||||||
|
-- -1 means there is no limit for the raffle
|
||||||
|
ticket_limit INT NOT NULL DEFAULT -1,
|
||||||
type VARCHAR(50) NOT NULL CHECK (type IN ('virtual', 'sport')),
|
type VARCHAR(50) NOT NULL CHECK (type IN ('virtual', 'sport')),
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed'))
|
status VARCHAR(50) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed'))
|
||||||
);
|
);
|
||||||
|
|
@ -580,14 +583,17 @@ CREATE VIEW bet_with_outcomes AS
|
||||||
SELECT bets.*,
|
SELECT bets.*,
|
||||||
CONCAT (users.first_name, ' ', users.last_name) AS full_name,
|
CONCAT (users.first_name, ' ', users.last_name) AS full_name,
|
||||||
users.phone_number,
|
users.phone_number,
|
||||||
JSON_AGG (bet_outcomes.*) AS outcomes
|
JSON_AGG (bet_outcomes.*) AS outcomes,
|
||||||
|
companies.slug as company_slug
|
||||||
FROM bets
|
FROM bets
|
||||||
LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id
|
LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id
|
||||||
LEFT JOIN users ON bets.user_id = users.id
|
LEFT JOIN users ON bets.user_id = users.id
|
||||||
|
JOIN companies ON bets.company_id = companies.id
|
||||||
GROUP BY bets.id,
|
GROUP BY bets.id,
|
||||||
users.first_name,
|
users.first_name,
|
||||||
users.last_name,
|
users.last_name,
|
||||||
users.phone_number;
|
users.phone_number,
|
||||||
|
companies.slug;
|
||||||
CREATE VIEW ticket_with_outcomes AS
|
CREATE VIEW ticket_with_outcomes AS
|
||||||
SELECT tickets.*,
|
SELECT tickets.*,
|
||||||
JSON_AGG (ticket_outcomes.*) AS outcomes
|
JSON_AGG (ticket_outcomes.*) AS outcomes
|
||||||
|
|
@ -644,6 +650,7 @@ SELECT sb.*,
|
||||||
st.verified AS transaction_verified,
|
st.verified AS transaction_verified,
|
||||||
bets.status,
|
bets.status,
|
||||||
bets.total_odds,
|
bets.total_odds,
|
||||||
|
bets.fast_code,
|
||||||
JSON_AGG (bet_outcomes.*) AS outcomes
|
JSON_AGG (bet_outcomes.*) AS outcomes
|
||||||
FROM shop_bets AS sb
|
FROM shop_bets AS sb
|
||||||
JOIN shop_transactions st ON st.id = sb.shop_transaction_id
|
JOIN shop_transactions st ON st.id = sb.shop_transaction_id
|
||||||
|
|
@ -657,7 +664,8 @@ GROUP BY sb.id,
|
||||||
st.amount,
|
st.amount,
|
||||||
st.verified,
|
st.verified,
|
||||||
bets.status,
|
bets.status,
|
||||||
bets.total_odds;
|
bets.total_odds,
|
||||||
|
bets.fast_code;
|
||||||
CREATE VIEW shop_deposit_detail AS
|
CREATE VIEW shop_deposit_detail AS
|
||||||
SELECT sd.*,
|
SELECT sd.*,
|
||||||
st.full_name,
|
st.full_name,
|
||||||
|
|
@ -685,16 +693,30 @@ SELECT e.*,
|
||||||
ces.winning_upper_limit,
|
ces.winning_upper_limit,
|
||||||
e.default_winning_upper_limit
|
e.default_winning_upper_limit
|
||||||
) AS winning_upper_limit,
|
) AS winning_upper_limit,
|
||||||
ces.updated_at,
|
ces.updated_at as company_updated_at,
|
||||||
l.country_code as league_cc
|
l.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events e
|
FROM events e
|
||||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||||
JOIN leagues l ON l.id = e.league_id;
|
JOIN leagues l ON l.id = e.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = e.id;
|
||||||
CREATE VIEW event_with_country AS
|
CREATE VIEW event_with_country AS
|
||||||
SELECT events.*,
|
SELECT events.*,
|
||||||
leagues.country_code as league_cc
|
leagues.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events
|
FROM events
|
||||||
LEFT JOIN leagues ON leagues.id = events.league_id;
|
LEFT JOIN leagues ON leagues.id = events.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = events.id;
|
||||||
CREATE VIEW odds_market_with_settings AS
|
CREATE VIEW odds_market_with_settings AS
|
||||||
SELECT o.id,
|
SELECT o.id,
|
||||||
o.event_id,
|
o.event_id,
|
||||||
|
|
@ -702,6 +724,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ CREATE TABLE IF NOT EXISTS notifications (
|
||||||
priority INTEGER,
|
priority INTEGER,
|
||||||
version INTEGER NOT NULL DEFAULT 0,
|
version INTEGER NOT NULL DEFAULT 0,
|
||||||
timestamp TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
timestamp TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
img TEXT,
|
||||||
|
expires TIMESTAMPTZ NOT NULL,
|
||||||
metadata JSONB
|
metadata JSONB
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS wallet_threshold_notifications (
|
CREATE TABLE IF NOT EXISTS wallet_threshold_notifications (
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,10 @@ DROP TABLE IF EXISTS enetpulse_sports;
|
||||||
DROP TABLE IF EXISTS enetpulse_tournament_templates;
|
DROP TABLE IF EXISTS enetpulse_tournament_templates;
|
||||||
DROP TABLE IF EXISTS enetpulse_tournaments;
|
DROP TABLE IF EXISTS enetpulse_tournaments;
|
||||||
DROP TABLE IF EXISTS enetpulse_tournament_stages;
|
DROP TABLE IF EXISTS enetpulse_tournament_stages;
|
||||||
DROP TABLE IF EXISTS enetpulse_fixtures;
|
DROP TABLE IF EXISTS enetpulse_fixtures;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_results;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_result_participants;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_result_referees;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_outcome_types;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_preodds;
|
||||||
|
DROP TABLE IF EXISTS enetpulse_preodds_bettingoffers;
|
||||||
|
|
@ -133,6 +133,40 @@ SELECT *
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE status = 2
|
WHERE status = 2
|
||||||
AND processed = false;
|
AND processed = false;
|
||||||
|
-- name: GetBetOutcomeViewByEventID :many
|
||||||
|
SELECT bet_outcomes.*,
|
||||||
|
users.first_name,
|
||||||
|
users.last_name,
|
||||||
|
bets.amount,
|
||||||
|
bets.total_odds,
|
||||||
|
companies.name as company_name
|
||||||
|
FROM bet_outcomes
|
||||||
|
JOIN bets ON bets.id = bet_outcomes.bet_id
|
||||||
|
JOIN users ON bets.user_id = users.id
|
||||||
|
JOIN companies ON bets.company_id = companies.id
|
||||||
|
WHERE bet_outcomes.event_id = $1
|
||||||
|
AND (
|
||||||
|
bets.company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
bet_outcomes.status = sqlc.narg('filter_status')
|
||||||
|
OR sqlc.narg('filter_status') IS NULL
|
||||||
|
)
|
||||||
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
|
-- name: TotalBetOutcomeViewByEventID :one
|
||||||
|
SELECT count(*)
|
||||||
|
FROM bet_outcomes
|
||||||
|
JOIN bets ON bets.id = bet_outcomes.bet_id
|
||||||
|
WHERE bet_outcomes.event_id = $1
|
||||||
|
AND (
|
||||||
|
bets.company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
bet_outcomes.status = sqlc.narg('filter_status')
|
||||||
|
OR sqlc.narg('filter_status') IS NULL
|
||||||
|
);
|
||||||
-- name: GetBetOutcomeByEventID :many
|
-- name: GetBetOutcomeByEventID :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM bet_outcomes
|
FROM bet_outcomes
|
||||||
|
|
@ -180,6 +214,15 @@ UPDATE bet_outcomes
|
||||||
SEt status = $1
|
SEt status = $1
|
||||||
WHERE event_id = $2
|
WHERE event_id = $2
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
-- name: UpdateBetOutcomeStatusForOddID :many
|
||||||
|
UPDATE bet_outcomes
|
||||||
|
SEt status = $1
|
||||||
|
WHERE odd_id = $2
|
||||||
|
RETURNING *;
|
||||||
|
-- name: BulkUpdateBetOutcomeStatusByOddIDs :exec
|
||||||
|
UPDATE bet_outcomes
|
||||||
|
SET status = $1
|
||||||
|
WHERE odd_id = ANY(sqlc.arg('odd_ids')::BIGINT []);
|
||||||
-- name: UpdateStatus :exec
|
-- name: UpdateStatus :exec
|
||||||
UPDATE bets
|
UPDATE bets
|
||||||
SET status = $1,
|
SET status = $1,
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ wHERE (
|
||||||
user_id = sqlc.narg('user_id')
|
user_id = sqlc.narg('user_id')
|
||||||
OR sqlc.narg('user_id') IS NULL
|
OR sqlc.narg('user_id') IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at > sqlc.narg('created_before')
|
created_at > sqlc.narg('created_before')
|
||||||
OR sqlc.narg('created_before') IS NULL
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
|
@ -60,6 +64,10 @@ wHERE (
|
||||||
user_id = sqlc.narg('user_id')
|
user_id = sqlc.narg('user_id')
|
||||||
OR sqlc.narg('user_id') IS NULL
|
OR sqlc.narg('user_id') IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
AND (
|
AND (
|
||||||
is_shop_bet = sqlc.narg('is_shop_bet')
|
is_shop_bet = sqlc.narg('is_shop_bet')
|
||||||
OR sqlc.narg('is_shop_bet') IS NULL
|
OR sqlc.narg('is_shop_bet') IS NULL
|
||||||
|
|
@ -117,6 +125,10 @@ WITH market_counts AS (
|
||||||
user_id = sqlc.narg('user_id')
|
user_id = sqlc.narg('user_id')
|
||||||
OR sqlc.narg('user_id') IS NULL
|
OR sqlc.narg('user_id') IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at > sqlc.narg('created_before')
|
created_at > sqlc.narg('created_before')
|
||||||
OR sqlc.narg('created_before') IS NULL
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,11 @@ WHERE branch_manager_id = $1;
|
||||||
-- name: SearchBranchByName :many
|
-- name: SearchBranchByName :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM branch_details
|
FROM branch_details
|
||||||
WHERE name ILIKE '%' || $1 || '%';
|
WHERE name ILIKE '%' || $1 || '%'
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
);
|
||||||
-- name: GetAllSupportedOperations :many
|
-- name: GetAllSupportedOperations :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM supported_operations;
|
FROM supported_operations;
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@ INSERT INTO companies (
|
||||||
slug,
|
slug,
|
||||||
admin_id,
|
admin_id,
|
||||||
wallet_id,
|
wallet_id,
|
||||||
deducted_percentage
|
deducted_percentage,
|
||||||
|
is_active
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: GetAllCompanies :many
|
-- name: GetAllCompanies :many
|
||||||
SELECT *
|
SELECT *
|
||||||
|
|
@ -30,15 +31,15 @@ WHERE (
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
-- name: GetCompanyIDUsingSlug :one
|
-- name: GetCompanyUsingSlug :one
|
||||||
SELECT id
|
SELECT *
|
||||||
FROM companies
|
FROM companies
|
||||||
WHERE slug = $1;
|
WHERE slug = $1;
|
||||||
-- name: SearchCompanyByName :many
|
-- name: SearchCompanyByName :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE name ILIKE '%' || $1 || '%';
|
WHERE name ILIKE '%' || $1 || '%';
|
||||||
-- name: UpdateCompany :one
|
-- name: UpdateCompany :exec
|
||||||
UPDATE companies
|
UPDATE companies
|
||||||
SET name = COALESCE(sqlc.narg(name), name),
|
SET name = COALESCE(sqlc.narg(name), name),
|
||||||
admin_id = COALESCE(sqlc.narg(admin_id), admin_id),
|
admin_id = COALESCE(sqlc.narg(admin_id), admin_id),
|
||||||
|
|
@ -47,9 +48,9 @@ SET name = COALESCE(sqlc.narg(name), name),
|
||||||
sqlc.narg(deducted_percentage),
|
sqlc.narg(deducted_percentage),
|
||||||
deducted_percentage
|
deducted_percentage
|
||||||
),
|
),
|
||||||
|
slug = COALESCE(sqlc.narg(slug), slug),
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1;
|
||||||
RETURNING *;
|
|
||||||
-- name: DeleteCompany :exec
|
-- name: DeleteCompany :exec
|
||||||
DELETE FROM companies
|
DELETE FROM companies
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
@ -107,7 +107,8 @@ INSERT INTO enetpulse_tournament_stages (
|
||||||
updates_count,
|
updates_count,
|
||||||
last_updated_at,
|
last_updated_at,
|
||||||
status
|
status
|
||||||
) VALUES (
|
)
|
||||||
|
VALUES (
|
||||||
$1, -- stage_id
|
$1, -- stage_id
|
||||||
$2, -- name
|
$2, -- name
|
||||||
$3, -- tournament_fk
|
$3, -- tournament_fk
|
||||||
|
|
@ -120,6 +121,19 @@ INSERT INTO enetpulse_tournament_stages (
|
||||||
$10, -- last_updated_at
|
$10, -- last_updated_at
|
||||||
$11 -- status
|
$11 -- status
|
||||||
)
|
)
|
||||||
|
ON CONFLICT (stage_id) DO UPDATE
|
||||||
|
SET
|
||||||
|
name = EXCLUDED.name,
|
||||||
|
tournament_fk = EXCLUDED.tournament_fk,
|
||||||
|
gender = EXCLUDED.gender,
|
||||||
|
country_fk = EXCLUDED.country_fk,
|
||||||
|
country_name = EXCLUDED.country_name,
|
||||||
|
start_date = EXCLUDED.start_date,
|
||||||
|
end_date = EXCLUDED.end_date,
|
||||||
|
updates_count = EXCLUDED.updates_count,
|
||||||
|
last_updated_at = EXCLUDED.last_updated_at,
|
||||||
|
status = EXCLUDED.status,
|
||||||
|
updated_at = NOW()
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetAllEnetpulseTournamentStages :many
|
-- name: GetAllEnetpulseTournamentStages :many
|
||||||
|
|
@ -367,6 +381,48 @@ SELECT *
|
||||||
FROM enetpulse_preodds_bettingoffers
|
FROM enetpulse_preodds_bettingoffers
|
||||||
ORDER BY created_at DESC;
|
ORDER BY created_at DESC;
|
||||||
|
|
||||||
|
-- name: GetFixturesWithPreodds :many
|
||||||
|
SELECT
|
||||||
|
f.fixture_id AS id,
|
||||||
|
f.fixture_id AS fixture_id,
|
||||||
|
f.name AS fixture_name,
|
||||||
|
f.sport_fk,
|
||||||
|
f.tournament_fk,
|
||||||
|
f.tournament_template_fk,
|
||||||
|
f.tournament_stage_fk,
|
||||||
|
f.start_date,
|
||||||
|
f.status_type,
|
||||||
|
f.status_desc_fk,
|
||||||
|
f.round_type_fk,
|
||||||
|
f.updates_count AS fixture_updates_count,
|
||||||
|
f.last_updated_at AS fixture_last_updated_at,
|
||||||
|
f.created_at AS fixture_created_at,
|
||||||
|
f.updated_at AS fixture_updated_at,
|
||||||
|
|
||||||
|
-- Preodds fields
|
||||||
|
p.id AS preodds_db_id,
|
||||||
|
p.preodds_id,
|
||||||
|
p.event_fk,
|
||||||
|
p.outcome_type_fk,
|
||||||
|
p.outcome_scope_fk,
|
||||||
|
p.outcome_subtype_fk,
|
||||||
|
p.event_participant_number,
|
||||||
|
p.iparam,
|
||||||
|
p.iparam2,
|
||||||
|
p.dparam,
|
||||||
|
p.dparam2,
|
||||||
|
p.sparam,
|
||||||
|
p.updates_count AS preodds_updates_count,
|
||||||
|
p.last_updated_at AS preodds_last_updated_at,
|
||||||
|
p.created_at AS preodds_created_at,
|
||||||
|
p.updated_at AS preodds_updated_at
|
||||||
|
|
||||||
|
FROM enetpulse_fixtures f
|
||||||
|
LEFT JOIN enetpulse_preodds p
|
||||||
|
ON p.event_fk = f.id
|
||||||
|
ORDER BY f.start_date DESC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ SET sport_id = EXCLUDED.sport_id,
|
||||||
source = EXCLUDED.source,
|
source = EXCLUDED.source,
|
||||||
default_winning_upper_limit = EXCLUDED.default_winning_upper_limit,
|
default_winning_upper_limit = EXCLUDED.default_winning_upper_limit,
|
||||||
fetched_at = now();
|
fetched_at = now();
|
||||||
-- name: SaveEventSettings :exec
|
-- name: SaveTenantEventSettings :exec
|
||||||
INSERT INTO company_event_settings (
|
INSERT INTO company_event_settings (
|
||||||
company_id,
|
company_id,
|
||||||
event_id,
|
event_id,
|
||||||
|
|
@ -218,11 +218,18 @@ SELECT e.*,
|
||||||
e.default_winning_upper_limit
|
e.default_winning_upper_limit
|
||||||
) AS winning_upper_limit,
|
) AS winning_upper_limit,
|
||||||
ces.updated_at,
|
ces.updated_at,
|
||||||
l.country_code as league_cc
|
l.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events e
|
FROM events e
|
||||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||||
AND ces.company_id = $1
|
AND ces.company_id = $1
|
||||||
JOIN leagues l ON l.id = e.league_id
|
JOIN leagues l ON l.id = e.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = e.id
|
||||||
WHERE (
|
WHERE (
|
||||||
is_live = sqlc.narg('is_live')
|
is_live = sqlc.narg('is_live')
|
||||||
OR sqlc.narg('is_live') IS NULL
|
OR sqlc.narg('is_live') IS NULL
|
||||||
|
|
@ -292,15 +299,24 @@ SELECT e.*,
|
||||||
e.default_winning_upper_limit
|
e.default_winning_upper_limit
|
||||||
) AS winning_upper_limit,
|
) AS winning_upper_limit,
|
||||||
ces.updated_at,
|
ces.updated_at,
|
||||||
l.country_code as league_cc
|
l.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events e
|
FROM events e
|
||||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||||
AND ces.company_id = $2
|
AND ces.company_id = $2
|
||||||
JOIN leagues l ON l.id = e.league_id
|
JOIN leagues l ON l.id = e.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = e.id
|
||||||
WHERE e.id = $1
|
WHERE e.id = $1
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
-- name: GetSportAndLeagueIDs :one
|
-- name: GetSportAndLeagueIDs :one
|
||||||
SELECT sport_id, league_id FROM events
|
SELECT sport_id,
|
||||||
|
league_id
|
||||||
|
FROM events
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
-- name: UpdateMatchResult :exec
|
-- name: UpdateMatchResult :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
|
|
@ -313,8 +329,22 @@ FROM events
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
-- name: UpdateEventMonitored :exec
|
-- name: UpdateEventMonitored :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
SET is_monitored = $1
|
SET is_monitored = $1,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $2;
|
WHERE id = $2;
|
||||||
|
-- name: UpdateGlobalEventSettings :exec
|
||||||
|
UPDATE events
|
||||||
|
SET default_is_active = COALESCE(sqlc.narg(default_is_active), default_is_active),
|
||||||
|
default_is_featured = COALESCE(
|
||||||
|
sqlc.narg(default_is_featured),
|
||||||
|
default_is_featured
|
||||||
|
),
|
||||||
|
default_winning_upper_limit = COALESCE(
|
||||||
|
sqlc.narg(default_winning_upper_limit),
|
||||||
|
default_winning_upper_limit
|
||||||
|
),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1;
|
||||||
-- name: DeleteEvent :exec
|
-- name: DeleteEvent :exec
|
||||||
DELETE FROM events
|
DELETE FROM events
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
@ -14,7 +14,7 @@ SET name = EXCLUDED.name,
|
||||||
country_code = EXCLUDED.country_code,
|
country_code = EXCLUDED.country_code,
|
||||||
bet365_id = EXCLUDED.bet365_id,
|
bet365_id = EXCLUDED.bet365_id,
|
||||||
sport_id = EXCLUDED.sport_id;
|
sport_id = EXCLUDED.sport_id;
|
||||||
-- name: InsertLeagueSettings :exec
|
-- name: SaveLeagueSettings :exec
|
||||||
INSERT INTO company_league_settings (
|
INSERT INTO company_league_settings (
|
||||||
company_id,
|
company_id,
|
||||||
league_id,
|
league_id,
|
||||||
|
|
@ -40,8 +40,31 @@ WHERE (
|
||||||
name ILIKE '%' || sqlc.narg('query') || '%'
|
name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
OR sqlc.narg('query') IS NULL
|
OR sqlc.narg('query') IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
default_is_active = sqlc.narg('is_active')
|
||||||
|
OR sqlc.narg('is_active') IS NULL
|
||||||
|
)
|
||||||
ORDER BY name ASC
|
ORDER BY name ASC
|
||||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
|
-- name: GetTotalLeagues :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM leagues
|
||||||
|
WHERE (
|
||||||
|
country_code = sqlc.narg('country_code')
|
||||||
|
OR sqlc.narg('country_code') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
sport_id = sqlc.narg('sport_id')
|
||||||
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
default_is_active = sqlc.narg('is_active')
|
||||||
|
OR sqlc.narg('is_active') IS NULL
|
||||||
|
);
|
||||||
-- name: GetTotalLeaguesWithSettings :one
|
-- name: GetTotalLeaguesWithSettings :one
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM leagues l
|
FROM leagues l
|
||||||
|
|
@ -118,7 +141,7 @@ SET name = COALESCE(sqlc.narg('name'), name),
|
||||||
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
||||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
-- name: UpdateLeagueSettings :exec
|
-- name: UpdateCompanyLeagueSettings :exec
|
||||||
UPDATE company_league_settings
|
UPDATE company_league_settings
|
||||||
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||||
is_featured = COALESCE(
|
is_featured = COALESCE(
|
||||||
|
|
@ -126,4 +149,9 @@ SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||||
is_featured
|
is_featured
|
||||||
)
|
)
|
||||||
WHERE league_id = $1
|
WHERE league_id = $1
|
||||||
AND company_id = $2;
|
AND company_id = $2;
|
||||||
|
-- name: UpdateGlobalLeagueSettings :exec
|
||||||
|
UPDATE leagues
|
||||||
|
SET default_is_active = COALESCE(sqlc.narg('is_active'), default_is_active),
|
||||||
|
default_is_featured = COALESCE(sqlc.narg('is_featured'), default_is_featured)
|
||||||
|
WHERE id = $1;
|
||||||
|
|
@ -12,6 +12,8 @@ INSERT INTO notifications (
|
||||||
payload,
|
payload,
|
||||||
priority,
|
priority,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
expires,
|
||||||
|
img,
|
||||||
metadata
|
metadata
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
|
|
@ -27,7 +29,9 @@ VALUES (
|
||||||
$10,
|
$10,
|
||||||
$11,
|
$11,
|
||||||
$12,
|
$12,
|
||||||
$13
|
$13,
|
||||||
|
$14,
|
||||||
|
$15
|
||||||
)
|
)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: GetNotification :one
|
-- name: GetNotification :one
|
||||||
|
|
@ -88,4 +92,8 @@ SELECT COUNT(*) as total,
|
||||||
WHEN is_read = false THEN 1
|
WHEN is_read = false THEN 1
|
||||||
END
|
END
|
||||||
) as unread
|
) as unread
|
||||||
FROM notifications;
|
FROM notifications;
|
||||||
|
|
||||||
|
-- name: DeleteOldNotifications :exec
|
||||||
|
DELETE FROM notifications
|
||||||
|
WHERE expires < now();
|
||||||
|
|
@ -5,6 +5,7 @@ INSERT INTO odds_market (
|
||||||
market_name,
|
market_name,
|
||||||
market_category,
|
market_category,
|
||||||
market_id,
|
market_id,
|
||||||
|
number_of_outcomes,
|
||||||
raw_odds,
|
raw_odds,
|
||||||
fetched_at,
|
fetched_at,
|
||||||
expires_at
|
expires_at
|
||||||
|
|
@ -17,13 +18,15 @@ VALUES (
|
||||||
$5,
|
$5,
|
||||||
$6,
|
$6,
|
||||||
$7,
|
$7,
|
||||||
$8
|
$8,
|
||||||
|
$9
|
||||||
) ON CONFLICT (event_id, market_id) DO
|
) ON CONFLICT (event_id, market_id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET market_type = EXCLUDED.market_type,
|
SET market_type = EXCLUDED.market_type,
|
||||||
market_name = EXCLUDED.market_name,
|
market_name = EXCLUDED.market_name,
|
||||||
market_category = EXCLUDED.market_category,
|
market_category = EXCLUDED.market_category,
|
||||||
raw_odds = EXCLUDED.raw_odds,
|
raw_odds = EXCLUDED.raw_odds,
|
||||||
|
number_of_outcomes = EXCLUDED.number_of_outcomes,
|
||||||
fetched_at = EXCLUDED.fetched_at,
|
fetched_at = EXCLUDED.fetched_at,
|
||||||
expires_at = EXCLUDED.expires_at;
|
expires_at = EXCLUDED.expires_at;
|
||||||
-- name: SaveOddSettings :exec
|
-- name: SaveOddSettings :exec
|
||||||
|
|
@ -48,6 +51,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -75,6 +79,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -94,6 +99,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -129,6 +135,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -143,4 +150,15 @@ WHERE event_id = $1
|
||||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
-- name: DeleteOddsForEvent :exec
|
-- name: DeleteOddsForEvent :exec
|
||||||
DELETE FROM odds_market
|
DELETE FROM odds_market
|
||||||
Where event_id = $1;
|
Where event_id = $1;
|
||||||
|
-- name: DeleteAllCompanyOddsSetting :exec
|
||||||
|
DELETE FROM company_odd_settings
|
||||||
|
WHERE company_id = $1;
|
||||||
|
-- name: DeleteCompanyOddsSettingByOddMarketID :exec
|
||||||
|
DELETE FROM company_odd_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
AND odds_market_id = $2;
|
||||||
|
-- name: UpdateGlobalOddsSetting :exec
|
||||||
|
UPDATE odds_market
|
||||||
|
SET default_is_active = COALESCE(sqlc.narg(default_is_active), default_is_active)
|
||||||
|
WHERE id = $1;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
-- name: CreateRaffle :one
|
-- name: CreateRaffle :one
|
||||||
INSERT INTO raffles (company_id, name, expires_at, type)
|
INSERT INTO raffles (company_id, name, expires_at, ticket_limit, type)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetRafflesOfCompany :many
|
-- name: GetRafflesOfCompany :many
|
||||||
|
|
@ -71,3 +71,19 @@ FROM raffle_sport_filters
|
||||||
WHERE raffle_id = $1
|
WHERE raffle_id = $1
|
||||||
AND sport_id = $2
|
AND sport_id = $2
|
||||||
AND league_id = $3;
|
AND league_id = $3;
|
||||||
|
|
||||||
|
-- name: CheckSportRaffleHasFilter :one
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM raffle_sport_filters WHERE raffle_id = $1
|
||||||
|
) AS has_filter;
|
||||||
|
|
||||||
|
-- name: GetRaffleTicketLimit :one
|
||||||
|
SELECT ticket_limit
|
||||||
|
FROM raffles
|
||||||
|
WHERE id = $1;
|
||||||
|
|
||||||
|
-- name: GetRaffleTicketCount :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM raffle_tickets
|
||||||
|
WHERE raffle_id = $1
|
||||||
|
AND user_id = $2;
|
||||||
|
|
|
||||||
31
db/scripts/fix_autoincrement_desync.sql
Normal file
31
db/scripts/fix_autoincrement_desync.sql
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
-- For each table with an id sequence
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('users', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM users;
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('wallets', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM wallets;
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('customer_wallets', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM customer_wallets;
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('companies', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM companies;
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('branches', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM branches;
|
||||||
|
SELECT setval(
|
||||||
|
pg_get_serial_sequence('supported_operations', 'id'),
|
||||||
|
COALESCE(MAX(id), 1)
|
||||||
|
)
|
||||||
|
FROM supported_operations;
|
||||||
|
|
@ -25,7 +25,7 @@ services:
|
||||||
image: mongo:7.0.11
|
image: mongo:7.0.11
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "27017:27017"
|
- "27022:27017"
|
||||||
environment:
|
environment:
|
||||||
MONGO_INITDB_ROOT_USERNAME: root
|
MONGO_INITDB_ROOT_USERNAME: root
|
||||||
MONGO_INITDB_ROOT_PASSWORD: secret
|
MONGO_INITDB_ROOT_PASSWORD: secret
|
||||||
|
|
@ -56,47 +56,17 @@ services:
|
||||||
]
|
]
|
||||||
networks:
|
networks:
|
||||||
- app
|
- app
|
||||||
|
# redis:
|
||||||
redis:
|
# image: redis:7-alpine
|
||||||
image: redis:7-alpine
|
# ports:
|
||||||
ports:
|
# - "6379:6379"
|
||||||
- "6379:6379"
|
# networks:
|
||||||
networks:
|
# - app
|
||||||
- app
|
# healthcheck:
|
||||||
healthcheck:
|
# test: ["CMD", "redis-cli", "ping"]
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
# interval: 10s
|
||||||
interval: 10s
|
# timeout: 5s
|
||||||
timeout: 5s
|
# retries: 5
|
||||||
retries: 5
|
|
||||||
|
|
||||||
zookeeper:
|
|
||||||
image: confluentinc/cp-zookeeper:7.5.0
|
|
||||||
container_name: zookeeper
|
|
||||||
ports:
|
|
||||||
- "22181:2181" # remapped host port (Windows-safe)
|
|
||||||
environment:
|
|
||||||
ZOOKEEPER_CLIENT_PORT: 2181
|
|
||||||
ZOOKEEPER_TICK_TIME: 2000
|
|
||||||
networks:
|
|
||||||
- app
|
|
||||||
|
|
||||||
kafka:
|
|
||||||
image: confluentinc/cp-kafka:7.5.0
|
|
||||||
depends_on:
|
|
||||||
- zookeeper
|
|
||||||
environment:
|
|
||||||
KAFKA_BROKER_ID: 1
|
|
||||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
|
||||||
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:29092
|
|
||||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
|
|
||||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
|
|
||||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
||||||
ports:
|
|
||||||
- "9092:9092"
|
|
||||||
- "29092:29092"
|
|
||||||
networks:
|
|
||||||
- app
|
|
||||||
|
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
|
|
@ -107,15 +77,9 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- DB_URL=postgresql://root:secret@postgres:5432/gh?sslmode=disable
|
- DB_URL=postgresql://root:secret@postgres:5432/gh?sslmode=disable
|
||||||
- MONGO_URI=mongodb://root:secret@mongo:27017
|
- MONGO_URI=mongodb://root:secret@mongo:27017
|
||||||
- REDIS_ADDR=redis:6379
|
|
||||||
- KAFKA_BROKERS=kafka:9092
|
|
||||||
depends_on:
|
depends_on:
|
||||||
migrate:
|
migrate:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
mongo:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
networks:
|
||||||
- app
|
- app
|
||||||
command: ["/app/bin/web"]
|
command: ["/app/bin/web"]
|
||||||
|
|
|
||||||
2421
docs/docs.go
2421
docs/docs.go
File diff suppressed because it is too large
Load Diff
2421
docs/swagger.json
2421
docs/swagger.json
File diff suppressed because it is too large
Load Diff
1582
docs/swagger.yaml
1582
docs/swagger.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -11,6 +11,22 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const BulkUpdateBetOutcomeStatusByOddIDs = `-- name: BulkUpdateBetOutcomeStatusByOddIDs :exec
|
||||||
|
UPDATE bet_outcomes
|
||||||
|
SET status = $1
|
||||||
|
WHERE odd_id = ANY($2::BIGINT [])
|
||||||
|
`
|
||||||
|
|
||||||
|
type BulkUpdateBetOutcomeStatusByOddIDsParams struct {
|
||||||
|
Status int32 `json:"status"`
|
||||||
|
OddIds []int64 `json:"odd_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) BulkUpdateBetOutcomeStatusByOddIDs(ctx context.Context, arg BulkUpdateBetOutcomeStatusByOddIDsParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, BulkUpdateBetOutcomeStatusByOddIDs, arg.Status, arg.OddIds)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const CreateBet = `-- name: CreateBet :one
|
const CreateBet = `-- name: CreateBet :one
|
||||||
INSERT INTO bets (
|
INSERT INTO bets (
|
||||||
amount,
|
amount,
|
||||||
|
|
@ -104,7 +120,7 @@ func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllBets = `-- name: GetAllBets :many
|
const GetAllBets = `-- name: GetAllBets :many
|
||||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes, company_slug
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
wHERE (
|
wHERE (
|
||||||
user_id = $1
|
user_id = $1
|
||||||
|
|
@ -192,6 +208,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
||||||
&i.FullName,
|
&i.FullName,
|
||||||
&i.PhoneNumber,
|
&i.PhoneNumber,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
|
&i.CompanySlug,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +221,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByFastCode = `-- name: GetBetByFastCode :one
|
const GetBetByFastCode = `-- name: GetBetByFastCode :one
|
||||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes, company_slug
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE fast_code = $1
|
WHERE fast_code = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -230,12 +247,13 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit
|
||||||
&i.FullName,
|
&i.FullName,
|
||||||
&i.PhoneNumber,
|
&i.PhoneNumber,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
|
&i.CompanySlug,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByID = `-- name: GetBetByID :one
|
const GetBetByID = `-- name: GetBetByID :one
|
||||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes, company_slug
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -260,12 +278,13 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
|
||||||
&i.FullName,
|
&i.FullName,
|
||||||
&i.PhoneNumber,
|
&i.PhoneNumber,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
|
&i.CompanySlug,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByUserID = `-- name: GetBetByUserID :many
|
const GetBetByUserID = `-- name: GetBetByUserID :many
|
||||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes, company_slug
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -296,6 +315,7 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID int64) ([]BetWithOu
|
||||||
&i.FullName,
|
&i.FullName,
|
||||||
&i.PhoneNumber,
|
&i.PhoneNumber,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
|
&i.CompanySlug,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -448,8 +468,109 @@ func (q *Queries) GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (i
|
||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GetBetOutcomeViewByEventID = `-- name: GetBetOutcomeViewByEventID :many
|
||||||
|
SELECT bet_outcomes.id, bet_outcomes.bet_id, bet_outcomes.sport_id, bet_outcomes.event_id, bet_outcomes.odd_id, bet_outcomes.home_team_name, bet_outcomes.away_team_name, bet_outcomes.market_id, bet_outcomes.market_name, bet_outcomes.odd, bet_outcomes.odd_name, bet_outcomes.odd_header, bet_outcomes.odd_handicap, bet_outcomes.status, bet_outcomes.expires,
|
||||||
|
users.first_name,
|
||||||
|
users.last_name,
|
||||||
|
bets.amount,
|
||||||
|
bets.total_odds,
|
||||||
|
companies.name as company_name
|
||||||
|
FROM bet_outcomes
|
||||||
|
JOIN bets ON bets.id = bet_outcomes.bet_id
|
||||||
|
JOIN users ON bets.user_id = users.id
|
||||||
|
JOIN companies ON bets.company_id = companies.id
|
||||||
|
WHERE bet_outcomes.event_id = $1
|
||||||
|
AND (
|
||||||
|
bets.company_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
bet_outcomes.status = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
LIMIT $5 OFFSET $4
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetBetOutcomeViewByEventIDParams struct {
|
||||||
|
EventID int64 `json:"event_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
FilterStatus pgtype.Int4 `json:"filter_status"`
|
||||||
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBetOutcomeViewByEventIDRow struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
BetID int64 `json:"bet_id"`
|
||||||
|
SportID int64 `json:"sport_id"`
|
||||||
|
EventID int64 `json:"event_id"`
|
||||||
|
OddID int64 `json:"odd_id"`
|
||||||
|
HomeTeamName string `json:"home_team_name"`
|
||||||
|
AwayTeamName string `json:"away_team_name"`
|
||||||
|
MarketID int64 `json:"market_id"`
|
||||||
|
MarketName string `json:"market_name"`
|
||||||
|
Odd float32 `json:"odd"`
|
||||||
|
OddName string `json:"odd_name"`
|
||||||
|
OddHeader string `json:"odd_header"`
|
||||||
|
OddHandicap string `json:"odd_handicap"`
|
||||||
|
Status int32 `json:"status"`
|
||||||
|
Expires pgtype.Timestamp `json:"expires"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
TotalOdds float32 `json:"total_odds"`
|
||||||
|
CompanyName string `json:"company_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetBetOutcomeViewByEventID(ctx context.Context, arg GetBetOutcomeViewByEventIDParams) ([]GetBetOutcomeViewByEventIDRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetBetOutcomeViewByEventID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.FilterStatus,
|
||||||
|
arg.Offset,
|
||||||
|
arg.Limit,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetBetOutcomeViewByEventIDRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetBetOutcomeViewByEventIDRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.BetID,
|
||||||
|
&i.SportID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.OddID,
|
||||||
|
&i.HomeTeamName,
|
||||||
|
&i.AwayTeamName,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.MarketName,
|
||||||
|
&i.Odd,
|
||||||
|
&i.OddName,
|
||||||
|
&i.OddHeader,
|
||||||
|
&i.OddHandicap,
|
||||||
|
&i.Status,
|
||||||
|
&i.Expires,
|
||||||
|
&i.FirstName,
|
||||||
|
&i.LastName,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TotalOdds,
|
||||||
|
&i.CompanyName,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const GetBetsForCashback = `-- name: GetBetsForCashback :many
|
const GetBetsForCashback = `-- name: GetBetsForCashback :many
|
||||||
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes
|
SELECT id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at, full_name, phone_number, outcomes, company_slug
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE status = 2
|
WHERE status = 2
|
||||||
AND processed = false
|
AND processed = false
|
||||||
|
|
@ -481,6 +602,7 @@ func (q *Queries) GetBetsForCashback(ctx context.Context) ([]BetWithOutcome, err
|
||||||
&i.FullName,
|
&i.FullName,
|
||||||
&i.PhoneNumber,
|
&i.PhoneNumber,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
|
&i.CompanySlug,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -557,6 +679,34 @@ func (q *Queries) GetTotalBets(ctx context.Context, arg GetTotalBetsParams) (int
|
||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TotalBetOutcomeViewByEventID = `-- name: TotalBetOutcomeViewByEventID :one
|
||||||
|
SELECT count(*)
|
||||||
|
FROM bet_outcomes
|
||||||
|
JOIN bets ON bets.id = bet_outcomes.bet_id
|
||||||
|
WHERE bet_outcomes.event_id = $1
|
||||||
|
AND (
|
||||||
|
bets.company_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
bet_outcomes.status = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type TotalBetOutcomeViewByEventIDParams struct {
|
||||||
|
EventID int64 `json:"event_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
FilterStatus pgtype.Int4 `json:"filter_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) TotalBetOutcomeViewByEventID(ctx context.Context, arg TotalBetOutcomeViewByEventIDParams) (int64, error) {
|
||||||
|
row := q.db.QueryRow(ctx, TotalBetOutcomeViewByEventID, arg.EventID, arg.CompanyID, arg.FilterStatus)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
const UpdateBetOutcomeStatus = `-- name: UpdateBetOutcomeStatus :one
|
const UpdateBetOutcomeStatus = `-- name: UpdateBetOutcomeStatus :one
|
||||||
UPDATE bet_outcomes
|
UPDATE bet_outcomes
|
||||||
SET status = $1
|
SET status = $1
|
||||||
|
|
@ -675,6 +825,54 @@ func (q *Queries) UpdateBetOutcomeStatusForEvent(ctx context.Context, arg Update
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UpdateBetOutcomeStatusForOddID = `-- name: UpdateBetOutcomeStatusForOddID :many
|
||||||
|
UPDATE bet_outcomes
|
||||||
|
SEt status = $1
|
||||||
|
WHERE odd_id = $2
|
||||||
|
RETURNING id, bet_id, sport_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, status, expires
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateBetOutcomeStatusForOddIDParams struct {
|
||||||
|
Status int32 `json:"status"`
|
||||||
|
OddID int64 `json:"odd_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateBetOutcomeStatusForOddID(ctx context.Context, arg UpdateBetOutcomeStatusForOddIDParams) ([]BetOutcome, error) {
|
||||||
|
rows, err := q.db.Query(ctx, UpdateBetOutcomeStatusForOddID, arg.Status, arg.OddID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []BetOutcome
|
||||||
|
for rows.Next() {
|
||||||
|
var i BetOutcome
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.BetID,
|
||||||
|
&i.SportID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.OddID,
|
||||||
|
&i.HomeTeamName,
|
||||||
|
&i.AwayTeamName,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.MarketName,
|
||||||
|
&i.Odd,
|
||||||
|
&i.OddName,
|
||||||
|
&i.OddHeader,
|
||||||
|
&i.OddHandicap,
|
||||||
|
&i.Status,
|
||||||
|
&i.Expires,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const UpdateBetWithCashback = `-- name: UpdateBetWithCashback :exec
|
const UpdateBetWithCashback = `-- name: UpdateBetWithCashback :exec
|
||||||
UPDATE bets
|
UPDATE bets
|
||||||
SET processed = $1
|
SET processed = $1
|
||||||
|
|
|
||||||
|
|
@ -34,32 +34,37 @@ wHERE (
|
||||||
OR $1 IS NULL
|
OR $1 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
is_shop_bet = $2
|
company_id = $2
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
cashed_out = $3
|
is_shop_bet = $3
|
||||||
OR $3 IS NULL
|
OR $3 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
full_name ILIKE '%' || $4 || '%'
|
cashed_out = $4
|
||||||
OR phone_number ILIKE '%' || $4 || '%'
|
|
||||||
OR $4 IS NULL
|
OR $4 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at > $5
|
full_name ILIKE '%' || $5 || '%'
|
||||||
|
OR phone_number ILIKE '%' || $5 || '%'
|
||||||
OR $5 IS NULL
|
OR $5 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at < $6
|
created_at > $6
|
||||||
OR $6 IS NULL
|
OR $6 IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $7
|
||||||
|
OR $7 IS NULL
|
||||||
|
)
|
||||||
GROUP BY DATE(created_at)
|
GROUP BY DATE(created_at)
|
||||||
ORDER BY DATE(created_at)
|
ORDER BY DATE(created_at)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetBetStatsParams struct {
|
type GetBetStatsParams struct {
|
||||||
UserID pgtype.Int8 `json:"user_id"`
|
UserID pgtype.Int8 `json:"user_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
IsShopBet pgtype.Bool `json:"is_shop_bet"`
|
IsShopBet pgtype.Bool `json:"is_shop_bet"`
|
||||||
CashedOut pgtype.Bool `json:"cashed_out"`
|
CashedOut pgtype.Bool `json:"cashed_out"`
|
||||||
Query pgtype.Text `json:"query"`
|
Query pgtype.Text `json:"query"`
|
||||||
|
|
@ -79,6 +84,7 @@ type GetBetStatsRow struct {
|
||||||
func (q *Queries) GetBetStats(ctx context.Context, arg GetBetStatsParams) ([]GetBetStatsRow, error) {
|
func (q *Queries) GetBetStats(ctx context.Context, arg GetBetStatsParams) ([]GetBetStatsRow, error) {
|
||||||
rows, err := q.db.Query(ctx, GetBetStats,
|
rows, err := q.db.Query(ctx, GetBetStats,
|
||||||
arg.UserID,
|
arg.UserID,
|
||||||
|
arg.CompanyID,
|
||||||
arg.IsShopBet,
|
arg.IsShopBet,
|
||||||
arg.CashedOut,
|
arg.CashedOut,
|
||||||
arg.Query,
|
arg.Query,
|
||||||
|
|
@ -143,17 +149,22 @@ wHERE (
|
||||||
OR $1 IS NULL
|
OR $1 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at > $2
|
company_id = $2
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at < $3
|
created_at > $3
|
||||||
OR $3 IS NULL
|
OR $3 IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetBetSummaryParams struct {
|
type GetBetSummaryParams struct {
|
||||||
UserID pgtype.Int8 `json:"user_id"`
|
UserID pgtype.Int8 `json:"user_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +179,12 @@ type GetBetSummaryRow struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetBetSummary(ctx context.Context, arg GetBetSummaryParams) (GetBetSummaryRow, error) {
|
func (q *Queries) GetBetSummary(ctx context.Context, arg GetBetSummaryParams) (GetBetSummaryRow, error) {
|
||||||
row := q.db.QueryRow(ctx, GetBetSummary, arg.UserID, arg.CreatedBefore, arg.CreatedAfter)
|
row := q.db.QueryRow(ctx, GetBetSummary,
|
||||||
|
arg.UserID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
var i GetBetSummaryRow
|
var i GetBetSummaryRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.TotalStakes,
|
&i.TotalStakes,
|
||||||
|
|
@ -198,13 +214,17 @@ WITH market_counts AS (
|
||||||
OR $1 IS NULL
|
OR $1 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at > $2
|
company_id = $2
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
created_at < $3
|
created_at > $3
|
||||||
OR $3 IS NULL
|
OR $3 IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
GROUP BY DATE(b.created_at),
|
GROUP BY DATE(b.created_at),
|
||||||
bo.market_name
|
bo.market_name
|
||||||
)
|
)
|
||||||
|
|
@ -216,6 +236,7 @@ WHERE rank = 1
|
||||||
|
|
||||||
type GetMarketPopularityParams struct {
|
type GetMarketPopularityParams struct {
|
||||||
UserID pgtype.Int8 `json:"user_id"`
|
UserID pgtype.Int8 `json:"user_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +247,12 @@ type GetMarketPopularityRow struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetMarketPopularity(ctx context.Context, arg GetMarketPopularityParams) (GetMarketPopularityRow, error) {
|
func (q *Queries) GetMarketPopularity(ctx context.Context, arg GetMarketPopularityParams) (GetMarketPopularityRow, error) {
|
||||||
row := q.db.QueryRow(ctx, GetMarketPopularity, arg.UserID, arg.CreatedBefore, arg.CreatedAfter)
|
row := q.db.QueryRow(ctx, GetMarketPopularity,
|
||||||
|
arg.UserID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
var i GetMarketPopularityRow
|
var i GetMarketPopularityRow
|
||||||
err := row.Scan(&i.Date, &i.MarketName)
|
err := row.Scan(&i.Date, &i.MarketName)
|
||||||
return i, err
|
return i, err
|
||||||
|
|
|
||||||
|
|
@ -455,10 +455,19 @@ const SearchBranchByName = `-- name: SearchBranchByName :many
|
||||||
SELECT id, name, location, profit_percent, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number, balance, wallet_is_active
|
SELECT id, name, location, profit_percent, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number, balance, wallet_is_active
|
||||||
FROM branch_details
|
FROM branch_details
|
||||||
WHERE name ILIKE '%' || $1 || '%'
|
WHERE name ILIKE '%' || $1 || '%'
|
||||||
|
AND (
|
||||||
|
company_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text) ([]BranchDetail, error) {
|
type SearchBranchByNameParams struct {
|
||||||
rows, err := q.db.Query(ctx, SearchBranchByName, dollar_1)
|
Column1 pgtype.Text `json:"column_1"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) SearchBranchByName(ctx context.Context, arg SearchBranchByNameParams) ([]BranchDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, SearchBranchByName, arg.Column1, arg.CompanyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ INSERT INTO companies (
|
||||||
slug,
|
slug,
|
||||||
admin_id,
|
admin_id,
|
||||||
wallet_id,
|
wallet_id,
|
||||||
deducted_percentage
|
deducted_percentage,
|
||||||
|
is_active
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -29,6 +30,7 @@ type CreateCompanyParams struct {
|
||||||
AdminID int64 `json:"admin_id"`
|
AdminID int64 `json:"admin_id"`
|
||||||
WalletID int64 `json:"wallet_id"`
|
WalletID int64 `json:"wallet_id"`
|
||||||
DeductedPercentage float32 `json:"deducted_percentage"`
|
DeductedPercentage float32 `json:"deducted_percentage"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
|
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
|
||||||
|
|
@ -38,6 +40,7 @@ func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (C
|
||||||
arg.AdminID,
|
arg.AdminID,
|
||||||
arg.WalletID,
|
arg.WalletID,
|
||||||
arg.DeductedPercentage,
|
arg.DeductedPercentage,
|
||||||
|
arg.IsActive,
|
||||||
)
|
)
|
||||||
var i Company
|
var i Company
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
|
|
@ -153,17 +156,27 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetCompanyIDUsingSlug = `-- name: GetCompanyIDUsingSlug :one
|
const GetCompanyUsingSlug = `-- name: GetCompanyUsingSlug :one
|
||||||
SELECT id
|
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
||||||
FROM companies
|
FROM companies
|
||||||
WHERE slug = $1
|
WHERE slug = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetCompanyIDUsingSlug(ctx context.Context, slug string) (int64, error) {
|
func (q *Queries) GetCompanyUsingSlug(ctx context.Context, slug string) (Company, error) {
|
||||||
row := q.db.QueryRow(ctx, GetCompanyIDUsingSlug, slug)
|
row := q.db.QueryRow(ctx, GetCompanyUsingSlug, slug)
|
||||||
var id int64
|
var i Company
|
||||||
err := row.Scan(&id)
|
err := row.Scan(
|
||||||
return id, err
|
&i.ID,
|
||||||
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
|
&i.AdminID,
|
||||||
|
&i.WalletID,
|
||||||
|
&i.DeductedPercentage,
|
||||||
|
&i.IsActive,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
||||||
|
|
@ -207,7 +220,7 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const UpdateCompany = `-- name: UpdateCompany :one
|
const UpdateCompany = `-- name: UpdateCompany :exec
|
||||||
UPDATE companies
|
UPDATE companies
|
||||||
SET name = COALESCE($2, name),
|
SET name = COALESCE($2, name),
|
||||||
admin_id = COALESCE($3, admin_id),
|
admin_id = COALESCE($3, admin_id),
|
||||||
|
|
@ -216,9 +229,9 @@ SET name = COALESCE($2, name),
|
||||||
$5,
|
$5,
|
||||||
deducted_percentage
|
deducted_percentage
|
||||||
),
|
),
|
||||||
|
slug = COALESCE($6, slug),
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateCompanyParams struct {
|
type UpdateCompanyParams struct {
|
||||||
|
|
@ -227,27 +240,17 @@ type UpdateCompanyParams struct {
|
||||||
AdminID pgtype.Int8 `json:"admin_id"`
|
AdminID pgtype.Int8 `json:"admin_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
DeductedPercentage pgtype.Float4 `json:"deducted_percentage"`
|
DeductedPercentage pgtype.Float4 `json:"deducted_percentage"`
|
||||||
|
Slug pgtype.Text `json:"slug"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (Company, error) {
|
func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) error {
|
||||||
row := q.db.QueryRow(ctx, UpdateCompany,
|
_, err := q.db.Exec(ctx, UpdateCompany,
|
||||||
arg.ID,
|
arg.ID,
|
||||||
arg.Name,
|
arg.Name,
|
||||||
arg.AdminID,
|
arg.AdminID,
|
||||||
arg.IsActive,
|
arg.IsActive,
|
||||||
arg.DeductedPercentage,
|
arg.DeductedPercentage,
|
||||||
|
arg.Slug,
|
||||||
)
|
)
|
||||||
var i Company
|
return err
|
||||||
err := row.Scan(
|
|
||||||
&i.ID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Slug,
|
|
||||||
&i.AdminID,
|
|
||||||
&i.WalletID,
|
|
||||||
&i.DeductedPercentage,
|
|
||||||
&i.IsActive,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -643,7 +643,8 @@ INSERT INTO enetpulse_tournament_stages (
|
||||||
updates_count,
|
updates_count,
|
||||||
last_updated_at,
|
last_updated_at,
|
||||||
status
|
status
|
||||||
) VALUES (
|
)
|
||||||
|
VALUES (
|
||||||
$1, -- stage_id
|
$1, -- stage_id
|
||||||
$2, -- name
|
$2, -- name
|
||||||
$3, -- tournament_fk
|
$3, -- tournament_fk
|
||||||
|
|
@ -656,6 +657,19 @@ INSERT INTO enetpulse_tournament_stages (
|
||||||
$10, -- last_updated_at
|
$10, -- last_updated_at
|
||||||
$11 -- status
|
$11 -- status
|
||||||
)
|
)
|
||||||
|
ON CONFLICT (stage_id) DO UPDATE
|
||||||
|
SET
|
||||||
|
name = EXCLUDED.name,
|
||||||
|
tournament_fk = EXCLUDED.tournament_fk,
|
||||||
|
gender = EXCLUDED.gender,
|
||||||
|
country_fk = EXCLUDED.country_fk,
|
||||||
|
country_name = EXCLUDED.country_name,
|
||||||
|
start_date = EXCLUDED.start_date,
|
||||||
|
end_date = EXCLUDED.end_date,
|
||||||
|
updates_count = EXCLUDED.updates_count,
|
||||||
|
last_updated_at = EXCLUDED.last_updated_at,
|
||||||
|
status = EXCLUDED.status,
|
||||||
|
updated_at = NOW()
|
||||||
RETURNING id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
RETURNING id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -1158,6 +1172,134 @@ func (q *Queries) GetAllEnetpulseTournaments(ctx context.Context) ([]EnetpulseTo
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GetFixturesWithPreodds = `-- name: GetFixturesWithPreodds :many
|
||||||
|
SELECT
|
||||||
|
f.fixture_id AS id,
|
||||||
|
f.fixture_id AS fixture_id,
|
||||||
|
f.name AS fixture_name,
|
||||||
|
f.sport_fk,
|
||||||
|
f.tournament_fk,
|
||||||
|
f.tournament_template_fk,
|
||||||
|
f.tournament_stage_fk,
|
||||||
|
f.start_date,
|
||||||
|
f.status_type,
|
||||||
|
f.status_desc_fk,
|
||||||
|
f.round_type_fk,
|
||||||
|
f.updates_count AS fixture_updates_count,
|
||||||
|
f.last_updated_at AS fixture_last_updated_at,
|
||||||
|
f.created_at AS fixture_created_at,
|
||||||
|
f.updated_at AS fixture_updated_at,
|
||||||
|
|
||||||
|
-- Preodds fields
|
||||||
|
p.id AS preodds_db_id,
|
||||||
|
p.preodds_id,
|
||||||
|
p.event_fk,
|
||||||
|
p.outcome_type_fk,
|
||||||
|
p.outcome_scope_fk,
|
||||||
|
p.outcome_subtype_fk,
|
||||||
|
p.event_participant_number,
|
||||||
|
p.iparam,
|
||||||
|
p.iparam2,
|
||||||
|
p.dparam,
|
||||||
|
p.dparam2,
|
||||||
|
p.sparam,
|
||||||
|
p.updates_count AS preodds_updates_count,
|
||||||
|
p.last_updated_at AS preodds_last_updated_at,
|
||||||
|
p.created_at AS preodds_created_at,
|
||||||
|
p.updated_at AS preodds_updated_at
|
||||||
|
|
||||||
|
FROM enetpulse_fixtures f
|
||||||
|
LEFT JOIN enetpulse_preodds p
|
||||||
|
ON p.event_fk = f.id
|
||||||
|
ORDER BY f.start_date DESC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetFixturesWithPreoddsRow struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
FixtureID string `json:"fixture_id"`
|
||||||
|
FixtureName string `json:"fixture_name"`
|
||||||
|
SportFk string `json:"sport_fk"`
|
||||||
|
TournamentFk pgtype.Text `json:"tournament_fk"`
|
||||||
|
TournamentTemplateFk pgtype.Text `json:"tournament_template_fk"`
|
||||||
|
TournamentStageFk pgtype.Text `json:"tournament_stage_fk"`
|
||||||
|
StartDate pgtype.Timestamptz `json:"start_date"`
|
||||||
|
StatusType pgtype.Text `json:"status_type"`
|
||||||
|
StatusDescFk pgtype.Text `json:"status_desc_fk"`
|
||||||
|
RoundTypeFk pgtype.Text `json:"round_type_fk"`
|
||||||
|
FixtureUpdatesCount pgtype.Int4 `json:"fixture_updates_count"`
|
||||||
|
FixtureLastUpdatedAt pgtype.Timestamptz `json:"fixture_last_updated_at"`
|
||||||
|
FixtureCreatedAt pgtype.Timestamptz `json:"fixture_created_at"`
|
||||||
|
FixtureUpdatedAt pgtype.Timestamptz `json:"fixture_updated_at"`
|
||||||
|
PreoddsDbID pgtype.Int8 `json:"preodds_db_id"`
|
||||||
|
PreoddsID pgtype.Text `json:"preodds_id"`
|
||||||
|
EventFk pgtype.Int8 `json:"event_fk"`
|
||||||
|
OutcomeTypeFk pgtype.Int4 `json:"outcome_type_fk"`
|
||||||
|
OutcomeScopeFk pgtype.Int4 `json:"outcome_scope_fk"`
|
||||||
|
OutcomeSubtypeFk pgtype.Int4 `json:"outcome_subtype_fk"`
|
||||||
|
EventParticipantNumber pgtype.Int4 `json:"event_participant_number"`
|
||||||
|
Iparam pgtype.Text `json:"iparam"`
|
||||||
|
Iparam2 pgtype.Text `json:"iparam2"`
|
||||||
|
Dparam pgtype.Text `json:"dparam"`
|
||||||
|
Dparam2 pgtype.Text `json:"dparam2"`
|
||||||
|
Sparam pgtype.Text `json:"sparam"`
|
||||||
|
PreoddsUpdatesCount pgtype.Int4 `json:"preodds_updates_count"`
|
||||||
|
PreoddsLastUpdatedAt pgtype.Timestamptz `json:"preodds_last_updated_at"`
|
||||||
|
PreoddsCreatedAt pgtype.Timestamptz `json:"preodds_created_at"`
|
||||||
|
PreoddsUpdatedAt pgtype.Timestamptz `json:"preodds_updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetFixturesWithPreodds(ctx context.Context) ([]GetFixturesWithPreoddsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetFixturesWithPreodds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetFixturesWithPreoddsRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetFixturesWithPreoddsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FixtureID,
|
||||||
|
&i.FixtureName,
|
||||||
|
&i.SportFk,
|
||||||
|
&i.TournamentFk,
|
||||||
|
&i.TournamentTemplateFk,
|
||||||
|
&i.TournamentStageFk,
|
||||||
|
&i.StartDate,
|
||||||
|
&i.StatusType,
|
||||||
|
&i.StatusDescFk,
|
||||||
|
&i.RoundTypeFk,
|
||||||
|
&i.FixtureUpdatesCount,
|
||||||
|
&i.FixtureLastUpdatedAt,
|
||||||
|
&i.FixtureCreatedAt,
|
||||||
|
&i.FixtureUpdatedAt,
|
||||||
|
&i.PreoddsDbID,
|
||||||
|
&i.PreoddsID,
|
||||||
|
&i.EventFk,
|
||||||
|
&i.OutcomeTypeFk,
|
||||||
|
&i.OutcomeScopeFk,
|
||||||
|
&i.OutcomeSubtypeFk,
|
||||||
|
&i.EventParticipantNumber,
|
||||||
|
&i.Iparam,
|
||||||
|
&i.Iparam2,
|
||||||
|
&i.Dparam,
|
||||||
|
&i.Dparam2,
|
||||||
|
&i.Sparam,
|
||||||
|
&i.PreoddsUpdatesCount,
|
||||||
|
&i.PreoddsLastUpdatedAt,
|
||||||
|
&i.PreoddsCreatedAt,
|
||||||
|
&i.PreoddsUpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const GetTournamentStagesByTournamentFK = `-- name: GetTournamentStagesByTournamentFK :many
|
const GetTournamentStagesByTournamentFK = `-- name: GetTournamentStagesByTournamentFK :many
|
||||||
SELECT id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
SELECT id, stage_id, name, tournament_fk, gender, country_fk, country_name, start_date, end_date, updates_count, last_updated_at, status, created_at, updated_at
|
||||||
FROM enetpulse_tournament_stages
|
FROM enetpulse_tournament_stages
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ func (q *Queries) DeleteEvent(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllEvents = `-- name: GetAllEvents :many
|
const GetAllEvents = `-- name: GetAllEvents :many
|
||||||
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc
|
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, updated_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc, total_outcomes
|
||||||
FROM event_with_country
|
FROM event_with_country
|
||||||
WHERE (
|
WHERE (
|
||||||
is_live = $1
|
is_live = $1
|
||||||
|
|
@ -122,12 +122,14 @@ func (q *Queries) GetAllEvents(ctx context.Context, arg GetAllEventsParams) ([]E
|
||||||
&i.IsLive,
|
&i.IsLive,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.DefaultIsFeatured,
|
&i.DefaultIsFeatured,
|
||||||
&i.DefaultWinningUpperLimit,
|
&i.DefaultWinningUpperLimit,
|
||||||
&i.IsMonitored,
|
&i.IsMonitored,
|
||||||
&i.LeagueCc,
|
&i.LeagueCc,
|
||||||
|
&i.TotalOutcomes,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +142,7 @@ func (q *Queries) GetAllEvents(ctx context.Context, arg GetAllEventsParams) ([]E
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetEventByID = `-- name: GetEventByID :one
|
const GetEventByID = `-- name: GetEventByID :one
|
||||||
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc
|
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, updated_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc, total_outcomes
|
||||||
FROM event_with_country
|
FROM event_with_country
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -171,18 +173,20 @@ func (q *Queries) GetEventByID(ctx context.Context, id int64) (EventWithCountry,
|
||||||
&i.IsLive,
|
&i.IsLive,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.DefaultIsFeatured,
|
&i.DefaultIsFeatured,
|
||||||
&i.DefaultWinningUpperLimit,
|
&i.DefaultWinningUpperLimit,
|
||||||
&i.IsMonitored,
|
&i.IsMonitored,
|
||||||
&i.LeagueCc,
|
&i.LeagueCc,
|
||||||
|
&i.TotalOutcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetEventBySourceID = `-- name: GetEventBySourceID :one
|
const GetEventBySourceID = `-- name: GetEventBySourceID :one
|
||||||
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc
|
SELECT id, source_event_id, sport_id, match_name, home_team, away_team, home_team_id, away_team_id, home_kit_image, away_kit_image, league_id, league_name, start_time, score, match_minute, timer_status, added_time, match_period, is_live, status, fetched_at, updated_at, source, default_is_active, default_is_featured, default_winning_upper_limit, is_monitored, league_cc, total_outcomes
|
||||||
FROM event_with_country
|
FROM event_with_country
|
||||||
WHERE source_event_id = $1
|
WHERE source_event_id = $1
|
||||||
AND source = $2
|
AND source = $2
|
||||||
|
|
@ -218,18 +222,20 @@ func (q *Queries) GetEventBySourceID(ctx context.Context, arg GetEventBySourceID
|
||||||
&i.IsLive,
|
&i.IsLive,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.DefaultIsFeatured,
|
&i.DefaultIsFeatured,
|
||||||
&i.DefaultWinningUpperLimit,
|
&i.DefaultWinningUpperLimit,
|
||||||
&i.IsMonitored,
|
&i.IsMonitored,
|
||||||
&i.LeagueCc,
|
&i.LeagueCc,
|
||||||
|
&i.TotalOutcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetEventWithSettingByID = `-- name: GetEventWithSettingByID :one
|
const GetEventWithSettingByID = `-- name: GetEventWithSettingByID :one
|
||||||
SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_team, e.home_team_id, e.away_team_id, e.home_kit_image, e.away_kit_image, e.league_id, e.league_name, e.start_time, e.score, e.match_minute, e.timer_status, e.added_time, e.match_period, e.is_live, e.status, e.fetched_at, e.source, e.default_is_active, e.default_is_featured, e.default_winning_upper_limit, e.is_monitored,
|
SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_team, e.home_team_id, e.away_team_id, e.home_kit_image, e.away_kit_image, e.league_id, e.league_name, e.start_time, e.score, e.match_minute, e.timer_status, e.added_time, e.match_period, e.is_live, e.status, e.fetched_at, e.updated_at, e.source, e.default_is_active, e.default_is_featured, e.default_winning_upper_limit, e.is_monitored,
|
||||||
ces.company_id,
|
ces.company_id,
|
||||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||||
|
|
@ -238,11 +244,18 @@ SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_te
|
||||||
e.default_winning_upper_limit
|
e.default_winning_upper_limit
|
||||||
) AS winning_upper_limit,
|
) AS winning_upper_limit,
|
||||||
ces.updated_at,
|
ces.updated_at,
|
||||||
l.country_code as league_cc
|
l.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events e
|
FROM events e
|
||||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||||
AND ces.company_id = $2
|
AND ces.company_id = $2
|
||||||
JOIN leagues l ON l.id = e.league_id
|
JOIN leagues l ON l.id = e.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = e.id
|
||||||
WHERE e.id = $1
|
WHERE e.id = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
@ -274,6 +287,7 @@ type GetEventWithSettingByIDRow struct {
|
||||||
IsLive bool `json:"is_live"`
|
IsLive bool `json:"is_live"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
|
@ -282,9 +296,10 @@ type GetEventWithSettingByIDRow struct {
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
WinningUpperLimit int64 `json:"winning_upper_limit"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt_2 pgtype.Timestamp `json:"updated_at_2"`
|
||||||
LeagueCc pgtype.Text `json:"league_cc"`
|
LeagueCc pgtype.Text `json:"league_cc"`
|
||||||
|
TotalOutcomes int64 `json:"total_outcomes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithSettingByIDParams) (GetEventWithSettingByIDRow, error) {
|
func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithSettingByIDParams) (GetEventWithSettingByIDRow, error) {
|
||||||
|
|
@ -312,6 +327,7 @@ func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithS
|
||||||
&i.IsLive,
|
&i.IsLive,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.DefaultIsFeatured,
|
&i.DefaultIsFeatured,
|
||||||
|
|
@ -321,14 +337,15 @@ func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithS
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.IsFeatured,
|
&i.IsFeatured,
|
||||||
&i.WinningUpperLimit,
|
&i.WinningUpperLimit,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt_2,
|
||||||
&i.LeagueCc,
|
&i.LeagueCc,
|
||||||
|
&i.TotalOutcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetEventsWithSettings = `-- name: GetEventsWithSettings :many
|
const GetEventsWithSettings = `-- name: GetEventsWithSettings :many
|
||||||
SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_team, e.home_team_id, e.away_team_id, e.home_kit_image, e.away_kit_image, e.league_id, e.league_name, e.start_time, e.score, e.match_minute, e.timer_status, e.added_time, e.match_period, e.is_live, e.status, e.fetched_at, e.source, e.default_is_active, e.default_is_featured, e.default_winning_upper_limit, e.is_monitored,
|
SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_team, e.home_team_id, e.away_team_id, e.home_kit_image, e.away_kit_image, e.league_id, e.league_name, e.start_time, e.score, e.match_minute, e.timer_status, e.added_time, e.match_period, e.is_live, e.status, e.fetched_at, e.updated_at, e.source, e.default_is_active, e.default_is_featured, e.default_winning_upper_limit, e.is_monitored,
|
||||||
ces.company_id,
|
ces.company_id,
|
||||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||||
|
|
@ -337,11 +354,18 @@ SELECT e.id, e.source_event_id, e.sport_id, e.match_name, e.home_team, e.away_te
|
||||||
e.default_winning_upper_limit
|
e.default_winning_upper_limit
|
||||||
) AS winning_upper_limit,
|
) AS winning_upper_limit,
|
||||||
ces.updated_at,
|
ces.updated_at,
|
||||||
l.country_code as league_cc
|
l.country_code as league_cc,
|
||||||
|
COALESCE(om.total_outcomes, 0) AS total_outcomes
|
||||||
FROM events e
|
FROM events e
|
||||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||||
AND ces.company_id = $1
|
AND ces.company_id = $1
|
||||||
JOIN leagues l ON l.id = e.league_id
|
JOIN leagues l ON l.id = e.league_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT event_id,
|
||||||
|
SUM(number_of_outcomes) AS total_outcomes
|
||||||
|
FROM odds_market
|
||||||
|
GROUP BY event_id
|
||||||
|
) om ON om.event_id = e.id
|
||||||
WHERE (
|
WHERE (
|
||||||
is_live = $2
|
is_live = $2
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
|
|
@ -432,6 +456,7 @@ type GetEventsWithSettingsRow struct {
|
||||||
IsLive bool `json:"is_live"`
|
IsLive bool `json:"is_live"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
|
@ -440,9 +465,10 @@ type GetEventsWithSettingsRow struct {
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
WinningUpperLimit int64 `json:"winning_upper_limit"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt_2 pgtype.Timestamp `json:"updated_at_2"`
|
||||||
LeagueCc pgtype.Text `json:"league_cc"`
|
LeagueCc pgtype.Text `json:"league_cc"`
|
||||||
|
TotalOutcomes int64 `json:"total_outcomes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSettingsParams) ([]GetEventsWithSettingsRow, error) {
|
func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSettingsParams) ([]GetEventsWithSettingsRow, error) {
|
||||||
|
|
@ -491,6 +517,7 @@ func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSe
|
||||||
&i.IsLive,
|
&i.IsLive,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.DefaultIsFeatured,
|
&i.DefaultIsFeatured,
|
||||||
|
|
@ -500,8 +527,9 @@ func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSe
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.IsFeatured,
|
&i.IsFeatured,
|
||||||
&i.WinningUpperLimit,
|
&i.WinningUpperLimit,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt_2,
|
||||||
&i.LeagueCc,
|
&i.LeagueCc,
|
||||||
|
&i.TotalOutcomes,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -514,7 +542,9 @@ func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSe
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetSportAndLeagueIDs = `-- name: GetSportAndLeagueIDs :one
|
const GetSportAndLeagueIDs = `-- name: GetSportAndLeagueIDs :one
|
||||||
SELECT sport_id, league_id FROM events
|
SELECT sport_id,
|
||||||
|
league_id
|
||||||
|
FROM events
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -831,7 +861,7 @@ func (q *Queries) ListLiveEvents(ctx context.Context) ([]int64, error) {
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const SaveEventSettings = `-- name: SaveEventSettings :exec
|
const SaveTenantEventSettings = `-- name: SaveTenantEventSettings :exec
|
||||||
INSERT INTO company_event_settings (
|
INSERT INTO company_event_settings (
|
||||||
company_id,
|
company_id,
|
||||||
event_id,
|
event_id,
|
||||||
|
|
@ -846,16 +876,16 @@ SET is_active = EXCLUDED.is_active,
|
||||||
winning_upper_limit = EXCLUDED.winning_upper_limit
|
winning_upper_limit = EXCLUDED.winning_upper_limit
|
||||||
`
|
`
|
||||||
|
|
||||||
type SaveEventSettingsParams struct {
|
type SaveTenantEventSettingsParams struct {
|
||||||
CompanyID int64 `json:"company_id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
WinningUpperLimit pgtype.Int4 `json:"winning_upper_limit"`
|
WinningUpperLimit pgtype.Int8 `json:"winning_upper_limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SaveEventSettings(ctx context.Context, arg SaveEventSettingsParams) error {
|
func (q *Queries) SaveTenantEventSettings(ctx context.Context, arg SaveTenantEventSettingsParams) error {
|
||||||
_, err := q.db.Exec(ctx, SaveEventSettings,
|
_, err := q.db.Exec(ctx, SaveTenantEventSettings,
|
||||||
arg.CompanyID,
|
arg.CompanyID,
|
||||||
arg.EventID,
|
arg.EventID,
|
||||||
arg.IsActive,
|
arg.IsActive,
|
||||||
|
|
@ -867,7 +897,8 @@ func (q *Queries) SaveEventSettings(ctx context.Context, arg SaveEventSettingsPa
|
||||||
|
|
||||||
const UpdateEventMonitored = `-- name: UpdateEventMonitored :exec
|
const UpdateEventMonitored = `-- name: UpdateEventMonitored :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
SET is_monitored = $1
|
SET is_monitored = $1,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $2
|
WHERE id = $2
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -881,6 +912,38 @@ func (q *Queries) UpdateEventMonitored(ctx context.Context, arg UpdateEventMonit
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UpdateGlobalEventSettings = `-- name: UpdateGlobalEventSettings :exec
|
||||||
|
UPDATE events
|
||||||
|
SET default_is_active = COALESCE($2, default_is_active),
|
||||||
|
default_is_featured = COALESCE(
|
||||||
|
$3,
|
||||||
|
default_is_featured
|
||||||
|
),
|
||||||
|
default_winning_upper_limit = COALESCE(
|
||||||
|
$4,
|
||||||
|
default_winning_upper_limit
|
||||||
|
),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateGlobalEventSettingsParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
DefaultIsActive pgtype.Bool `json:"default_is_active"`
|
||||||
|
DefaultIsFeatured pgtype.Bool `json:"default_is_featured"`
|
||||||
|
DefaultWinningUpperLimit pgtype.Int8 `json:"default_winning_upper_limit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateGlobalEventSettings(ctx context.Context, arg UpdateGlobalEventSettingsParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateGlobalEventSettings,
|
||||||
|
arg.ID,
|
||||||
|
arg.DefaultIsActive,
|
||||||
|
arg.DefaultIsFeatured,
|
||||||
|
arg.DefaultWinningUpperLimit,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const UpdateMatchResult = `-- name: UpdateMatchResult :exec
|
const UpdateMatchResult = `-- name: UpdateMatchResult :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
SET score = $1,
|
SET score = $1,
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,19 @@ WHERE (
|
||||||
name ILIKE '%' || $3 || '%'
|
name ILIKE '%' || $3 || '%'
|
||||||
OR $3 IS NULL
|
OR $3 IS NULL
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
default_is_active = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
ORDER BY name ASC
|
ORDER BY name ASC
|
||||||
LIMIT $5 OFFSET $4
|
LIMIT $6 OFFSET $5
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetAllLeaguesParams struct {
|
type GetAllLeaguesParams struct {
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
SportID pgtype.Int4 `json:"sport_id"`
|
SportID pgtype.Int4 `json:"sport_id"`
|
||||||
Query pgtype.Text `json:"query"`
|
Query pgtype.Text `json:"query"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
Offset pgtype.Int4 `json:"offset"`
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
Limit pgtype.Int4 `json:"limit"`
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +70,7 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
||||||
arg.CountryCode,
|
arg.CountryCode,
|
||||||
arg.SportID,
|
arg.SportID,
|
||||||
arg.Query,
|
arg.Query,
|
||||||
|
arg.IsActive,
|
||||||
arg.Offset,
|
arg.Offset,
|
||||||
arg.Limit,
|
arg.Limit,
|
||||||
)
|
)
|
||||||
|
|
@ -199,6 +205,46 @@ func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeagu
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GetTotalLeagues = `-- name: GetTotalLeagues :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM leagues
|
||||||
|
WHERE (
|
||||||
|
country_code = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
sport_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
name ILIKE '%' || $3 || '%'
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
default_is_active = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTotalLeaguesParams struct {
|
||||||
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
|
SportID pgtype.Int4 `json:"sport_id"`
|
||||||
|
Query pgtype.Text `json:"query"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetTotalLeagues(ctx context.Context, arg GetTotalLeaguesParams) (int64, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetTotalLeagues,
|
||||||
|
arg.CountryCode,
|
||||||
|
arg.SportID,
|
||||||
|
arg.Query,
|
||||||
|
arg.IsActive,
|
||||||
|
)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
const GetTotalLeaguesWithSettings = `-- name: GetTotalLeaguesWithSettings :one
|
const GetTotalLeaguesWithSettings = `-- name: GetTotalLeaguesWithSettings :one
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM leagues l
|
FROM leagues l
|
||||||
|
|
@ -292,7 +338,7 @@ func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const InsertLeagueSettings = `-- name: InsertLeagueSettings :exec
|
const SaveLeagueSettings = `-- name: SaveLeagueSettings :exec
|
||||||
INSERT INTO company_league_settings (
|
INSERT INTO company_league_settings (
|
||||||
company_id,
|
company_id,
|
||||||
league_id,
|
league_id,
|
||||||
|
|
@ -305,15 +351,15 @@ SET is_active = EXCLUDED.is_active,
|
||||||
is_featured = EXCLUDED.is_featured
|
is_featured = EXCLUDED.is_featured
|
||||||
`
|
`
|
||||||
|
|
||||||
type InsertLeagueSettingsParams struct {
|
type SaveLeagueSettingsParams struct {
|
||||||
CompanyID int64 `json:"company_id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
LeagueID int64 `json:"league_id"`
|
LeagueID int64 `json:"league_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) InsertLeagueSettings(ctx context.Context, arg InsertLeagueSettingsParams) error {
|
func (q *Queries) SaveLeagueSettings(ctx context.Context, arg SaveLeagueSettingsParams) error {
|
||||||
_, err := q.db.Exec(ctx, InsertLeagueSettings,
|
_, err := q.db.Exec(ctx, SaveLeagueSettings,
|
||||||
arg.CompanyID,
|
arg.CompanyID,
|
||||||
arg.LeagueID,
|
arg.LeagueID,
|
||||||
arg.IsActive,
|
arg.IsActive,
|
||||||
|
|
@ -322,6 +368,52 @@ func (q *Queries) InsertLeagueSettings(ctx context.Context, arg InsertLeagueSett
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UpdateCompanyLeagueSettings = `-- name: UpdateCompanyLeagueSettings :exec
|
||||||
|
UPDATE company_league_settings
|
||||||
|
SET is_active = COALESCE($3, is_active),
|
||||||
|
is_featured = COALESCE(
|
||||||
|
$4,
|
||||||
|
is_featured
|
||||||
|
)
|
||||||
|
WHERE league_id = $1
|
||||||
|
AND company_id = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateCompanyLeagueSettingsParams struct {
|
||||||
|
LeagueID int64 `json:"league_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateCompanyLeagueSettings(ctx context.Context, arg UpdateCompanyLeagueSettingsParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateCompanyLeagueSettings,
|
||||||
|
arg.LeagueID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.IsActive,
|
||||||
|
arg.IsFeatured,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateGlobalLeagueSettings = `-- name: UpdateGlobalLeagueSettings :exec
|
||||||
|
UPDATE leagues
|
||||||
|
SET default_is_active = COALESCE($2, default_is_active),
|
||||||
|
default_is_featured = COALESCE($3, default_is_featured)
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateGlobalLeagueSettingsParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateGlobalLeagueSettings(ctx context.Context, arg UpdateGlobalLeagueSettingsParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateGlobalLeagueSettings, arg.ID, arg.IsActive, arg.IsFeatured)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const UpdateLeague = `-- name: UpdateLeague :exec
|
const UpdateLeague = `-- name: UpdateLeague :exec
|
||||||
UPDATE leagues
|
UPDATE leagues
|
||||||
SET name = COALESCE($2, name),
|
SET name = COALESCE($2, name),
|
||||||
|
|
@ -349,31 +441,3 @@ func (q *Queries) UpdateLeague(ctx context.Context, arg UpdateLeagueParams) erro
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const UpdateLeagueSettings = `-- name: UpdateLeagueSettings :exec
|
|
||||||
UPDATE company_league_settings
|
|
||||||
SET is_active = COALESCE($3, is_active),
|
|
||||||
is_featured = COALESCE(
|
|
||||||
$4,
|
|
||||||
is_featured
|
|
||||||
)
|
|
||||||
WHERE league_id = $1
|
|
||||||
AND company_id = $2
|
|
||||||
`
|
|
||||||
|
|
||||||
type UpdateLeagueSettingsParams struct {
|
|
||||||
LeagueID int64 `json:"league_id"`
|
|
||||||
CompanyID int64 `json:"company_id"`
|
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) UpdateLeagueSettings(ctx context.Context, arg UpdateLeagueSettingsParams) error {
|
|
||||||
_, err := q.db.Exec(ctx, UpdateLeagueSettings,
|
|
||||||
arg.LeagueID,
|
|
||||||
arg.CompanyID,
|
|
||||||
arg.IsActive,
|
|
||||||
arg.IsFeatured,
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
|
||||||
107
gen/db/models.go
107
gen/db/models.go
|
|
@ -82,6 +82,7 @@ type BetWithOutcome struct {
|
||||||
FullName interface{} `json:"full_name"`
|
FullName interface{} `json:"full_name"`
|
||||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||||
Outcomes []BetOutcome `json:"outcomes"`
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
|
CompanySlug string `json:"company_slug"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Branch struct {
|
type Branch struct {
|
||||||
|
|
@ -177,7 +178,7 @@ type CompanyEventSetting struct {
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
WinningUpperLimit pgtype.Int4 `json:"winning_upper_limit"`
|
WinningUpperLimit pgtype.Int8 `json:"winning_upper_limit"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,6 +469,7 @@ type Event struct {
|
||||||
IsLive bool `json:"is_live"`
|
IsLive bool `json:"is_live"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
|
@ -504,12 +506,14 @@ type EventWithCountry struct {
|
||||||
IsLive bool `json:"is_live"`
|
IsLive bool `json:"is_live"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||||
IsMonitored bool `json:"is_monitored"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
LeagueCc pgtype.Text `json:"league_cc"`
|
LeagueCc pgtype.Text `json:"league_cc"`
|
||||||
|
TotalOutcomes int64 `json:"total_outcomes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventWithSetting struct {
|
type EventWithSetting struct {
|
||||||
|
|
@ -534,6 +538,7 @@ type EventWithSetting struct {
|
||||||
IsLive bool `json:"is_live"`
|
IsLive bool `json:"is_live"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
|
@ -542,9 +547,10 @@ type EventWithSetting struct {
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
WinningUpperLimit int64 `json:"winning_upper_limit"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
CompanyUpdatedAt pgtype.Timestamp `json:"company_updated_at"`
|
||||||
LeagueCc pgtype.Text `json:"league_cc"`
|
LeagueCc pgtype.Text `json:"league_cc"`
|
||||||
|
TotalOutcomes int64 `json:"total_outcomes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExchangeRate struct {
|
type ExchangeRate struct {
|
||||||
|
|
@ -619,6 +625,8 @@ type Notification struct {
|
||||||
Priority pgtype.Int4 `json:"priority"`
|
Priority pgtype.Int4 `json:"priority"`
|
||||||
Version int32 `json:"version"`
|
Version int32 `json:"version"`
|
||||||
Timestamp pgtype.Timestamptz `json:"timestamp"`
|
Timestamp pgtype.Timestamptz `json:"timestamp"`
|
||||||
|
Img pgtype.Text `json:"img"`
|
||||||
|
Expires pgtype.Timestamptz `json:"expires"`
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,49 +641,52 @@ type OddHistory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type OddsMarket struct {
|
type OddsMarket struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OddsMarketWithEvent struct {
|
type OddsMarketWithEvent struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
IsMonitored bool `json:"is_monitored"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsLive bool `json:"is_live"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
Status string `json:"status"`
|
IsLive bool `json:"is_live"`
|
||||||
Source string `json:"source"`
|
Status string `json:"status"`
|
||||||
|
Source string `json:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OddsMarketWithSetting struct {
|
type OddsMarketWithSetting struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsActive bool `json:"is_active"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
IsActive bool `json:"is_active"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Otp struct {
|
type Otp struct {
|
||||||
|
|
@ -691,13 +702,14 @@ type Otp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Raffle struct {
|
type Raffle struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
CompanyID int32 `json:"company_id"`
|
CompanyID int32 `json:"company_id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
Type string `json:"type"`
|
TicketLimit int32 `json:"ticket_limit"`
|
||||||
Status string `json:"status"`
|
Type string `json:"type"`
|
||||||
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RaffleGameFilter struct {
|
type RaffleGameFilter struct {
|
||||||
|
|
@ -824,6 +836,7 @@ type ShopBetDetail struct {
|
||||||
TransactionVerified bool `json:"transaction_verified"`
|
TransactionVerified bool `json:"transaction_verified"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
|
FastCode string `json:"fast_code"`
|
||||||
Outcomes []BetOutcome `json:"outcomes"`
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ INSERT INTO notifications (
|
||||||
payload,
|
payload,
|
||||||
priority,
|
priority,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
expires,
|
||||||
|
img,
|
||||||
metadata
|
metadata
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
|
|
@ -54,9 +56,11 @@ VALUES (
|
||||||
$10,
|
$10,
|
||||||
$11,
|
$11,
|
||||||
$12,
|
$12,
|
||||||
$13
|
$13,
|
||||||
|
$14,
|
||||||
|
$15
|
||||||
)
|
)
|
||||||
RETURNING id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
RETURNING id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateNotificationParams struct {
|
type CreateNotificationParams struct {
|
||||||
|
|
@ -72,6 +76,8 @@ type CreateNotificationParams struct {
|
||||||
Payload []byte `json:"payload"`
|
Payload []byte `json:"payload"`
|
||||||
Priority pgtype.Int4 `json:"priority"`
|
Priority pgtype.Int4 `json:"priority"`
|
||||||
Timestamp pgtype.Timestamptz `json:"timestamp"`
|
Timestamp pgtype.Timestamptz `json:"timestamp"`
|
||||||
|
Expires pgtype.Timestamptz `json:"expires"`
|
||||||
|
Img pgtype.Text `json:"img"`
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,6 +95,8 @@ func (q *Queries) CreateNotification(ctx context.Context, arg CreateNotification
|
||||||
arg.Payload,
|
arg.Payload,
|
||||||
arg.Priority,
|
arg.Priority,
|
||||||
arg.Timestamp,
|
arg.Timestamp,
|
||||||
|
arg.Expires,
|
||||||
|
arg.Img,
|
||||||
arg.Metadata,
|
arg.Metadata,
|
||||||
)
|
)
|
||||||
var i Notification
|
var i Notification
|
||||||
|
|
@ -106,13 +114,25 @@ func (q *Queries) CreateNotification(ctx context.Context, arg CreateNotification
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DeleteOldNotifications = `-- name: DeleteOldNotifications :exec
|
||||||
|
DELETE FROM notifications
|
||||||
|
WHERE expires < now()
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteOldNotifications(ctx context.Context) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteOldNotifications)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const GetAllNotifications = `-- name: GetAllNotifications :many
|
const GetAllNotifications = `-- name: GetAllNotifications :many
|
||||||
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
FROM notifications
|
FROM notifications
|
||||||
ORDER BY timestamp DESC
|
ORDER BY timestamp DESC
|
||||||
LIMIT $1 OFFSET $2
|
LIMIT $1 OFFSET $2
|
||||||
|
|
@ -146,6 +166,8 @@ func (q *Queries) GetAllNotifications(ctx context.Context, arg GetAllNotificatio
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -159,7 +181,7 @@ func (q *Queries) GetAllNotifications(ctx context.Context, arg GetAllNotificatio
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetNotification = `-- name: GetNotification :one
|
const GetNotification = `-- name: GetNotification :one
|
||||||
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
FROM notifications
|
FROM notifications
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -182,6 +204,8 @@ func (q *Queries) GetNotification(ctx context.Context, id string) (Notification,
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
|
|
@ -254,7 +278,7 @@ func (q *Queries) GetUserNotificationCount(ctx context.Context, recipientID int6
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetUserNotifications = `-- name: GetUserNotifications :many
|
const GetUserNotifications = `-- name: GetUserNotifications :many
|
||||||
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
FROM notifications
|
FROM notifications
|
||||||
WHERE recipient_id = $1
|
WHERE recipient_id = $1
|
||||||
ORDER BY timestamp DESC
|
ORDER BY timestamp DESC
|
||||||
|
|
@ -290,6 +314,8 @@ func (q *Queries) GetUserNotifications(ctx context.Context, arg GetUserNotificat
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -303,7 +329,7 @@ func (q *Queries) GetUserNotifications(ctx context.Context, arg GetUserNotificat
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListFailedNotifications = `-- name: ListFailedNotifications :many
|
const ListFailedNotifications = `-- name: ListFailedNotifications :many
|
||||||
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
SELECT id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
FROM notifications
|
FROM notifications
|
||||||
WHERE delivery_status = 'failed'
|
WHERE delivery_status = 'failed'
|
||||||
AND timestamp < NOW() - INTERVAL '1 hour'
|
AND timestamp < NOW() - INTERVAL '1 hour'
|
||||||
|
|
@ -334,6 +360,8 @@ func (q *Queries) ListFailedNotifications(ctx context.Context, limit int32) ([]N
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -378,7 +406,7 @@ SET delivery_status = $2,
|
||||||
is_read = $3,
|
is_read = $3,
|
||||||
metadata = $4
|
metadata = $4
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, metadata
|
RETURNING id, recipient_id, type, level, error_severity, reciever, is_read, delivery_status, delivery_channel, payload, priority, version, timestamp, img, expires, metadata
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateNotificationStatusParams struct {
|
type UpdateNotificationStatusParams struct {
|
||||||
|
|
@ -410,6 +438,8 @@ func (q *Queries) UpdateNotificationStatus(ctx context.Context, arg UpdateNotifi
|
||||||
&i.Priority,
|
&i.Priority,
|
||||||
&i.Version,
|
&i.Version,
|
||||||
&i.Timestamp,
|
&i.Timestamp,
|
||||||
|
&i.Img,
|
||||||
|
&i.Expires,
|
||||||
&i.Metadata,
|
&i.Metadata,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,32 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DeleteAllCompanyOddsSetting = `-- name: DeleteAllCompanyOddsSetting :exec
|
||||||
|
DELETE FROM company_odd_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteAllCompanyOddsSetting, companyID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteCompanyOddsSettingByOddMarketID = `-- name: DeleteCompanyOddsSettingByOddMarketID :exec
|
||||||
|
DELETE FROM company_odd_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
AND odds_market_id = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type DeleteCompanyOddsSettingByOddMarketIDParams struct {
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, arg DeleteCompanyOddsSettingByOddMarketIDParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteCompanyOddsSettingByOddMarketID, arg.CompanyID, arg.OddsMarketID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const DeleteOddsForEvent = `-- name: DeleteOddsForEvent :exec
|
const DeleteOddsForEvent = `-- name: DeleteOddsForEvent :exec
|
||||||
DELETE FROM odds_market
|
DELETE FROM odds_market
|
||||||
Where event_id = $1
|
Where event_id = $1
|
||||||
|
|
@ -22,7 +48,7 @@ func (q *Queries) DeleteOddsForEvent(ctx context.Context, eventID int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllOdds = `-- name: GetAllOdds :many
|
const GetAllOdds = `-- name: GetAllOdds :many
|
||||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, number_of_outcomes, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||||
FROM odds_market_with_event
|
FROM odds_market_with_event
|
||||||
LIMIT $2 OFFSET $1
|
LIMIT $2 OFFSET $1
|
||||||
`
|
`
|
||||||
|
|
@ -49,6 +75,7 @@ func (q *Queries) GetAllOdds(ctx context.Context, arg GetAllOddsParams) ([]OddsM
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -74,6 +101,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -94,19 +122,20 @@ type GetAllOddsWithSettingsParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetAllOddsWithSettingsRow struct {
|
type GetAllOddsWithSettingsRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsActive bool `json:"is_active"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
IsActive bool `json:"is_active"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]GetAllOddsWithSettingsRow, error) {
|
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]GetAllOddsWithSettingsRow, error) {
|
||||||
|
|
@ -125,6 +154,7 @@ func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWith
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -144,7 +174,7 @@ func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWith
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetOddByID = `-- name: GetOddByID :one
|
const GetOddByID = `-- name: GetOddByID :one
|
||||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, number_of_outcomes, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||||
FROM odds_market_with_event
|
FROM odds_market_with_event
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -160,6 +190,7 @@ func (q *Queries) GetOddByID(ctx context.Context, id int64) (OddsMarketWithEvent
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -172,7 +203,7 @@ func (q *Queries) GetOddByID(ctx context.Context, id int64) (OddsMarketWithEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetOddsByEventID = `-- name: GetOddsByEventID :many
|
const GetOddsByEventID = `-- name: GetOddsByEventID :many
|
||||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, number_of_outcomes, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||||
FROM odds_market_with_event
|
FROM odds_market_with_event
|
||||||
WHERE event_id = $1
|
WHERE event_id = $1
|
||||||
AND (
|
AND (
|
||||||
|
|
@ -223,6 +254,7 @@ func (q *Queries) GetOddsByEventID(ctx context.Context, arg GetOddsByEventIDPara
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -242,7 +274,7 @@ func (q *Queries) GetOddsByEventID(ctx context.Context, arg GetOddsByEventIDPara
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetOddsByMarketID = `-- name: GetOddsByMarketID :one
|
const GetOddsByMarketID = `-- name: GetOddsByMarketID :one
|
||||||
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
SELECT id, event_id, market_type, market_name, market_category, market_id, raw_odds, number_of_outcomes, default_is_active, fetched_at, expires_at, is_monitored, is_live, status, source
|
||||||
FROM odds_market_with_event
|
FROM odds_market_with_event
|
||||||
WHERE market_id = $1
|
WHERE market_id = $1
|
||||||
AND event_id = $2
|
AND event_id = $2
|
||||||
|
|
@ -264,6 +296,7 @@ func (q *Queries) GetOddsByMarketID(ctx context.Context, arg GetOddsByMarketIDPa
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -282,6 +315,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -304,19 +338,20 @@ type GetOddsWithSettingsByEventIDParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetOddsWithSettingsByEventIDRow struct {
|
type GetOddsWithSettingsByEventIDRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsActive bool `json:"is_active"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
IsActive bool `json:"is_active"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]GetOddsWithSettingsByEventIDRow, error) {
|
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]GetOddsWithSettingsByEventIDRow, error) {
|
||||||
|
|
@ -340,6 +375,7 @@ func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsW
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -365,6 +401,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -384,19 +421,20 @@ type GetOddsWithSettingsByIDParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetOddsWithSettingsByIDRow struct {
|
type GetOddsWithSettingsByIDRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsActive bool `json:"is_active"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
IsActive bool `json:"is_active"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSettingsByIDParams) (GetOddsWithSettingsByIDRow, error) {
|
func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSettingsByIDParams) (GetOddsWithSettingsByIDRow, error) {
|
||||||
|
|
@ -409,6 +447,7 @@ func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSe
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -427,6 +466,7 @@ SELECT o.id,
|
||||||
o.market_name,
|
o.market_name,
|
||||||
o.market_category,
|
o.market_category,
|
||||||
o.market_id,
|
o.market_id,
|
||||||
|
o.number_of_outcomes,
|
||||||
o.default_is_active,
|
o.default_is_active,
|
||||||
o.fetched_at,
|
o.fetched_at,
|
||||||
o.expires_at,
|
o.expires_at,
|
||||||
|
|
@ -448,19 +488,20 @@ type GetOddsWithSettingsByMarketIDParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetOddsWithSettingsByMarketIDRow struct {
|
type GetOddsWithSettingsByMarketIDRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
IsActive bool `json:"is_active"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
IsActive bool `json:"is_active"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (GetOddsWithSettingsByMarketIDRow, error) {
|
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (GetOddsWithSettingsByMarketIDRow, error) {
|
||||||
|
|
@ -473,6 +514,7 @@ func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOdds
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
&i.DefaultIsActive,
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
|
@ -491,6 +533,7 @@ INSERT INTO odds_market (
|
||||||
market_name,
|
market_name,
|
||||||
market_category,
|
market_category,
|
||||||
market_id,
|
market_id,
|
||||||
|
number_of_outcomes,
|
||||||
raw_odds,
|
raw_odds,
|
||||||
fetched_at,
|
fetched_at,
|
||||||
expires_at
|
expires_at
|
||||||
|
|
@ -503,26 +546,29 @@ VALUES (
|
||||||
$5,
|
$5,
|
||||||
$6,
|
$6,
|
||||||
$7,
|
$7,
|
||||||
$8
|
$8,
|
||||||
|
$9
|
||||||
) ON CONFLICT (event_id, market_id) DO
|
) ON CONFLICT (event_id, market_id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET market_type = EXCLUDED.market_type,
|
SET market_type = EXCLUDED.market_type,
|
||||||
market_name = EXCLUDED.market_name,
|
market_name = EXCLUDED.market_name,
|
||||||
market_category = EXCLUDED.market_category,
|
market_category = EXCLUDED.market_category,
|
||||||
raw_odds = EXCLUDED.raw_odds,
|
raw_odds = EXCLUDED.raw_odds,
|
||||||
|
number_of_outcomes = EXCLUDED.number_of_outcomes,
|
||||||
fetched_at = EXCLUDED.fetched_at,
|
fetched_at = EXCLUDED.fetched_at,
|
||||||
expires_at = EXCLUDED.expires_at
|
expires_at = EXCLUDED.expires_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type InsertOddsMarketParams struct {
|
type InsertOddsMarketParams struct {
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) InsertOddsMarket(ctx context.Context, arg InsertOddsMarketParams) error {
|
func (q *Queries) InsertOddsMarket(ctx context.Context, arg InsertOddsMarketParams) error {
|
||||||
|
|
@ -532,6 +578,7 @@ func (q *Queries) InsertOddsMarket(ctx context.Context, arg InsertOddsMarketPara
|
||||||
arg.MarketName,
|
arg.MarketName,
|
||||||
arg.MarketCategory,
|
arg.MarketCategory,
|
||||||
arg.MarketID,
|
arg.MarketID,
|
||||||
|
arg.NumberOfOutcomes,
|
||||||
arg.RawOdds,
|
arg.RawOdds,
|
||||||
arg.FetchedAt,
|
arg.FetchedAt,
|
||||||
arg.ExpiresAt,
|
arg.ExpiresAt,
|
||||||
|
|
@ -568,3 +615,19 @@ func (q *Queries) SaveOddSettings(ctx context.Context, arg SaveOddSettingsParams
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UpdateGlobalOddsSetting = `-- name: UpdateGlobalOddsSetting :exec
|
||||||
|
UPDATE odds_market
|
||||||
|
SET default_is_active = COALESCE($2, default_is_active)
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateGlobalOddsSettingParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
DefaultIsActive pgtype.Bool `json:"default_is_active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateGlobalOddsSetting(ctx context.Context, arg UpdateGlobalOddsSettingParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateGlobalOddsSetting, arg.ID, arg.DefaultIsActive)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,19 @@ func (q *Queries) AddSportRaffleFilter(ctx context.Context, arg AddSportRaffleFi
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CheckSportRaffleHasFilter = `-- name: CheckSportRaffleHasFilter :one
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM raffle_sport_filters WHERE raffle_id = $1
|
||||||
|
) AS has_filter
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CheckSportRaffleHasFilter, raffleID)
|
||||||
|
var has_filter bool
|
||||||
|
err := row.Scan(&has_filter)
|
||||||
|
return has_filter, err
|
||||||
|
}
|
||||||
|
|
||||||
const CheckValidSportRaffleFilter = `-- name: CheckValidSportRaffleFilter :one
|
const CheckValidSportRaffleFilter = `-- name: CheckValidSportRaffleFilter :one
|
||||||
SELECT COUNT(*) > 0 AS exists
|
SELECT COUNT(*) > 0 AS exists
|
||||||
FROM raffle_sport_filters
|
FROM raffle_sport_filters
|
||||||
|
|
@ -57,16 +70,17 @@ func (q *Queries) CheckValidSportRaffleFilter(ctx context.Context, arg CheckVali
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateRaffle = `-- name: CreateRaffle :one
|
const CreateRaffle = `-- name: CreateRaffle :one
|
||||||
INSERT INTO raffles (company_id, name, expires_at, type)
|
INSERT INTO raffles (company_id, name, expires_at, ticket_limit, type)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING id, company_id, name, created_at, expires_at, type, status
|
RETURNING id, company_id, name, created_at, expires_at, ticket_limit, type, status
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateRaffleParams struct {
|
type CreateRaffleParams struct {
|
||||||
CompanyID int32 `json:"company_id"`
|
CompanyID int32 `json:"company_id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
Type string `json:"type"`
|
TicketLimit int32 `json:"ticket_limit"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raffle, error) {
|
func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raffle, error) {
|
||||||
|
|
@ -74,6 +88,7 @@ func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raf
|
||||||
arg.CompanyID,
|
arg.CompanyID,
|
||||||
arg.Name,
|
arg.Name,
|
||||||
arg.ExpiresAt,
|
arg.ExpiresAt,
|
||||||
|
arg.TicketLimit,
|
||||||
arg.Type,
|
arg.Type,
|
||||||
)
|
)
|
||||||
var i Raffle
|
var i Raffle
|
||||||
|
|
@ -83,6 +98,7 @@ func (q *Queries) CreateRaffle(ctx context.Context, arg CreateRaffleParams) (Raf
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
&i.TicketLimit,
|
||||||
&i.Type,
|
&i.Type,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
)
|
)
|
||||||
|
|
@ -140,7 +156,7 @@ func (q *Queries) CreateRaffleWinner(ctx context.Context, arg CreateRaffleWinner
|
||||||
const DeleteRaffle = `-- name: DeleteRaffle :one
|
const DeleteRaffle = `-- name: DeleteRaffle :one
|
||||||
DELETE FROM raffles
|
DELETE FROM raffles
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, company_id, name, created_at, expires_at, type, status
|
RETURNING id, company_id, name, created_at, expires_at, ticket_limit, type, status
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) {
|
func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) {
|
||||||
|
|
@ -152,6 +168,7 @@ func (q *Queries) DeleteRaffle(ctx context.Context, id int32) (Raffle, error) {
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
&i.TicketLimit,
|
||||||
&i.Type,
|
&i.Type,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
)
|
)
|
||||||
|
|
@ -219,8 +236,40 @@ func (q *Queries) GetRaffleStanding(ctx context.Context, arg GetRaffleStandingPa
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GetRaffleTicketCount = `-- name: GetRaffleTicketCount :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM raffle_tickets
|
||||||
|
WHERE raffle_id = $1
|
||||||
|
AND user_id = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetRaffleTicketCountParams struct {
|
||||||
|
RaffleID int32 `json:"raffle_id"`
|
||||||
|
UserID int32 `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetRaffleTicketCount(ctx context.Context, arg GetRaffleTicketCountParams) (int64, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetRaffleTicketCount, arg.RaffleID, arg.UserID)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetRaffleTicketLimit = `-- name: GetRaffleTicketLimit :one
|
||||||
|
SELECT ticket_limit
|
||||||
|
FROM raffles
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetRaffleTicketLimit(ctx context.Context, id int32) (int32, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetRaffleTicketLimit, id)
|
||||||
|
var ticket_limit int32
|
||||||
|
err := row.Scan(&ticket_limit)
|
||||||
|
return ticket_limit, err
|
||||||
|
}
|
||||||
|
|
||||||
const GetRafflesOfCompany = `-- name: GetRafflesOfCompany :many
|
const GetRafflesOfCompany = `-- name: GetRafflesOfCompany :many
|
||||||
SELECT id, company_id, name, created_at, expires_at, type, status FROM raffles WHERE company_id = $1
|
SELECT id, company_id, name, created_at, expires_at, ticket_limit, type, status FROM raffles WHERE company_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]Raffle, error) {
|
func (q *Queries) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]Raffle, error) {
|
||||||
|
|
@ -238,6 +287,7 @@ func (q *Queries) GetRafflesOfCompany(ctx context.Context, companyID int32) ([]R
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
|
&i.TicketLimit,
|
||||||
&i.Type,
|
&i.Type,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ func (q *Queries) CreateShopTransaction(ctx context.Context, arg CreateShopTrans
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllShopBets = `-- name: GetAllShopBets :many
|
const GetAllShopBets = `-- name: GetAllShopBets :many
|
||||||
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes
|
||||||
FROM shop_bet_detail
|
FROM shop_bet_detail
|
||||||
WHERE (
|
WHERE (
|
||||||
full_name ILIKE '%' || $1 || '%'
|
full_name ILIKE '%' || $1 || '%'
|
||||||
|
|
@ -239,6 +239,7 @@ func (q *Queries) GetAllShopBets(ctx context.Context, arg GetAllShopBetsParams)
|
||||||
&i.TransactionVerified,
|
&i.TransactionVerified,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
|
&i.FastCode,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -419,7 +420,7 @@ func (q *Queries) GetAllShopTransactions(ctx context.Context, arg GetAllShopTran
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetShopBetByBetID = `-- name: GetShopBetByBetID :one
|
const GetShopBetByBetID = `-- name: GetShopBetByBetID :one
|
||||||
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes
|
||||||
FROM shop_bet_detail
|
FROM shop_bet_detail
|
||||||
WHERE bet_id = $1
|
WHERE bet_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -445,13 +446,14 @@ func (q *Queries) GetShopBetByBetID(ctx context.Context, betID int64) (ShopBetDe
|
||||||
&i.TransactionVerified,
|
&i.TransactionVerified,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
|
&i.FastCode,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetShopBetByCashoutID = `-- name: GetShopBetByCashoutID :one
|
const GetShopBetByCashoutID = `-- name: GetShopBetByCashoutID :one
|
||||||
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes
|
||||||
FROM shop_bet_detail
|
FROM shop_bet_detail
|
||||||
WHERE cashout_id = $1
|
WHERE cashout_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -477,13 +479,14 @@ func (q *Queries) GetShopBetByCashoutID(ctx context.Context, cashoutID string) (
|
||||||
&i.TransactionVerified,
|
&i.TransactionVerified,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
|
&i.FastCode,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetShopBetByID = `-- name: GetShopBetByID :one
|
const GetShopBetByID = `-- name: GetShopBetByID :one
|
||||||
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes
|
||||||
FROM shop_bet_detail
|
FROM shop_bet_detail
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -509,13 +512,14 @@ func (q *Queries) GetShopBetByID(ctx context.Context, id int64) (ShopBetDetail,
|
||||||
&i.TransactionVerified,
|
&i.TransactionVerified,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
|
&i.FastCode,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetShopBetByShopTransactionID = `-- name: GetShopBetByShopTransactionID :one
|
const GetShopBetByShopTransactionID = `-- name: GetShopBetByShopTransactionID :one
|
||||||
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes
|
||||||
FROM shop_bet_detail
|
FROM shop_bet_detail
|
||||||
WHERE shop_transaction_id = $1
|
WHERE shop_transaction_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -541,6 +545,7 @@ func (q *Queries) GetShopBetByShopTransactionID(ctx context.Context, shopTransac
|
||||||
&i.TransactionVerified,
|
&i.TransactionVerified,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
|
&i.FastCode,
|
||||||
&i.Outcomes,
|
&i.Outcomes,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
|
|
|
||||||
8
go.mod
8
go.mod
|
|
@ -81,19 +81,11 @@ require (
|
||||||
require github.com/twilio/twilio-go v1.26.3
|
require github.com/twilio/twilio-go v1.26.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/redis/go-redis/v9 v9.10.0 // direct
|
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
|
||||||
github.com/segmentio/kafka-go v0.4.48 // direct
|
|
||||||
)
|
|
||||||
|
|
||||||
// require github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f
|
// require github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f
|
||||||
|
|
||||||
// require github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f // direct
|
// require github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f // direct
|
||||||
|
|
|
||||||
33
go.sum
33
go.sum
|
|
@ -1,5 +1,3 @@
|
||||||
github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f h1:UOp9At84RG8OT2Nw2TQidYWaoW1rAfTqChOJLdhYcm8=
|
|
||||||
github.com/AnaniyaBelew/ArifpayGoPlugin v0.0.0-20231127130208-54b9bc51118f/go.mod h1:N2NQ6ad3i+oLQU+MlPci2f7mx6Mtg+wUcvzCv77KCl8=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
|
@ -12,17 +10,11 @@ github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
|
||||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
|
||||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
|
||||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
|
||||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
|
@ -31,8 +23,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
|
@ -91,7 +81,6 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||||
|
|
@ -129,15 +118,11 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ
|
||||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=
|
|
||||||
github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
|
||||||
github.com/resend/resend-go/v2 v2.20.0 h1:MrIrgV0aHhwRgmcRPw33Nexn6aGJvCvG2XwfFpAMBGM=
|
github.com/resend/resend-go/v2 v2.20.0 h1:MrIrgV0aHhwRgmcRPw33Nexn6aGJvCvG2XwfFpAMBGM=
|
||||||
github.com/resend/resend-go/v2 v2.20.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ=
|
github.com/resend/resend-go/v2 v2.20.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
|
@ -150,8 +135,6 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/segmentio/kafka-go v0.4.48 h1:9jyu9CWK4W5W+SroCe8EffbrRZVqAOkuaLd/ApID4Vs=
|
|
||||||
github.com/segmentio/kafka-go v0.4.48/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
|
@ -215,12 +198,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
|
||||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
|
@ -233,15 +214,11 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
|
||||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
@ -257,25 +234,16 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|
||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|
||||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
@ -284,7 +252,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|
||||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ type GetBet struct {
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
UserID int64
|
UserID int64
|
||||||
CompanyID int64
|
CompanyID int64
|
||||||
|
CompanySlug string
|
||||||
IsShopBet bool
|
IsShopBet bool
|
||||||
CashedOut bool
|
CashedOut bool
|
||||||
Outcomes []BetOutcome
|
Outcomes []BetOutcome
|
||||||
|
|
@ -149,18 +150,49 @@ type CreateBetRes struct {
|
||||||
FastCode string `json:"fast_code"`
|
FastCode string `json:"fast_code"`
|
||||||
}
|
}
|
||||||
type BetRes struct {
|
type BetRes struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
Outcomes []BetOutcome `json:"outcomes"`
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
Amount float32 `json:"amount" example:"100.0"`
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
Status OutcomeStatus `json:"status" example:"1"`
|
Status OutcomeStatus `json:"status" example:"1"`
|
||||||
Fullname string `json:"full_name" example:"John Smith"`
|
Fullname string `json:"full_name" example:"John Smith"`
|
||||||
UserID int64 `json:"user_id" example:"2"`
|
UserID int64 `json:"user_id" example:"2"`
|
||||||
CompanyID int64 `json:"company_id" example:"1"`
|
CompanyID int64 `json:"company_id" example:"1"`
|
||||||
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
CompanySlug string `json:"company_slug" example:"fortune"`
|
||||||
CashedOut bool `json:"cashed_out" example:"false"`
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||||
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
|
CashedOut bool `json:"cashed_out" example:"false"`
|
||||||
FastCode string `json:"fast_code"`
|
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
|
||||||
|
FastCode string `json:"fast_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BetOutcomeViewRes struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
BetID int64 `json:"bet_id"`
|
||||||
|
CompanyName string `json:"company_name"`
|
||||||
|
SportID int64 `json:"sport_id"`
|
||||||
|
EventID int64 `json:"event_id"`
|
||||||
|
OddID int64 `json:"odd_id"`
|
||||||
|
HomeTeamName string `json:"home_team_name"`
|
||||||
|
AwayTeamName string `json:"away_team_name"`
|
||||||
|
MarketID int64 `json:"market_id"`
|
||||||
|
MarketName string `json:"market_name"`
|
||||||
|
Odd float32 `json:"odd"`
|
||||||
|
OddName string `json:"odd_name"`
|
||||||
|
OddHeader string `json:"odd_header"`
|
||||||
|
OddHandicap string `json:"odd_handicap"`
|
||||||
|
Status OutcomeStatus `json:"status"`
|
||||||
|
Expires time.Time `json:"expires"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
TotalOdds float32 `json:"total_odds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BetOutcomeViewFilter struct {
|
||||||
|
OutcomeStatus ValidOutcomeStatus
|
||||||
|
CompanyID ValidInt64
|
||||||
|
Limit ValidInt32
|
||||||
|
Offset ValidInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateBetRes(bet Bet, createdNumber int64) CreateBetRes {
|
func ConvertCreateBetRes(bet Bet, createdNumber int64) CreateBetRes {
|
||||||
|
|
@ -179,18 +211,19 @@ func ConvertCreateBetRes(bet Bet, createdNumber int64) CreateBetRes {
|
||||||
|
|
||||||
func ConvertBet(bet GetBet) BetRes {
|
func ConvertBet(bet GetBet) BetRes {
|
||||||
return BetRes{
|
return BetRes{
|
||||||
ID: bet.ID,
|
ID: bet.ID,
|
||||||
Amount: bet.Amount.Float32(),
|
Amount: bet.Amount.Float32(),
|
||||||
TotalOdds: bet.TotalOdds,
|
TotalOdds: bet.TotalOdds,
|
||||||
Status: bet.Status,
|
Status: bet.Status,
|
||||||
Fullname: bet.FullName,
|
Fullname: bet.FullName,
|
||||||
UserID: bet.UserID,
|
UserID: bet.UserID,
|
||||||
CompanyID: bet.CompanyID,
|
CompanyID: bet.CompanyID,
|
||||||
Outcomes: bet.Outcomes,
|
CompanySlug: bet.CompanySlug,
|
||||||
IsShopBet: bet.IsShopBet,
|
Outcomes: bet.Outcomes,
|
||||||
CashedOut: bet.CashedOut,
|
IsShopBet: bet.IsShopBet,
|
||||||
CreatedAt: bet.CreatedAt,
|
CashedOut: bet.CashedOut,
|
||||||
FastCode: bet.FastCode,
|
CreatedAt: bet.CreatedAt,
|
||||||
|
FastCode: bet.FastCode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,6 +261,30 @@ func ConvertDBBetOutcomes(outcome dbgen.BetOutcome) BetOutcome {
|
||||||
Expires: outcome.Expires.Time,
|
Expires: outcome.Expires.Time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func ConvertDBBetOutcomesView(outcome dbgen.GetBetOutcomeViewByEventIDRow) BetOutcomeViewRes {
|
||||||
|
return BetOutcomeViewRes{
|
||||||
|
ID: outcome.ID,
|
||||||
|
BetID: outcome.BetID,
|
||||||
|
CompanyName: outcome.CompanyName,
|
||||||
|
SportID: outcome.SportID,
|
||||||
|
EventID: outcome.EventID,
|
||||||
|
OddID: outcome.OddID,
|
||||||
|
HomeTeamName: outcome.HomeTeamName,
|
||||||
|
AwayTeamName: outcome.AwayTeamName,
|
||||||
|
MarketID: outcome.MarketID,
|
||||||
|
MarketName: outcome.MarketName,
|
||||||
|
Odd: outcome.Odd,
|
||||||
|
OddName: outcome.OddName,
|
||||||
|
OddHeader: outcome.OddHeader,
|
||||||
|
OddHandicap: outcome.OddHandicap,
|
||||||
|
Status: OutcomeStatus(outcome.Status),
|
||||||
|
Expires: outcome.Expires.Time,
|
||||||
|
FirstName: outcome.FirstName,
|
||||||
|
LastName: outcome.LastName,
|
||||||
|
Amount: outcome.Amount,
|
||||||
|
TotalOdds: outcome.TotalOdds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
||||||
var outcomes []BetOutcome = make([]BetOutcome, 0, len(bet.Outcomes))
|
var outcomes []BetOutcome = make([]BetOutcome, 0, len(bet.Outcomes))
|
||||||
|
|
@ -239,6 +296,7 @@ func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
||||||
return GetBet{
|
return GetBet{
|
||||||
ID: bet.ID,
|
ID: bet.ID,
|
||||||
CompanyID: bet.CompanyID,
|
CompanyID: bet.CompanyID,
|
||||||
|
CompanySlug: bet.CompanySlug,
|
||||||
Amount: Currency(bet.Amount),
|
Amount: Currency(bet.Amount),
|
||||||
TotalOdds: bet.TotalOdds,
|
TotalOdds: bet.TotalOdds,
|
||||||
Status: OutcomeStatus(bet.Status),
|
Status: OutcomeStatus(bet.Status),
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ type CreateCompany struct {
|
||||||
AdminID int64
|
AdminID int64
|
||||||
WalletID int64
|
WalletID int64
|
||||||
DeductedPercentage float32
|
DeductedPercentage float32
|
||||||
|
Slug string
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateCompany struct {
|
type UpdateCompany struct {
|
||||||
|
|
@ -53,18 +55,22 @@ type UpdateCompany struct {
|
||||||
AdminID ValidInt64
|
AdminID ValidInt64
|
||||||
IsActive ValidBool
|
IsActive ValidBool
|
||||||
DeductedPercentage ValidFloat32
|
DeductedPercentage ValidFloat32
|
||||||
|
Slug ValidString
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateCompanyReq struct {
|
type CreateCompanyReq struct {
|
||||||
Name string `json:"name" example:"CompanyName"`
|
Name string `json:"name" example:"CompanyName"`
|
||||||
AdminID int64 `json:"admin_id" example:"1"`
|
AdminID int64 `json:"admin_id" example:"1"`
|
||||||
DeductedPercentage float32 `json:"deducted_percentage" example:"0.1" validate:"lt=1"`
|
DeductedPercentage float32 `json:"deducted_percentage" example:"0.1" validate:"lt=1"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
}
|
}
|
||||||
type UpdateCompanyReq struct {
|
type UpdateCompanyReq struct {
|
||||||
Name *string `json:"name,omitempty" example:"CompanyName"`
|
Name *string `json:"name,omitempty" example:"CompanyName"`
|
||||||
AdminID *int64 `json:"admin_id,omitempty" example:"1"`
|
AdminID *int64 `json:"admin_id,omitempty" example:"1"`
|
||||||
IsActive *bool `json:"is_active,omitempty" example:"true"`
|
IsActive *bool `json:"is_active,omitempty" example:"true"`
|
||||||
DeductedPercentage *float32 `json:"deducted_percentage,omitempty" example:"0.1" validate:"lt=1"`
|
DeductedPercentage *float32 `json:"deducted_percentage,omitempty" example:"0.1" validate:"lt=1"`
|
||||||
|
Slug *string `json:"slug"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompanyRes struct {
|
type CompanyRes struct {
|
||||||
|
|
@ -113,13 +119,14 @@ func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateCompany(company CreateCompany, uniqueSlug string) dbgen.CreateCompanyParams {
|
func ConvertCreateCompany(company CreateCompany) dbgen.CreateCompanyParams {
|
||||||
return dbgen.CreateCompanyParams{
|
return dbgen.CreateCompanyParams{
|
||||||
Name: company.Name,
|
Name: company.Name,
|
||||||
Slug: uniqueSlug,
|
Slug: company.Slug,
|
||||||
AdminID: company.AdminID,
|
AdminID: company.AdminID,
|
||||||
WalletID: company.WalletID,
|
WalletID: company.WalletID,
|
||||||
DeductedPercentage: company.DeductedPercentage,
|
DeductedPercentage: company.DeductedPercentage,
|
||||||
|
IsActive: company.IsActive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,31 +161,22 @@ func ConvertDBCompanyDetails(dbCompany dbgen.CompaniesDetail) GetCompany {
|
||||||
|
|
||||||
func ConvertUpdateCompany(updateCompany UpdateCompany) dbgen.UpdateCompanyParams {
|
func ConvertUpdateCompany(updateCompany UpdateCompany) dbgen.UpdateCompanyParams {
|
||||||
newUpdateCompany := dbgen.UpdateCompanyParams{
|
newUpdateCompany := dbgen.UpdateCompanyParams{
|
||||||
ID: updateCompany.ID,
|
ID: updateCompany.ID,
|
||||||
Name: pgtype.Text{
|
Name: updateCompany.Name.ToPG(),
|
||||||
String: updateCompany.Name.Value,
|
AdminID: updateCompany.AdminID.ToPG(),
|
||||||
Valid: updateCompany.Name.Valid,
|
IsActive: updateCompany.IsActive.ToPG(),
|
||||||
},
|
DeductedPercentage: updateCompany.DeductedPercentage.ToPG(),
|
||||||
AdminID: pgtype.Int8{
|
Slug: updateCompany.Slug.ToPG(),
|
||||||
Int64: updateCompany.AdminID.Value,
|
|
||||||
Valid: updateCompany.AdminID.Valid,
|
|
||||||
},
|
|
||||||
IsActive: pgtype.Bool{
|
|
||||||
Bool: updateCompany.IsActive.Value,
|
|
||||||
Valid: updateCompany.IsActive.Valid,
|
|
||||||
},
|
|
||||||
DeductedPercentage: pgtype.Float4{
|
|
||||||
Float32: updateCompany.DeductedPercentage.Value,
|
|
||||||
Valid: updateCompany.DeductedPercentage.Valid,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newUpdateCompany
|
return newUpdateCompany
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertUpdateCompanyReq(req UpdateCompanyReq) UpdateCompany {
|
func ConvertUpdateCompanyReq(req UpdateCompanyReq, companyID int64) UpdateCompany {
|
||||||
var updateCompany UpdateCompany
|
var updateCompany UpdateCompany
|
||||||
|
|
||||||
|
updateCompany.ID = companyID
|
||||||
|
|
||||||
if req.Name != nil {
|
if req.Name != nil {
|
||||||
updateCompany.Name = ValidString{
|
updateCompany.Name = ValidString{
|
||||||
Value: *req.Name,
|
Value: *req.Name,
|
||||||
|
|
@ -206,6 +204,12 @@ func ConvertUpdateCompanyReq(req UpdateCompanyReq) UpdateCompany {
|
||||||
Valid: true,
|
Valid: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if req.Slug != nil {
|
||||||
|
updateCompany.Slug = ValidString{
|
||||||
|
Value: *req.Slug,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return updateCompany
|
return updateCompany
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,49 +25,83 @@ func (m Currency) String() string {
|
||||||
return fmt.Sprintf("$%.2f", m.Float32())
|
return fmt.Sprintf("$%.2f", m.Float32())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Change the currency to this format when implementing multi-currency
|
||||||
|
// type Currency struct {
|
||||||
|
// Value int64
|
||||||
|
// Type IntCurrency
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // ToCurrency converts a float32 (like 12.34) into Currency (stored in cents).
|
||||||
|
// func NewCurrency(f float32, currencyType IntCurrency) Currency {
|
||||||
|
// cents := math.Round(float64(f) * 100) // avoid float32 precision issues
|
||||||
|
// return Currency{
|
||||||
|
// Value: int64(cents),
|
||||||
|
// Type: currencyType,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func NewBase(v int64) Currency {
|
||||||
|
// return Currency{
|
||||||
|
// Value: v,
|
||||||
|
// Type: BASE,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Float32 converts a Currency back into float32 (like 12.34).
|
||||||
|
// func (m Currency) Float32() float32 {
|
||||||
|
// return float32(m.Value) / 100
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // String returns a formatted Currency value for display.
|
||||||
|
// func (m Currency) String() string {
|
||||||
|
// return fmt.Sprintf("$%.2f", m.Float32())
|
||||||
|
// }
|
||||||
|
|
||||||
type IntCurrency string
|
type IntCurrency string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ETB IntCurrency = "ETB" // Ethiopian Birr
|
BASE IntCurrency = "BASE"
|
||||||
NGN IntCurrency = "NGN" // Nigerian Naira
|
ETB IntCurrency = "ETB" // Ethiopian Birr
|
||||||
ZAR IntCurrency = "ZAR" // South African Rand
|
NGN IntCurrency = "NGN" // Nigerian Naira
|
||||||
EGP IntCurrency = "EGP" // Egyptian Pound
|
ZAR IntCurrency = "ZAR" // South African Rand
|
||||||
KES IntCurrency = "KES" // Kenyan Shilling
|
EGP IntCurrency = "EGP" // Egyptian Pound
|
||||||
UGX IntCurrency = "UGX" // Ugandan Shilling
|
KES IntCurrency = "KES" // Kenyan Shilling
|
||||||
TZS IntCurrency = "TZS" // Tanzanian Shilling
|
UGX IntCurrency = "UGX" // Ugandan Shilling
|
||||||
RWF IntCurrency = "RWF" // Rwandan Franc
|
TZS IntCurrency = "TZS" // Tanzanian Shilling
|
||||||
BIF IntCurrency = "BIF" // Burundian Franc
|
RWF IntCurrency = "RWF" // Rwandan Franc
|
||||||
XOF IntCurrency = "XOF" // West African CFA Franc (BCEAO)
|
BIF IntCurrency = "BIF" // Burundian Franc
|
||||||
XAF IntCurrency = "XAF" // Central African CFA Franc (BEAC)
|
XOF IntCurrency = "XOF" // West African CFA Franc (BCEAO)
|
||||||
GHS IntCurrency = "GHS" // Ghanaian Cedi
|
XAF IntCurrency = "XAF" // Central African CFA Franc (BEAC)
|
||||||
SDG IntCurrency = "SDG" // Sudanese Pound
|
GHS IntCurrency = "GHS" // Ghanaian Cedi
|
||||||
SSP IntCurrency = "SSP" // South Sudanese Pound
|
SDG IntCurrency = "SDG" // Sudanese Pound
|
||||||
DZD IntCurrency = "DZD" // Algerian Dinar
|
SSP IntCurrency = "SSP" // South Sudanese Pound
|
||||||
MAD IntCurrency = "MAD" // Moroccan Dirham
|
DZD IntCurrency = "DZD" // Algerian Dinar
|
||||||
TND IntCurrency = "TND" // Tunisian Dinar
|
MAD IntCurrency = "MAD" // Moroccan Dirham
|
||||||
LYD IntCurrency = "LYD" // Libyan Dinar
|
TND IntCurrency = "TND" // Tunisian Dinar
|
||||||
MZN IntCurrency = "MZN" // Mozambican Metical
|
LYD IntCurrency = "LYD" // Libyan Dinar
|
||||||
AOA IntCurrency = "AOA" // Angolan Kwanza
|
MZN IntCurrency = "MZN" // Mozambican Metical
|
||||||
BWP IntCurrency = "BWP" // Botswana Pula
|
AOA IntCurrency = "AOA" // Angolan Kwanza
|
||||||
ZMW IntCurrency = "ZMW" // Zambian Kwacha
|
BWP IntCurrency = "BWP" // Botswana Pula
|
||||||
MWK IntCurrency = "MWK" // Malawian Kwacha
|
ZMW IntCurrency = "ZMW" // Zambian Kwacha
|
||||||
LSL IntCurrency = "LSL" // Lesotho Loti
|
MWK IntCurrency = "MWK" // Malawian Kwacha
|
||||||
NAD IntCurrency = "NAD" // Namibian Dollar
|
LSL IntCurrency = "LSL" // Lesotho Loti
|
||||||
SZL IntCurrency = "SZL" // Swazi Lilangeni
|
NAD IntCurrency = "NAD" // Namibian Dollar
|
||||||
CVE IntCurrency = "CVE" // Cape Verdean Escudo
|
SZL IntCurrency = "SZL" // Swazi Lilangeni
|
||||||
GMD IntCurrency = "GMD" // Gambian Dalasi
|
CVE IntCurrency = "CVE" // Cape Verdean Escudo
|
||||||
SLL IntCurrency = "SLL" // Sierra Leonean Leone
|
GMD IntCurrency = "GMD" // Gambian Dalasi
|
||||||
LRD IntCurrency = "LRD" // Liberian Dollar
|
SLL IntCurrency = "SLL" // Sierra Leonean Leone
|
||||||
GNF IntCurrency = "GNF" // Guinean Franc
|
LRD IntCurrency = "LRD" // Liberian Dollar
|
||||||
XCD IntCurrency = "XCD" // Eastern Caribbean Dollar (used in Saint Lucia)
|
GNF IntCurrency = "GNF" // Guinean Franc
|
||||||
MRU IntCurrency = "MRU" // Mauritanian Ouguiya
|
XCD IntCurrency = "XCD" // Eastern Caribbean Dollar (used in Saint Lucia)
|
||||||
KMF IntCurrency = "KMF" // Comorian Franc
|
MRU IntCurrency = "MRU" // Mauritanian Ouguiya
|
||||||
DJF IntCurrency = "DJF" // Djiboutian Franc
|
KMF IntCurrency = "KMF" // Comorian Franc
|
||||||
SOS IntCurrency = "SOS" // Somali Shilling
|
DJF IntCurrency = "DJF" // Djiboutian Franc
|
||||||
ERN IntCurrency = "ERN" // Eritrean Nakfa
|
SOS IntCurrency = "SOS" // Somali Shilling
|
||||||
MGA IntCurrency = "MGA" // Malagasy Ariary
|
ERN IntCurrency = "ERN" // Eritrean Nakfa
|
||||||
SCR IntCurrency = "SCR" // Seychellois Rupee
|
MGA IntCurrency = "MGA" // Malagasy Ariary
|
||||||
MUR IntCurrency = "MUR" // Mauritian Rupee
|
SCR IntCurrency = "SCR" // Seychellois Rupee
|
||||||
|
MUR IntCurrency = "MUR" // Mauritian Rupee
|
||||||
|
|
||||||
// International currencies (already listed)
|
// International currencies (already listed)
|
||||||
USD IntCurrency = "USD" // US Dollar
|
USD IntCurrency = "USD" // US Dollar
|
||||||
|
|
|
||||||
|
|
@ -486,25 +486,23 @@ type CreateEnetpulseFixture struct {
|
||||||
|
|
||||||
// Full domain model
|
// Full domain model
|
||||||
type EnetpulseFixture struct {
|
type EnetpulseFixture struct {
|
||||||
FixtureID string
|
FixtureID string `json:"id"`
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
SportFK string
|
SportFK string `json:"sportFK"`
|
||||||
TournamentFK string
|
TournamentFK string `json:"tournamentFK"`
|
||||||
TournamentTemplateFK string
|
TournamentTemplateFK string `json:"tournament_templateFK"`
|
||||||
TournamentStageFK string
|
TournamentStageFK string `json:"tournament_stageFK"`
|
||||||
TournamentStageName string
|
TournamentStageName string `json:"tournament_stage_name"`
|
||||||
TournamentName string
|
TournamentName string `json:"tournament_name"`
|
||||||
TournamentTemplateName string
|
TournamentTemplateName string `json:"tournament_template_name"`
|
||||||
SportName string
|
SportName string `json:"sport_name"`
|
||||||
Gender string
|
Gender string `json:"gender"`
|
||||||
StartDate time.Time
|
StartDate string `json:"startdate"` // ISO 8601
|
||||||
StatusType string
|
StatusType string `json:"status_type"`
|
||||||
StatusDescFK string
|
StatusDescFK string `json:"status_descFK"`
|
||||||
RoundTypeFK string
|
RoundTypeFK string `json:"round_typeFK"`
|
||||||
UpdatesCount int
|
UpdatesCount string `json:"n"` // convert to int
|
||||||
LastUpdatedAt time.Time
|
LastUpdatedAt string `json:"ut"` // parse to time.Time
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateEnetpulseResult struct {
|
type CreateEnetpulseResult struct {
|
||||||
|
|
@ -604,7 +602,7 @@ type CreateEnetpulseOutcomeType struct {
|
||||||
LastUpdatedAt time.Time `json:"last_updated_at"`
|
LastUpdatedAt time.Time `json:"last_updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EnetpulsePreodds struct {
|
type EnetpulsePreoddsTemp struct {
|
||||||
PreoddsID string `json:"preodds_id"`
|
PreoddsID string `json:"preodds_id"`
|
||||||
EventFK string `json:"event_fk"`
|
EventFK string `json:"event_fk"`
|
||||||
OutcomeTypeFK string `json:"outcome_type_fk"`
|
OutcomeTypeFK string `json:"outcome_type_fk"`
|
||||||
|
|
@ -668,3 +666,41 @@ type EnetpulsePreoddsBettingOffer struct {
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnetpulseFixtureWithPreodds struct {
|
||||||
|
FixtureID string
|
||||||
|
FixtureApiID string
|
||||||
|
FixtureName string
|
||||||
|
SportFk string
|
||||||
|
TournamentFk string
|
||||||
|
TournamentTemplateFk string
|
||||||
|
TournamentStageFk string
|
||||||
|
StartDate time.Time
|
||||||
|
StatusType string
|
||||||
|
StatusDescFk string
|
||||||
|
RoundTypeFk string
|
||||||
|
UpdatesCount int32
|
||||||
|
LastUpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
Preodds []EnetpulsePreodds
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnetpulsePreodds struct {
|
||||||
|
ID int64
|
||||||
|
PreoddsID string
|
||||||
|
EventFK int64
|
||||||
|
OutcomeTypeFK int32
|
||||||
|
OutcomeScopeFK int32
|
||||||
|
OutcomeSubtypeFK int32
|
||||||
|
EventParticipantNumber int32
|
||||||
|
IParam string
|
||||||
|
IParam2 string
|
||||||
|
DParam string
|
||||||
|
DParam2 string
|
||||||
|
SParam string
|
||||||
|
UpdatesCount int32
|
||||||
|
LastUpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
|
@ -50,6 +51,58 @@ const (
|
||||||
EVENT_SOURCE_ENET EventSource = "enetpulse"
|
EVENT_SOURCE_ENET EventSource = "enetpulse"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// --- EventStatus Validation ---
|
||||||
|
func (s EventStatus) IsValid() bool {
|
||||||
|
switch s {
|
||||||
|
case STATUS_PENDING,
|
||||||
|
STATUS_IN_PLAY,
|
||||||
|
STATUS_TO_BE_FIXED,
|
||||||
|
STATUS_ENDED,
|
||||||
|
STATUS_POSTPONED,
|
||||||
|
STATUS_CANCELLED,
|
||||||
|
STATUS_WALKOVER,
|
||||||
|
STATUS_INTERRUPTED,
|
||||||
|
STATUS_ABANDONED,
|
||||||
|
STATUS_RETIRED,
|
||||||
|
STATUS_SUSPENDED,
|
||||||
|
STATUS_DECIDED_BY_FA,
|
||||||
|
STATUS_REMOVED:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseEventStatus(val string) (EventStatus, error) {
|
||||||
|
s := EventStatus(val)
|
||||||
|
if !s.IsValid() {
|
||||||
|
return "", fmt.Errorf("invalid EventStatus: %q", val)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- EventSource Validation ---
|
||||||
|
func (s EventSource) IsValid() bool {
|
||||||
|
switch s {
|
||||||
|
case EVENT_SOURCE_BET365,
|
||||||
|
EVENT_SOURCE_BWIN,
|
||||||
|
EVENT_SOURCE_BETFAIR,
|
||||||
|
EVENT_SOURCE_1XBET,
|
||||||
|
EVENT_SOURCE_ENET:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseEventSource(val string) (EventSource, error) {
|
||||||
|
s := EventSource(val)
|
||||||
|
if !s.IsValid() {
|
||||||
|
return "", fmt.Errorf("invalid EventSource: %q", val)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
type BaseEvent struct {
|
type BaseEvent struct {
|
||||||
ID int64
|
ID int64
|
||||||
SourceEventID string
|
SourceEventID string
|
||||||
|
|
@ -67,6 +120,7 @@ type BaseEvent struct {
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
Source EventSource
|
Source EventSource
|
||||||
Status EventStatus
|
Status EventStatus
|
||||||
|
TotalOddOutcomes int64
|
||||||
IsMonitored bool
|
IsMonitored bool
|
||||||
DefaultIsFeatured bool
|
DefaultIsFeatured bool
|
||||||
DefaultIsActive bool
|
DefaultIsActive bool
|
||||||
|
|
@ -96,6 +150,7 @@ type BaseEventRes struct {
|
||||||
StartTime time.Time `json:"start_time"`
|
StartTime time.Time `json:"start_time"`
|
||||||
Source EventSource `json:"source"`
|
Source EventSource `json:"source"`
|
||||||
Status EventStatus `json:"status"`
|
Status EventStatus `json:"status"`
|
||||||
|
TotalOddOutcomes int64 `json:"total_odd_outcomes"`
|
||||||
IsMonitored bool `json:"is_monitored"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
|
|
@ -125,10 +180,11 @@ type EventWithSettings struct {
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
Source EventSource
|
Source EventSource
|
||||||
Status EventStatus
|
Status EventStatus
|
||||||
|
TotalOddOutcomes int64
|
||||||
IsMonitored bool
|
IsMonitored bool
|
||||||
IsFeatured bool
|
IsFeatured bool
|
||||||
IsActive bool
|
IsActive bool
|
||||||
WinningUpperLimit int32
|
WinningUpperLimit int64
|
||||||
DefaultIsFeatured bool
|
DefaultIsFeatured bool
|
||||||
DefaultIsActive bool
|
DefaultIsActive bool
|
||||||
DefaultWinningUpperLimit int64
|
DefaultWinningUpperLimit int64
|
||||||
|
|
@ -178,10 +234,11 @@ type EventWithSettingsRes struct {
|
||||||
StartTime time.Time `json:"start_time"`
|
StartTime time.Time `json:"start_time"`
|
||||||
Source EventSource `json:"source"`
|
Source EventSource `json:"source"`
|
||||||
Status EventStatus `json:"status"`
|
Status EventStatus `json:"status"`
|
||||||
|
TotalOddOutcomes int64 `json:"total_odd_outcomes"`
|
||||||
IsMonitored bool `json:"is_monitored"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
WinningUpperLimit int64 `json:"winning_upper_limit"`
|
||||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
DefaultIsActive bool `json:"default_is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||||
|
|
@ -204,12 +261,18 @@ type EventSettings struct {
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateEventSettings struct {
|
type UpdateTenantEventSettings struct {
|
||||||
CompanyID int64
|
CompanyID int64
|
||||||
EventID int64
|
EventID int64
|
||||||
IsActive ValidBool
|
IsActive ValidBool
|
||||||
IsFeatured ValidBool
|
IsFeatured ValidBool
|
||||||
WinningUpperLimit ValidInt
|
WinningUpperLimit ValidInt64
|
||||||
|
}
|
||||||
|
type UpdateGlobalEventSettings struct {
|
||||||
|
EventID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
IsFeatured ValidBool
|
||||||
|
WinningUpperLimit ValidInt64
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidEventStatus struct {
|
type ValidEventStatus struct {
|
||||||
|
|
@ -273,6 +336,7 @@ func ConvertDBEvent(event dbgen.EventWithCountry) BaseEvent {
|
||||||
StartTime: event.StartTime.Time.UTC(),
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
Source: EventSource(event.Source),
|
Source: EventSource(event.Source),
|
||||||
Status: EventStatus(event.Status),
|
Status: EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOutcomes,
|
||||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
DefaultIsActive: event.DefaultIsActive,
|
DefaultIsActive: event.DefaultIsActive,
|
||||||
|
|
@ -331,8 +395,8 @@ func ConvertCreateEvent(e CreateEvent) dbgen.InsertEventParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateEventSettings(eventSettings CreateEventSettings) dbgen.SaveEventSettingsParams {
|
func ConvertCreateEventSettings(eventSettings UpdateTenantEventSettings) dbgen.SaveTenantEventSettingsParams {
|
||||||
return dbgen.SaveEventSettingsParams{
|
return dbgen.SaveTenantEventSettingsParams{
|
||||||
CompanyID: eventSettings.CompanyID,
|
CompanyID: eventSettings.CompanyID,
|
||||||
EventID: eventSettings.EventID,
|
EventID: eventSettings.EventID,
|
||||||
IsActive: eventSettings.IsActive.ToPG(),
|
IsActive: eventSettings.IsActive.ToPG(),
|
||||||
|
|
@ -343,17 +407,19 @@ func ConvertCreateEventSettings(eventSettings CreateEventSettings) dbgen.SaveEve
|
||||||
|
|
||||||
func ConvertDBEventWithSetting(event dbgen.EventWithSetting) EventWithSettings {
|
func ConvertDBEventWithSetting(event dbgen.EventWithSetting) EventWithSettings {
|
||||||
return EventWithSettings{
|
return EventWithSettings{
|
||||||
ID: event.ID,
|
ID: event.ID,
|
||||||
SportID: event.SportID,
|
SourceEventID: event.SourceEventID,
|
||||||
MatchName: event.MatchName,
|
WinningUpperLimit: event.WinningUpperLimit,
|
||||||
HomeTeam: event.HomeTeam,
|
SportID: event.SportID,
|
||||||
AwayTeam: event.AwayTeam,
|
MatchName: event.MatchName,
|
||||||
HomeTeamID: event.HomeTeamID,
|
HomeTeam: event.HomeTeam,
|
||||||
AwayTeamID: event.AwayTeamID,
|
AwayTeam: event.AwayTeam,
|
||||||
HomeTeamImage: event.HomeKitImage,
|
HomeTeamID: event.HomeTeamID,
|
||||||
AwayTeamImage: event.AwayKitImage,
|
AwayTeamID: event.AwayTeamID,
|
||||||
LeagueID: event.LeagueID,
|
HomeTeamImage: event.HomeKitImage,
|
||||||
LeagueName: event.LeagueName,
|
AwayTeamImage: event.AwayKitImage,
|
||||||
|
LeagueID: event.LeagueID,
|
||||||
|
LeagueName: event.LeagueName,
|
||||||
LeagueCC: ValidString{
|
LeagueCC: ValidString{
|
||||||
Value: event.LeagueCc.String,
|
Value: event.LeagueCc.String,
|
||||||
Valid: event.LeagueCc.Valid,
|
Valid: event.LeagueCc.Valid,
|
||||||
|
|
@ -361,6 +427,7 @@ func ConvertDBEventWithSetting(event dbgen.EventWithSetting) EventWithSettings {
|
||||||
StartTime: event.StartTime.Time.UTC(),
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
Source: EventSource(event.Source),
|
Source: EventSource(event.Source),
|
||||||
Status: EventStatus(event.Status),
|
Status: EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOutcomes,
|
||||||
IsFeatured: event.IsFeatured,
|
IsFeatured: event.IsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
IsActive: event.IsActive,
|
IsActive: event.IsActive,
|
||||||
|
|
@ -401,8 +468,8 @@ func ConvertDBEventWithSettings(events []dbgen.EventWithSetting) []EventWithSett
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertUpdateEventSettings(event CreateEventSettings) dbgen.SaveEventSettingsParams {
|
func ConvertUpdateTenantEventSettings(event UpdateTenantEventSettings) dbgen.SaveTenantEventSettingsParams {
|
||||||
return dbgen.SaveEventSettingsParams{
|
return dbgen.SaveTenantEventSettingsParams{
|
||||||
EventID: event.EventID,
|
EventID: event.EventID,
|
||||||
CompanyID: event.CompanyID,
|
CompanyID: event.CompanyID,
|
||||||
IsActive: event.IsActive.ToPG(),
|
IsActive: event.IsActive.ToPG(),
|
||||||
|
|
@ -410,10 +477,19 @@ func ConvertUpdateEventSettings(event CreateEventSettings) dbgen.SaveEventSettin
|
||||||
WinningUpperLimit: event.WinningUpperLimit.ToPG(),
|
WinningUpperLimit: event.WinningUpperLimit.ToPG(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func ConvertUpdateGlobalEventSettings(event UpdateGlobalEventSettings) dbgen.UpdateGlobalEventSettingsParams {
|
||||||
|
return dbgen.UpdateGlobalEventSettingsParams{
|
||||||
|
ID: event.EventID,
|
||||||
|
DefaultIsActive: event.IsActive.ToPG(),
|
||||||
|
DefaultIsFeatured: event.IsFeatured.ToPG(),
|
||||||
|
DefaultWinningUpperLimit: event.WinningUpperLimit.ToPG(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ConvertEventRes(event BaseEvent) BaseEventRes {
|
func ConvertEventRes(event BaseEvent) BaseEventRes {
|
||||||
return BaseEventRes{
|
return BaseEventRes{
|
||||||
ID: event.ID,
|
ID: event.ID,
|
||||||
|
SourceEventID: event.SourceEventID,
|
||||||
SportID: event.SportID,
|
SportID: event.SportID,
|
||||||
MatchName: event.MatchName,
|
MatchName: event.MatchName,
|
||||||
HomeTeam: event.HomeTeam,
|
HomeTeam: event.HomeTeam,
|
||||||
|
|
@ -428,6 +504,7 @@ func ConvertEventRes(event BaseEvent) BaseEventRes {
|
||||||
StartTime: event.StartTime.UTC(),
|
StartTime: event.StartTime.UTC(),
|
||||||
Source: EventSource(event.Source),
|
Source: EventSource(event.Source),
|
||||||
Status: EventStatus(event.Status),
|
Status: EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOddOutcomes,
|
||||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
DefaultIsActive: event.DefaultIsActive,
|
DefaultIsActive: event.DefaultIsActive,
|
||||||
|
|
@ -452,6 +529,7 @@ func ConvertEventResList(events []BaseEvent) []BaseEventRes {
|
||||||
func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
||||||
return EventWithSettingsRes{
|
return EventWithSettingsRes{
|
||||||
ID: event.ID,
|
ID: event.ID,
|
||||||
|
SourceEventID: event.SourceEventID,
|
||||||
SportID: event.SportID,
|
SportID: event.SportID,
|
||||||
MatchName: event.MatchName,
|
MatchName: event.MatchName,
|
||||||
HomeTeam: event.HomeTeam,
|
HomeTeam: event.HomeTeam,
|
||||||
|
|
@ -466,6 +544,7 @@ func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
||||||
StartTime: event.StartTime.UTC(),
|
StartTime: event.StartTime.UTC(),
|
||||||
Source: EventSource(event.Source),
|
Source: EventSource(event.Source),
|
||||||
Status: EventStatus(event.Status),
|
Status: EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOddOutcomes,
|
||||||
IsFeatured: event.IsFeatured,
|
IsFeatured: event.IsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
IsActive: event.IsActive,
|
IsActive: event.IsActive,
|
||||||
|
|
@ -480,6 +559,7 @@ func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
||||||
MatchPeriod: event.MatchPeriod.Value,
|
MatchPeriod: event.MatchPeriod.Value,
|
||||||
IsLive: event.IsLive,
|
IsLive: event.IsLive,
|
||||||
FetchedAt: event.FetchedAt.UTC(),
|
FetchedAt: event.FetchedAt.UTC(),
|
||||||
|
UpdatedAt: event.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,17 @@ type UpdateLeague struct {
|
||||||
SportID ValidInt32 `json:"sport_id" example:"1"`
|
SportID ValidInt32 `json:"sport_id" example:"1"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateLeagueSettingsReq struct {
|
||||||
|
IsFeatured *bool `json:"is_featured" example:"true"`
|
||||||
|
IsActive *bool `json:"is_active" example:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateGlobalLeagueSettings struct {
|
||||||
|
ID int64
|
||||||
|
DefaultIsActive ValidBool
|
||||||
|
DefaultIsFeatured ValidBool
|
||||||
|
}
|
||||||
|
|
||||||
type LeagueFilter struct {
|
type LeagueFilter struct {
|
||||||
Query ValidString
|
Query ValidString
|
||||||
CountryCode ValidString
|
CountryCode ValidString
|
||||||
|
|
@ -109,8 +120,8 @@ func ConvertCreateLeague(league CreateLeague) dbgen.InsertLeagueParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateLeagueSettings(leagueSetting CreateLeagueSettings) dbgen.InsertLeagueSettingsParams {
|
func ConvertCreateLeagueSettings(leagueSetting CreateLeagueSettings) dbgen.SaveLeagueSettingsParams {
|
||||||
return dbgen.InsertLeagueSettingsParams{
|
return dbgen.SaveLeagueSettingsParams{
|
||||||
CompanyID: leagueSetting.CompanyID,
|
CompanyID: leagueSetting.CompanyID,
|
||||||
LeagueID: leagueSetting.LeagueID,
|
LeagueID: leagueSetting.LeagueID,
|
||||||
IsActive: leagueSetting.IsActive.ToPG(),
|
IsActive: leagueSetting.IsActive.ToPG(),
|
||||||
|
|
@ -149,7 +160,7 @@ func ConvertDBLeagueWithSetting(lws dbgen.GetAllLeaguesWithSettingsRow) LeagueWi
|
||||||
ID: lws.ID,
|
ID: lws.ID,
|
||||||
Name: lws.Name,
|
Name: lws.Name,
|
||||||
CompanyID: lws.CompanyID.Int64,
|
CompanyID: lws.CompanyID.Int64,
|
||||||
CountryCode: ValidString{
|
CountryCode: ValidString{
|
||||||
Value: lws.CountryCode.String,
|
Value: lws.CountryCode.String,
|
||||||
Valid: lws.CountryCode.Valid,
|
Valid: lws.CountryCode.Valid,
|
||||||
},
|
},
|
||||||
|
|
@ -187,15 +198,15 @@ func ConvertUpdateLeague(updateLeague UpdateLeague) dbgen.UpdateLeagueParams {
|
||||||
|
|
||||||
func ConvertLeagueWithSettingRes(lws LeagueWithSettings) LeagueWithSettingsRes {
|
func ConvertLeagueWithSettingRes(lws LeagueWithSettings) LeagueWithSettingsRes {
|
||||||
return LeagueWithSettingsRes{
|
return LeagueWithSettingsRes{
|
||||||
ID: lws.ID,
|
ID: lws.ID,
|
||||||
Name: lws.Name,
|
Name: lws.Name,
|
||||||
CompanyID: lws.CompanyID,
|
CompanyID: lws.CompanyID,
|
||||||
CountryCode: lws.CountryCode.Value,
|
CountryCode: lws.CountryCode.Value,
|
||||||
Bet365ID: lws.Bet365ID.Value,
|
Bet365ID: lws.Bet365ID.Value,
|
||||||
IsActive: lws.IsActive,
|
IsActive: lws.IsActive,
|
||||||
SportID: lws.SportID,
|
SportID: lws.SportID,
|
||||||
IsFeatured: lws.IsFeatured,
|
IsFeatured: lws.IsFeatured,
|
||||||
UpdatedAt: lws.UpdatedAt,
|
UpdatedAt: lws.UpdatedAt,
|
||||||
DefaultIsActive: lws.DefaultIsActive,
|
DefaultIsActive: lws.DefaultIsActive,
|
||||||
DefaultIsFeatured: lws.DefaultIsFeatured,
|
DefaultIsFeatured: lws.DefaultIsFeatured,
|
||||||
}
|
}
|
||||||
|
|
@ -213,12 +224,12 @@ func ConvertLeagueWithSettingResList(leagues []LeagueWithSettings) []LeagueWithS
|
||||||
|
|
||||||
func ConvertBaseLeagueRes(league BaseLeague) BaseLeagueRes {
|
func ConvertBaseLeagueRes(league BaseLeague) BaseLeagueRes {
|
||||||
return BaseLeagueRes{
|
return BaseLeagueRes{
|
||||||
ID: league.ID,
|
ID: league.ID,
|
||||||
Name: league.Name,
|
Name: league.Name,
|
||||||
CountryCode: league.CountryCode.Value,
|
CountryCode: league.CountryCode.Value,
|
||||||
Bet365ID: league.Bet365ID.Value,
|
Bet365ID: league.Bet365ID.Value,
|
||||||
SportID: league.SportID,
|
SportID: league.SportID,
|
||||||
DefaultIsActive: league.DefaultIsActive,
|
DefaultIsActive: league.DefaultIsActive,
|
||||||
DefaultIsFeatured: league.DefaultIsFeatured,
|
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -231,3 +242,11 @@ func ConvertBaseLeagueResList(leagues []BaseLeague) []BaseLeagueRes {
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertUpdateGlobalLeagueSetting(league UpdateGlobalLeagueSettings) dbgen.UpdateGlobalLeagueSettingsParams {
|
||||||
|
return dbgen.UpdateGlobalLeagueSettingsParams{
|
||||||
|
ID: league.ID,
|
||||||
|
IsActive: league.DefaultIsActive.ToPG(),
|
||||||
|
IsFeatured: league.DefaultIsFeatured.ToPG(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ type Notification struct {
|
||||||
Priority int `json:"priority,omitempty"`
|
Priority int `json:"priority,omitempty"`
|
||||||
Version int `json:"-"`
|
Version int `json:"-"`
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
Expires time.Time `json:"expires"`
|
||||||
|
Image string `json:"image"`
|
||||||
Metadata json.RawMessage `json:"metadata,omitempty"`
|
Metadata json.RawMessage `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
type CreateNotification struct {
|
type CreateNotification struct {
|
||||||
|
|
@ -97,6 +99,8 @@ type CreateNotification struct {
|
||||||
DeliveryChannel DeliveryChannel `json:"delivery_channel,omitempty"`
|
DeliveryChannel DeliveryChannel `json:"delivery_channel,omitempty"`
|
||||||
Payload NotificationPayload `json:"payload"`
|
Payload NotificationPayload `json:"payload"`
|
||||||
Priority int `json:"priority,omitempty"`
|
Priority int `json:"priority,omitempty"`
|
||||||
|
Expires time.Time `json:"expires"`
|
||||||
|
Image string `json:"image,omitempty"`
|
||||||
Metadata json.RawMessage `json:"metadata,omitempty"`
|
Metadata json.RawMessage `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,42 +9,45 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateOddMarket struct {
|
type CreateOddMarket struct {
|
||||||
EventID int64
|
EventID int64
|
||||||
MarketCategory string
|
MarketCategory string
|
||||||
MarketType string
|
MarketType string
|
||||||
MarketName string
|
MarketName string
|
||||||
MarketID int64
|
MarketID int64
|
||||||
UpdatedAt time.Time
|
NumberOfOutcomes int64
|
||||||
Odds []map[string]interface{}
|
UpdatedAt time.Time
|
||||||
|
Odds []map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type OddMarket struct {
|
type OddMarket struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
RawOdds []json.RawMessage `json:"raw_odds"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt time.Time `json:"fetched_at"`
|
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||||
ExpiresAt time.Time `json:"expires_at"`
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
DefaultIsActive bool `json:"is_active"`
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
IsMonitored bool `json:"is_monitored"`
|
DefaultIsActive bool `json:"is_active"`
|
||||||
IsLive bool `json:"is_live"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
Status EventStatus `json:"status"`
|
IsLive bool `json:"is_live"`
|
||||||
Source EventSource `json:"source"`
|
Status EventStatus `json:"status"`
|
||||||
|
Source EventSource `json:"source"`
|
||||||
}
|
}
|
||||||
type OddMarketWithSettings struct {
|
type OddMarketWithSettings struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID int64 `json:"event_id"`
|
EventID int64 `json:"event_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory string `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID int64 `json:"market_id"`
|
MarketID int64 `json:"market_id"`
|
||||||
RawOdds []json.RawMessage `json:"raw_odds"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
FetchedAt time.Time `json:"fetched_at"`
|
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||||
ExpiresAt time.Time `json:"expires_at"`
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
IsActive bool `json:"is_active"`
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OddMarketSettings struct {
|
type OddMarketSettings struct {
|
||||||
|
|
@ -61,6 +64,11 @@ type CreateOddMarketSettings struct {
|
||||||
CustomRawOdds []map[string]interface{}
|
CustomRawOdds []map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateGlobalOddMarketSettings struct {
|
||||||
|
OddMarketID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
}
|
||||||
|
|
||||||
type CustomOdd struct {
|
type CustomOdd struct {
|
||||||
OddID int64 `json:"odd_id"`
|
OddID int64 `json:"odd_id"`
|
||||||
OddValue float32 `json:"odd_value"`
|
OddValue float32 `json:"odd_value"`
|
||||||
|
|
@ -72,6 +80,11 @@ type CreateOddMarketSettingsReq struct {
|
||||||
CustomOdd []CustomOdd `json:"custom_odd,omitempty"`
|
CustomOdd []CustomOdd `json:"custom_odd,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateGlobalOddMarketSettingsReq struct {
|
||||||
|
OddMarketID int64 `json:"odd_market_id"`
|
||||||
|
IsActive *bool `json:"is_active,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type RawOddsByMarketID struct {
|
type RawOddsByMarketID struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
MarketName string `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
|
|
@ -86,6 +99,8 @@ type OddMarketFilter struct {
|
||||||
Offset ValidInt32
|
Offset ValidInt32
|
||||||
}
|
}
|
||||||
type OddMarketWithEventFilter struct {
|
type OddMarketWithEventFilter struct {
|
||||||
|
Status ValidString
|
||||||
|
IsLive ValidBool
|
||||||
Limit ValidInt32
|
Limit ValidInt32
|
||||||
Offset ValidInt32
|
Offset ValidInt32
|
||||||
}
|
}
|
||||||
|
|
@ -100,20 +115,21 @@ func ConvertDBOddMarket(oddMarket dbgen.OddsMarketWithEvent) (OddMarket, error)
|
||||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||||
}
|
}
|
||||||
return OddMarket{
|
return OddMarket{
|
||||||
ID: oddMarket.ID,
|
ID: oddMarket.ID,
|
||||||
EventID: oddMarket.EventID,
|
EventID: oddMarket.EventID,
|
||||||
MarketType: oddMarket.MarketType,
|
MarketType: oddMarket.MarketType,
|
||||||
MarketName: oddMarket.MarketName,
|
MarketName: oddMarket.MarketName,
|
||||||
MarketCategory: oddMarket.MarketCategory,
|
MarketCategory: oddMarket.MarketCategory,
|
||||||
MarketID: oddMarket.MarketID,
|
MarketID: oddMarket.MarketID,
|
||||||
RawOdds: rawOdds,
|
NumberOfOutcomes: oddMarket.NumberOfOutcomes,
|
||||||
FetchedAt: oddMarket.FetchedAt.Time,
|
RawOdds: rawOdds,
|
||||||
ExpiresAt: oddMarket.ExpiresAt.Time,
|
FetchedAt: oddMarket.FetchedAt.Time,
|
||||||
DefaultIsActive: oddMarket.DefaultIsActive,
|
ExpiresAt: oddMarket.ExpiresAt.Time,
|
||||||
IsMonitored: oddMarket.IsMonitored,
|
DefaultIsActive: oddMarket.DefaultIsActive,
|
||||||
IsLive: oddMarket.IsLive,
|
IsMonitored: oddMarket.IsMonitored,
|
||||||
Status: EventStatus(oddMarket.Status),
|
IsLive: oddMarket.IsLive,
|
||||||
Source: EventSource(oddMarket.Source),
|
Status: EventStatus(oddMarket.Status),
|
||||||
|
Source: EventSource(oddMarket.Source),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,14 +152,15 @@ func ConvertCreateOddMarket(oddMarket CreateOddMarket) (dbgen.InsertOddsMarketPa
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbgen.InsertOddsMarketParams{
|
return dbgen.InsertOddsMarketParams{
|
||||||
EventID: oddMarket.EventID,
|
EventID: oddMarket.EventID,
|
||||||
MarketType: oddMarket.MarketType,
|
MarketType: oddMarket.MarketType,
|
||||||
MarketName: oddMarket.MarketName,
|
MarketName: oddMarket.MarketName,
|
||||||
MarketCategory: oddMarket.MarketCategory,
|
MarketCategory: oddMarket.MarketCategory,
|
||||||
MarketID: oddMarket.MarketID,
|
MarketID: oddMarket.MarketID,
|
||||||
RawOdds: rawOddsBytes,
|
NumberOfOutcomes: oddMarket.NumberOfOutcomes,
|
||||||
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
RawOdds: rawOddsBytes,
|
||||||
ExpiresAt: pgtype.Timestamp{Time: (time.Now()).Add(time.Hour), Valid: true},
|
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||||
|
ExpiresAt: pgtype.Timestamp{Time: (time.Now()).Add(time.Hour), Valid: true},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,16 +187,17 @@ func ConvertDBOddMarketWithSetting(oms dbgen.OddsMarketWithSetting) (OddMarketWi
|
||||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||||
}
|
}
|
||||||
return OddMarketWithSettings{
|
return OddMarketWithSettings{
|
||||||
ID: oms.ID,
|
ID: oms.ID,
|
||||||
EventID: oms.EventID,
|
EventID: oms.EventID,
|
||||||
MarketType: oms.MarketType,
|
MarketType: oms.MarketType,
|
||||||
MarketName: oms.MarketName,
|
MarketName: oms.MarketName,
|
||||||
MarketCategory: oms.MarketCategory,
|
MarketCategory: oms.MarketCategory,
|
||||||
MarketID: oms.MarketID,
|
MarketID: oms.MarketID,
|
||||||
RawOdds: rawOdds,
|
NumberOfOutcomes: oms.NumberOfOutcomes,
|
||||||
FetchedAt: oms.FetchedAt.Time,
|
RawOdds: rawOdds,
|
||||||
ExpiresAt: oms.ExpiresAt.Time,
|
FetchedAt: oms.FetchedAt.Time,
|
||||||
IsActive: oms.IsActive,
|
ExpiresAt: oms.ExpiresAt.Time,
|
||||||
|
IsActive: oms.IsActive,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ package domain
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Raffle struct {
|
type Raffle struct {
|
||||||
ID int32
|
ID int32
|
||||||
CompanyID int32
|
CompanyID int32
|
||||||
Name string
|
Name string
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
Type string
|
TicketLimit int32
|
||||||
Status string
|
Type string
|
||||||
|
Status string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RaffleFilter struct {
|
type RaffleFilter struct {
|
||||||
|
|
@ -64,10 +65,11 @@ type RaffleTicketRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateRaffle struct {
|
type CreateRaffle struct {
|
||||||
CompanyID int32 `json:"company_id" validate:"required"`
|
CompanyID int32 `json:"company_id" validate:"required"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
ExpiresAt *time.Time `json:"expires_at" validate:"required"`
|
ExpiresAt *time.Time `json:"expires_at" validate:"required"`
|
||||||
Type string `json:"type" validate:"required"`
|
TicketLimit int32 `json:"ticket_limit" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateRaffleTicket struct {
|
type CreateRaffleTicket struct {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
|
@ -48,6 +49,28 @@ const (
|
||||||
OUTCOME_STATUS_ERROR OutcomeStatus = 5 //Half Win and Half Given Back
|
OUTCOME_STATUS_ERROR OutcomeStatus = 5 //Half Win and Half Given Back
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (o OutcomeStatus) IsValid() bool {
|
||||||
|
switch o {
|
||||||
|
case OUTCOME_STATUS_PENDING,
|
||||||
|
OUTCOME_STATUS_WIN,
|
||||||
|
OUTCOME_STATUS_LOSS,
|
||||||
|
OUTCOME_STATUS_VOID,
|
||||||
|
OUTCOME_STATUS_HALF,
|
||||||
|
OUTCOME_STATUS_ERROR:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseOutcomeStatus(val int) (OutcomeStatus, error) {
|
||||||
|
o := OutcomeStatus(val)
|
||||||
|
if !o.IsValid() {
|
||||||
|
return 0, fmt.Errorf("invalid OutcomeStatus: %d", val)
|
||||||
|
}
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (o *OutcomeStatus) String() string {
|
func (o *OutcomeStatus) String() string {
|
||||||
switch *o {
|
switch *o {
|
||||||
case OUTCOME_STATUS_PENDING:
|
case OUTCOME_STATUS_PENDING:
|
||||||
|
|
@ -72,7 +95,6 @@ type ValidOutcomeStatus struct {
|
||||||
Valid bool
|
Valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (v ValidOutcomeStatus) ToPG() pgtype.Int4 {
|
func (v ValidOutcomeStatus) ToPG() pgtype.Int4 {
|
||||||
return pgtype.Int4{
|
return pgtype.Int4{
|
||||||
Int32: int32(v.Value),
|
Int32: int32(v.Value),
|
||||||
|
|
@ -80,7 +102,6 @@ func (v ValidOutcomeStatus) ToPG() pgtype.Int4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type TimeStatus int32
|
type TimeStatus int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ type ShopBetDetail struct {
|
||||||
CompanyID int64
|
CompanyID int64
|
||||||
FullName string
|
FullName string
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
|
FastCode string
|
||||||
CashoutID string
|
CashoutID string
|
||||||
CashedOut bool
|
CashedOut bool
|
||||||
BetID int64
|
BetID int64
|
||||||
|
|
@ -80,12 +81,13 @@ type ShopBetRes struct {
|
||||||
CompanyID int64 `json:"company_id" example:"2"`
|
CompanyID int64 `json:"company_id" example:"2"`
|
||||||
FullName string `json:"full_name" example:"John"`
|
FullName string `json:"full_name" example:"John"`
|
||||||
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
||||||
|
FastCode string `json:"fast_code" example:"12SD1"`
|
||||||
CashoutID string `json:"cashout_id" example:"21234"`
|
CashoutID string `json:"cashout_id" example:"21234"`
|
||||||
CashedOut bool `json:"cashed_out" example:"false"`
|
CashedOut bool `json:"cashed_out" example:"false"`
|
||||||
BetID int64 `json:"bet_id" example:"1"`
|
BetID int64 `json:"bet_id" example:"1"`
|
||||||
NumberOfOutcomes int64 `json:"number_of_outcomes" example:"1"`
|
NumberOfOutcomes int64 `json:"number_of_outcomes" example:"1"`
|
||||||
Status OutcomeStatus `json:"status" example:"1"`
|
Status OutcomeStatus `json:"status" example:"1"`
|
||||||
Amount Currency `json:"amount"`
|
Amount float32 `json:"amount"`
|
||||||
Outcomes []BetOutcome `json:"outcomes"`
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
TransactionVerified bool `json:"transaction_verified" example:"true"`
|
TransactionVerified bool `json:"transaction_verified" example:"true"`
|
||||||
UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:00:00Z"`
|
UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:00:00Z"`
|
||||||
|
|
@ -111,12 +113,13 @@ func ConvertShopBetDetail(shopBet ShopBetDetail) ShopBetRes {
|
||||||
CompanyID: shopBet.CompanyID,
|
CompanyID: shopBet.CompanyID,
|
||||||
FullName: shopBet.FullName,
|
FullName: shopBet.FullName,
|
||||||
PhoneNumber: shopBet.PhoneNumber,
|
PhoneNumber: shopBet.PhoneNumber,
|
||||||
|
FastCode: shopBet.FastCode,
|
||||||
CashoutID: shopBet.CashoutID,
|
CashoutID: shopBet.CashoutID,
|
||||||
CashedOut: shopBet.CashedOut,
|
CashedOut: shopBet.CashedOut,
|
||||||
BetID: shopBet.BetID,
|
BetID: shopBet.BetID,
|
||||||
NumberOfOutcomes: shopBet.NumberOfOutcomes,
|
NumberOfOutcomes: shopBet.NumberOfOutcomes,
|
||||||
Status: shopBet.Status,
|
Status: shopBet.Status,
|
||||||
Amount: shopBet.Amount,
|
Amount: shopBet.Amount.Float32(),
|
||||||
Outcomes: shopBet.Outcomes,
|
Outcomes: shopBet.Outcomes,
|
||||||
TransactionVerified: shopBet.TransactionVerified,
|
TransactionVerified: shopBet.TransactionVerified,
|
||||||
UpdatedAt: shopBet.UpdatedAt,
|
UpdatedAt: shopBet.UpdatedAt,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrWalletIDDuplicate = errors.New("there already exists user id with wallet_type")
|
||||||
|
)
|
||||||
|
|
||||||
type Wallet struct {
|
type Wallet struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,11 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma
|
||||||
Query: filter.Query.ToPG(),
|
Query: filter.Query.ToPG(),
|
||||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
Offset: filter.Offset.ToPG(),
|
Offset: pgtype.Int4{
|
||||||
Limit: filter.Limit.ToPG(),
|
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||||
|
Valid: filter.Offset.Valid,
|
||||||
|
},
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to get all bets",
|
domain.MongoDBLogger.Error("failed to get all bets",
|
||||||
|
|
@ -123,7 +126,7 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma
|
||||||
Query: filter.Query.ToPG(),
|
Query: filter.Query.ToPG(),
|
||||||
CreatedBefore: filter.CreatedBefore.ToPG(),
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
CreatedAfter: filter.CreatedAfter.ToPG(),
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
});
|
})
|
||||||
|
|
||||||
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
|
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
|
||||||
for _, bet := range bets {
|
for _, bet := range bets {
|
||||||
|
|
@ -275,6 +278,36 @@ func (s *Store) SettleWinningBet(ctx context.Context, betID int64, userID int64,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetBetOutcomeViewByEventID(ctx context.Context, eventID int64, filter domain.BetOutcomeViewFilter) ([]domain.BetOutcomeViewRes, int64, error) {
|
||||||
|
|
||||||
|
outcomes, err := s.queries.GetBetOutcomeViewByEventID(ctx, dbgen.GetBetOutcomeViewByEventIDParams{
|
||||||
|
EventID: eventID,
|
||||||
|
FilterStatus: filter.OutcomeStatus.ToPG(),
|
||||||
|
CompanyID: filter.CompanyID.ToPG(),
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Error("failed to get bet outcomes by event ID",
|
||||||
|
zap.Int64("event_id", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
total, err := s.queries.TotalBetOutcomeViewByEventID(ctx, dbgen.TotalBetOutcomeViewByEventIDParams{
|
||||||
|
EventID: eventID,
|
||||||
|
FilterStatus: filter.OutcomeStatus.ToPG(),
|
||||||
|
CompanyID: filter.CompanyID.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
var result []domain.BetOutcomeViewRes = make([]domain.BetOutcomeViewRes, 0, len(outcomes))
|
||||||
|
for _, outcome := range outcomes {
|
||||||
|
result = append(result, domain.ConvertDBBetOutcomesView(outcome))
|
||||||
|
}
|
||||||
|
return result, total, nil
|
||||||
|
}
|
||||||
func (s *Store) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error) {
|
func (s *Store) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error) {
|
||||||
|
|
||||||
outcomes, err := s.queries.GetBetOutcomeByEventID(ctx, dbgen.GetBetOutcomeByEventIDParams{
|
outcomes, err := s.queries.GetBetOutcomeByEventID(ctx, dbgen.GetBetOutcomeByEventIDParams{
|
||||||
|
|
@ -377,6 +410,45 @@ func (s *Store) UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int6
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
func (s *Store) UpdateBetOutcomeStatusForOddId(ctx context.Context, oddID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error) {
|
||||||
|
outcomes, err := s.queries.UpdateBetOutcomeStatusForOddID(ctx, dbgen.UpdateBetOutcomeStatusForOddIDParams{
|
||||||
|
OddID: oddID,
|
||||||
|
Status: int32(status),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Error("failed to update bet outcome status for oddID",
|
||||||
|
zap.Int64("oddId", oddID),
|
||||||
|
zap.Int32("status", int32(status)),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||||
|
for _, outcome := range outcomes {
|
||||||
|
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) (error) {
|
||||||
|
err := s.queries.BulkUpdateBetOutcomeStatusByOddIDs(ctx, dbgen.BulkUpdateBetOutcomeStatusByOddIDsParams{
|
||||||
|
Status: int32(status),
|
||||||
|
OddIds: oddID,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Error("failed to update bet outcome status for oddIDs",
|
||||||
|
zap.Int64s("oddIds", oddID),
|
||||||
|
zap.Int32("status", int32(status)),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Store) UpdateBetWithCashback(ctx context.Context, betID int64, cashbackStatus bool) error {
|
func (s *Store) UpdateBetWithCashback(ctx context.Context, betID int64, cashbackStatus bool) error {
|
||||||
err := s.queries.UpdateBetWithCashback(ctx, dbgen.UpdateBetWithCashbackParams{
|
err := s.queries.UpdateBetWithCashback(ctx, dbgen.UpdateBetWithCashbackParams{
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,11 @@ func (s *Store) GetAllBranches(ctx context.Context, filter domain.BranchFilter)
|
||||||
return branches, nil
|
return branches, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error) {
|
func (s *Store) SearchBranchByName(ctx context.Context, name string, companyID domain.ValidInt64) ([]domain.BranchDetail, error) {
|
||||||
dbBranches, err := s.queries.SearchBranchByName(ctx, pgtype.Text{String: name, Valid: true})
|
dbBranches, err := s.queries.SearchBranchByName(ctx, dbgen.SearchBranchByNameParams{
|
||||||
|
Column1: pgtype.Text{String: name, Valid: true},
|
||||||
|
CompanyID: companyID.ToPG(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
internal/repository/common.go
Normal file
12
internal/repository/common.go
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsUniqueViolation(err error) bool {
|
||||||
|
var pgErr *pgconn.PgError
|
||||||
|
return errors.As(err, &pgErr) && pgErr.Code == "23505"
|
||||||
|
}
|
||||||
|
|
@ -2,36 +2,34 @@ package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
|
|
||||||
"github.com/jackc/pgx/v5"
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
|
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
|
||||||
baseSlug := helpers.GenerateSlug(company.Name)
|
// baseSlug := helpers.GenerateSlug(company.Name)
|
||||||
uniqueSlug := baseSlug
|
// uniqueSlug := baseSlug
|
||||||
i := 1
|
// i := 1
|
||||||
|
|
||||||
for {
|
// for {
|
||||||
_, err := s.queries.GetCompanyIDUsingSlug(ctx, uniqueSlug)
|
// _, err := s.queries.GetCompanyUsingSlug(ctx, uniqueSlug)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
// if errors.Is(err, pgx.ErrNoRows) {
|
||||||
// slug is unique
|
// // slug is unique
|
||||||
break
|
// break
|
||||||
} else {
|
// } else {
|
||||||
// real DB error
|
// // real DB error
|
||||||
return domain.Company{}, err
|
// return domain.Company{}, err
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i)
|
// uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i)
|
||||||
i++
|
// i++
|
||||||
}
|
// }
|
||||||
|
fmt.Printf("\ncompany %v\n\n", company)
|
||||||
|
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company))
|
||||||
|
|
||||||
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company, uniqueSlug))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Company{}, err
|
return domain.Company{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -78,25 +76,26 @@ func (s *Store) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany
|
||||||
return domain.ConvertDBCompanyDetails(dbCompany), nil
|
return domain.ConvertDBCompanyDetails(dbCompany), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error) {
|
func (s *Store) GetCompanyBySlug(ctx context.Context, slug string) (domain.Company, error) {
|
||||||
dbCompanyID, err := s.queries.GetCompanyIDUsingSlug(ctx, slug)
|
dbCompany, err := s.queries.GetCompanyUsingSlug(ctx, slug)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return dbCompanyID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
|
|
||||||
dbCompany, err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company))
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Company{}, err
|
return domain.Company{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.ConvertDBCompany(dbCompany), nil
|
return domain.ConvertDBCompany(dbCompany), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) error {
|
||||||
|
fmt.Printf("company %v\n", company)
|
||||||
|
err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Store) DeleteCompany(ctx context.Context, id int64) error {
|
func (s *Store) DeleteCompany(ctx context.Context, id int64) error {
|
||||||
return s.queries.DeleteCompany(ctx, id)
|
return s.queries.DeleteCompany(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,71 @@ func (s *Store) GetAllEnetpulsePreoddsBettingOffers(ctx context.Context) ([]doma
|
||||||
return offers, nil
|
return offers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetFixturesWithPreodds(ctx context.Context) ([]domain.EnetpulseFixtureWithPreodds, error) {
|
||||||
|
dbRows, err := s.queries.GetFixturesWithPreodds(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use a map to group preodds by fixture
|
||||||
|
fixtureMap := make(map[string]*domain.EnetpulseFixtureWithPreodds)
|
||||||
|
|
||||||
|
for _, row := range dbRows {
|
||||||
|
// If fixture not yet in map, add it
|
||||||
|
if _, exists := fixtureMap[row.FixtureID]; !exists {
|
||||||
|
fixtureMap[row.FixtureID] = &domain.EnetpulseFixtureWithPreodds{
|
||||||
|
FixtureID: row.FixtureID,
|
||||||
|
FixtureApiID: row.FixtureID, // same alias used in query
|
||||||
|
FixtureName: row.FixtureName,
|
||||||
|
SportFk: row.SportFk,
|
||||||
|
TournamentFk: row.TournamentFk.String,
|
||||||
|
TournamentTemplateFk: row.TournamentTemplateFk.String,
|
||||||
|
TournamentStageFk: row.TournamentStageFk.String,
|
||||||
|
StartDate: row.StartDate.Time,
|
||||||
|
StatusType: row.StatusType.String,
|
||||||
|
StatusDescFk: row.StatusDescFk.String,
|
||||||
|
RoundTypeFk: row.RoundTypeFk.String,
|
||||||
|
UpdatesCount: row.FixtureUpdatesCount.Int32,
|
||||||
|
LastUpdatedAt: row.FixtureLastUpdatedAt.Time,
|
||||||
|
CreatedAt: row.FixtureCreatedAt.Time,
|
||||||
|
UpdatedAt: row.FixtureUpdatedAt.Time,
|
||||||
|
Preodds: []domain.EnetpulsePreodds{}, // initialize slice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add preodds only if it exists (avoid NULL rows)
|
||||||
|
if row.PreoddsDbID.Valid {
|
||||||
|
preodds := domain.EnetpulsePreodds{
|
||||||
|
ID: row.PreoddsDbID.Int64,
|
||||||
|
PreoddsID: row.PreoddsID.String,
|
||||||
|
EventFK: row.EventFk.Int64,
|
||||||
|
OutcomeTypeFK: row.OutcomeTypeFk.Int32,
|
||||||
|
OutcomeScopeFK: row.OutcomeScopeFk.Int32,
|
||||||
|
OutcomeSubtypeFK: row.OutcomeSubtypeFk.Int32,
|
||||||
|
EventParticipantNumber: row.EventParticipantNumber.Int32,
|
||||||
|
IParam: row.Iparam.String,
|
||||||
|
IParam2: row.Iparam2.String,
|
||||||
|
DParam: row.Dparam.String,
|
||||||
|
DParam2: row.Dparam2.String,
|
||||||
|
SParam: row.Sparam.String,
|
||||||
|
UpdatesCount: row.PreoddsUpdatesCount.Int32,
|
||||||
|
LastUpdatedAt: row.PreoddsLastUpdatedAt.Time,
|
||||||
|
CreatedAt: row.PreoddsCreatedAt.Time,
|
||||||
|
UpdatedAt: row.PreoddsUpdatedAt.Time,
|
||||||
|
}
|
||||||
|
fixtureMap[row.FixtureID].Preodds = append(fixtureMap[row.FixtureID].Preodds, preodds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flatten the map into a slice
|
||||||
|
result := make([]domain.EnetpulseFixtureWithPreodds, 0, len(fixtureMap))
|
||||||
|
for _, f := range fixtureMap {
|
||||||
|
result = append(result, *f)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// func ConvertCreateEnetpulseTournamentStage(stage domain.CreateEnetpulseTournamentStage) dbgen.EnetpulseTournamentStage {
|
// func ConvertCreateEnetpulseTournamentStage(stage domain.CreateEnetpulseTournamentStage) dbgen.EnetpulseTournamentStage {
|
||||||
// return dbgen.EnetpulseTournamentStage{
|
// return dbgen.EnetpulseTournamentStage{
|
||||||
// StageID: stage.StageID,
|
// StageID: stage.StageID,
|
||||||
|
|
@ -356,14 +421,14 @@ func ConvertDBEnetpulseFixture(dbF dbgen.EnetpulseFixture) domain.EnetpulseFixtu
|
||||||
TournamentTemplateName: dbF.TournamentTemplateName.String,
|
TournamentTemplateName: dbF.TournamentTemplateName.String,
|
||||||
SportName: dbF.SportName.String,
|
SportName: dbF.SportName.String,
|
||||||
Gender: dbF.Gender.String,
|
Gender: dbF.Gender.String,
|
||||||
StartDate: dbF.StartDate.Time,
|
StartDate: dbF.StartDate.Time.String(),
|
||||||
StatusType: dbF.StatusType.String,
|
StatusType: dbF.StatusType.String,
|
||||||
StatusDescFK: dbF.StatusDescFk.String,
|
StatusDescFK: dbF.StatusDescFk.String,
|
||||||
RoundTypeFK: dbF.RoundTypeFk.String,
|
RoundTypeFK: dbF.RoundTypeFk.String,
|
||||||
UpdatesCount: int(dbF.UpdatesCount.Int32),
|
UpdatesCount: fmt.Sprintf("%v", dbF.UpdatesCount),
|
||||||
LastUpdatedAt: dbF.LastUpdatedAt.Time,
|
LastUpdatedAt: dbF.LastUpdatedAt.Time.String(),
|
||||||
CreatedAt: dbF.CreatedAt.Time,
|
// CreatedAt: dbF.CreatedAt.Time,
|
||||||
UpdatedAt: dbF.UpdatedAt.Time,
|
// UpdatedAt: dbF.UpdatedAt.Time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -672,17 +737,17 @@ func ConvertCreateEnetpulsePreodds(p domain.CreateEnetpulsePreodds) (dbgen.Creat
|
||||||
func ConvertDBEnetpulsePreodds(dbP dbgen.EnetpulsePreodd) domain.EnetpulsePreodds {
|
func ConvertDBEnetpulsePreodds(dbP dbgen.EnetpulsePreodd) domain.EnetpulsePreodds {
|
||||||
return domain.EnetpulsePreodds{
|
return domain.EnetpulsePreodds{
|
||||||
PreoddsID: dbP.PreoddsID,
|
PreoddsID: dbP.PreoddsID,
|
||||||
EventFK: fmt.Sprintf("%v", dbP.EventFk),
|
EventFK: dbP.EventFk,
|
||||||
OutcomeTypeFK: fmt.Sprintf("%v", dbP.OutcomeTypeFk),
|
OutcomeTypeFK: dbP.OutcomeTypeFk.Int32,
|
||||||
OutcomeScopeFK: fmt.Sprintf("%v", dbP.OutcomeScopeFk),
|
OutcomeScopeFK: dbP.OutcomeScopeFk.Int32,
|
||||||
OutcomeSubtypeFK: fmt.Sprintf("%v", dbP.OutcomeSubtypeFk),
|
OutcomeSubtypeFK: dbP.OutcomeSubtypeFk.Int32,
|
||||||
EventParticipantNumber: int(dbP.EventParticipantNumber.Int32),
|
EventParticipantNumber: dbP.EventParticipantNumber.Int32,
|
||||||
IParam: dbP.Iparam.String,
|
IParam: dbP.Iparam.String,
|
||||||
IParam2: dbP.Iparam2.String,
|
IParam2: dbP.Iparam2.String,
|
||||||
DParam: dbP.Dparam.String,
|
DParam: dbP.Dparam.String,
|
||||||
DParam2: dbP.Dparam2.String,
|
DParam2: dbP.Dparam2.String,
|
||||||
SParam: dbP.Sparam.String,
|
SParam: dbP.Sparam.String,
|
||||||
UpdatesCount: int(dbP.UpdatesCount.Int32),
|
UpdatesCount: dbP.UpdatesCount.Int32,
|
||||||
LastUpdatedAt: dbP.LastUpdatedAt.Time,
|
LastUpdatedAt: dbP.LastUpdatedAt.Time,
|
||||||
CreatedAt: dbP.CreatedAt.Time,
|
CreatedAt: dbP.CreatedAt.Time,
|
||||||
UpdatedAt: dbP.UpdatedAt.Time,
|
UpdatedAt: dbP.UpdatedAt.Time,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package repository
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
|
|
||||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
|
@ -23,11 +22,15 @@ func (s *Store) GetLiveEventIDs(ctx context.Context) ([]int64, error) {
|
||||||
func (s *Store) GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
func (s *Store) GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
||||||
|
|
||||||
events, err := s.queries.GetAllEvents(ctx, dbgen.GetAllEventsParams{
|
events, err := s.queries.GetAllEvents(ctx, dbgen.GetAllEventsParams{
|
||||||
LeagueID: filter.LeagueID.ToPG(),
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
SportID: filter.SportID.ToPG(),
|
SportID: filter.SportID.ToPG(),
|
||||||
Query: filter.Query.ToPG(),
|
Query: filter.Query.ToPG(),
|
||||||
Limit: filter.Limit.ToPG(),
|
Limit: filter.Limit.ToPG(),
|
||||||
Offset: filter.Offset.ToPG(),
|
Offset: pgtype.Int4{
|
||||||
|
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||||
|
Valid: filter.Offset.Valid,
|
||||||
|
},
|
||||||
|
|
||||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
LastStartTime: filter.LastStartTime.ToPG(),
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
CountryCode: filter.CountryCode.ToPG(),
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
|
@ -55,18 +58,20 @@ func (s *Store) GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
return domain.ConvertDBEvents(events), totalCount, nil
|
||||||
return domain.ConvertDBEvents(events), int64(numberOfPages), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
||||||
events, err := s.queries.GetEventsWithSettings(ctx, dbgen.GetEventsWithSettingsParams{
|
events, err := s.queries.GetEventsWithSettings(ctx, dbgen.GetEventsWithSettingsParams{
|
||||||
CompanyID: companyID,
|
CompanyID: companyID,
|
||||||
LeagueID: filter.LeagueID.ToPG(),
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
SportID: filter.SportID.ToPG(),
|
SportID: filter.SportID.ToPG(),
|
||||||
Query: filter.Query.ToPG(),
|
Query: filter.Query.ToPG(),
|
||||||
Limit: filter.Limit.ToPG(),
|
Limit: filter.Limit.ToPG(),
|
||||||
Offset: filter.Offset.ToPG(),
|
Offset: pgtype.Int4{
|
||||||
|
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||||
|
Valid: filter.Offset.Valid,
|
||||||
|
},
|
||||||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
LastStartTime: filter.LastStartTime.ToPG(),
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
CountryCode: filter.CountryCode.ToPG(),
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
|
@ -99,8 +104,6 @@ func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filt
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
|
||||||
|
|
||||||
result := make([]domain.EventWithSettings, len(events))
|
result := make([]domain.EventWithSettings, len(events))
|
||||||
|
|
||||||
for i, event := range events {
|
for i, event := range events {
|
||||||
|
|
@ -123,6 +126,9 @@ func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filt
|
||||||
StartTime: event.StartTime.Time.UTC(),
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
Source: domain.EventSource(event.Source),
|
Source: domain.EventSource(event.Source),
|
||||||
Status: domain.EventStatus(event.Status),
|
Status: domain.EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOutcomes,
|
||||||
|
SourceEventID: event.SourceEventID,
|
||||||
|
WinningUpperLimit: event.WinningUpperLimit,
|
||||||
IsFeatured: event.IsFeatured,
|
IsFeatured: event.IsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
IsActive: event.IsActive,
|
IsActive: event.IsActive,
|
||||||
|
|
@ -155,7 +161,7 @@ func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, int64(numberOfPages), nil
|
return result, totalCount, nil
|
||||||
}
|
}
|
||||||
func (s *Store) GetEventByID(ctx context.Context, ID int64) (domain.BaseEvent, error) {
|
func (s *Store) GetEventByID(ctx context.Context, ID int64) (domain.BaseEvent, error) {
|
||||||
event, err := s.queries.GetEventByID(ctx, ID)
|
event, err := s.queries.GetEventByID(ctx, ID)
|
||||||
|
|
@ -204,6 +210,9 @@ func (s *Store) GetEventWithSettingByID(ctx context.Context, ID int64, companyID
|
||||||
StartTime: event.StartTime.Time.UTC(),
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
Source: domain.EventSource(event.Source),
|
Source: domain.EventSource(event.Source),
|
||||||
Status: domain.EventStatus(event.Status),
|
Status: domain.EventStatus(event.Status),
|
||||||
|
TotalOddOutcomes: event.TotalOutcomes,
|
||||||
|
SourceEventID: event.SourceEventID,
|
||||||
|
WinningUpperLimit: event.WinningUpperLimit,
|
||||||
IsFeatured: event.IsFeatured,
|
IsFeatured: event.IsFeatured,
|
||||||
IsMonitored: event.IsMonitored,
|
IsMonitored: event.IsMonitored,
|
||||||
IsActive: event.IsActive,
|
IsActive: event.IsActive,
|
||||||
|
|
@ -281,10 +290,13 @@ func (s *Store) UpdateEventMonitored(ctx context.Context, eventID int64, IsMonit
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
func (s *Store) UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error {
|
||||||
return s.queries.SaveEventSettings(ctx, domain.ConvertUpdateEventSettings(event))
|
return s.queries.SaveTenantEventSettings(ctx, domain.ConvertUpdateTenantEventSettings(event))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error {
|
||||||
|
return s.queries.UpdateGlobalEventSettings(ctx, domain.ConvertUpdateGlobalEventSettings(event))
|
||||||
|
}
|
||||||
func (s *Store) DeleteEvent(ctx context.Context, eventID int64) error {
|
func (s *Store) DeleteEvent(ctx context.Context, eventID int64) error {
|
||||||
err := s.queries.DeleteEvent(ctx, eventID)
|
err := s.queries.DeleteEvent(ctx, eventID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ func (s *Store) SaveLeague(ctx context.Context, league domain.CreateLeague) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
||||||
return s.queries.InsertLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings))
|
return s.queries.SaveLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague,int64, error) {
|
||||||
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
||||||
Query: filter.Query.ToPG(),
|
Query: filter.Query.ToPG(),
|
||||||
CountryCode: filter.CountryCode.ToPG(),
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
|
@ -31,10 +31,17 @@ func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) (
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.ConvertDBBaseLeagues(l), nil
|
total, err := s.queries.GetTotalLeagues(ctx, dbgen.GetTotalLeaguesParams{
|
||||||
|
Query: filter.Query.ToPG(),
|
||||||
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
SportID: filter.SportID.ToPG(),
|
||||||
|
IsActive: filter.IsActive.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
return domain.ConvertDBBaseLeagues(l), total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error) {
|
func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error) {
|
||||||
|
|
@ -85,3 +92,7 @@ func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64, companyI
|
||||||
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||||
return s.queries.UpdateLeague(ctx, domain.ConvertUpdateLeague(league))
|
return s.queries.UpdateLeague(ctx, domain.ConvertUpdateLeague(league))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateGlobalLeagueSettings(ctx context.Context, league domain.UpdateGlobalLeagueSettings) error {
|
||||||
|
return s.queries.UpdateGlobalLeagueSettings(ctx, domain.ConvertUpdateGlobalLeagueSetting(league))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@ import (
|
||||||
type NotificationRepository interface {
|
type NotificationRepository interface {
|
||||||
CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error)
|
CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error)
|
||||||
UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error)
|
UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error)
|
||||||
GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error)
|
GetUserNotifications(ctx context.Context, recipientID int64, limit, offset int) ([]domain.Notification, int64, error)
|
||||||
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
|
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
|
||||||
ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error)
|
ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error)
|
||||||
CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
|
CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
|
||||||
GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
|
GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
|
||||||
GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error)
|
GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error)
|
||||||
|
DeleteOldNotifications(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
|
@ -69,6 +70,8 @@ func (r *Repository) CreateNotification(ctx context.Context, notification *domai
|
||||||
Payload: marshalPayload(notification.Payload),
|
Payload: marshalPayload(notification.Payload),
|
||||||
Priority: priority,
|
Priority: priority,
|
||||||
Timestamp: pgtype.Timestamptz{Time: notification.Timestamp, Valid: true},
|
Timestamp: pgtype.Timestamptz{Time: notification.Timestamp, Valid: true},
|
||||||
|
Expires: pgtype.Timestamptz{Time: notification.Expires, Valid: true},
|
||||||
|
Img: pgtype.Text{String: notification.Image, Valid: notification.Image != ""},
|
||||||
Metadata: notification.Metadata,
|
Metadata: notification.Metadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +116,7 @@ func (r *Repository) GetUserNotifications(ctx context.Context, recipientID int64
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []domain.Notification = make([]domain.Notification, 0, len(dbNotifications))
|
var result []domain.Notification = make([]domain.Notification, 0, len(dbNotifications))
|
||||||
for _, dbNotif := range dbNotifications {
|
for _, dbNotif := range dbNotifications {
|
||||||
domainNotif := r.mapDBToDomain(&dbNotif)
|
domainNotif := r.mapDBToDomain(&dbNotif)
|
||||||
|
|
@ -160,6 +163,10 @@ func (r *Repository) ListRecipientIDs(ctx context.Context, receiver domain.Notif
|
||||||
return r.store.queries.ListRecipientIDsByReceiver(ctx, string(receiver))
|
return r.store.queries.ListRecipientIDsByReceiver(ctx, string(receiver))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Repository) DeleteOldNotifications(ctx context.Context) error {
|
||||||
|
return s.store.queries.DeleteOldNotifications(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
|
func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
|
||||||
var errorSeverity domain.NotificationErrorSeverity
|
var errorSeverity domain.NotificationErrorSeverity
|
||||||
if dbNotif.ErrorSeverity.Valid {
|
if dbNotif.ErrorSeverity.Valid {
|
||||||
|
|
@ -199,6 +206,8 @@ func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notifica
|
||||||
Payload: payload,
|
Payload: payload,
|
||||||
Priority: priority,
|
Priority: priority,
|
||||||
Timestamp: dbNotif.Timestamp.Time,
|
Timestamp: dbNotif.Timestamp.Time,
|
||||||
|
Expires: dbNotif.Expires.Time,
|
||||||
|
Image: dbNotif.Img.String,
|
||||||
Metadata: dbNotif.Metadata,
|
Metadata: dbNotif.Metadata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,16 +180,17 @@ func (s *Store) GetOddsWithSettingsByMarketID(ctx context.Context, marketID int6
|
||||||
}
|
}
|
||||||
|
|
||||||
converted := domain.OddMarketWithSettings{
|
converted := domain.OddMarketWithSettings{
|
||||||
ID: odds.ID,
|
ID: odds.ID,
|
||||||
EventID: odds.EventID,
|
EventID: odds.EventID,
|
||||||
MarketType: odds.MarketType,
|
MarketType: odds.MarketType,
|
||||||
MarketName: odds.MarketName,
|
MarketName: odds.MarketName,
|
||||||
MarketCategory: odds.MarketCategory,
|
MarketCategory: odds.MarketCategory,
|
||||||
MarketID: odds.MarketID,
|
MarketID: odds.MarketID,
|
||||||
RawOdds: rawOdds,
|
NumberOfOutcomes: odds.NumberOfOutcomes,
|
||||||
FetchedAt: odds.FetchedAt.Time,
|
RawOdds: rawOdds,
|
||||||
ExpiresAt: odds.ExpiresAt.Time,
|
FetchedAt: odds.FetchedAt.Time,
|
||||||
IsActive: odds.IsActive,
|
ExpiresAt: odds.ExpiresAt.Time,
|
||||||
|
IsActive: odds.IsActive,
|
||||||
}
|
}
|
||||||
return converted, nil
|
return converted, nil
|
||||||
}
|
}
|
||||||
|
|
@ -221,16 +222,17 @@ func (s *Store) GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID
|
||||||
}
|
}
|
||||||
|
|
||||||
converted := domain.OddMarketWithSettings{
|
converted := domain.OddMarketWithSettings{
|
||||||
ID: odds.ID,
|
ID: odds.ID,
|
||||||
EventID: odds.EventID,
|
EventID: odds.EventID,
|
||||||
MarketType: odds.MarketType,
|
MarketType: odds.MarketType,
|
||||||
MarketName: odds.MarketName,
|
MarketName: odds.MarketName,
|
||||||
MarketCategory: odds.MarketCategory,
|
MarketCategory: odds.MarketCategory,
|
||||||
MarketID: odds.MarketID,
|
MarketID: odds.MarketID,
|
||||||
RawOdds: rawOdds,
|
NumberOfOutcomes: odds.NumberOfOutcomes,
|
||||||
FetchedAt: odds.FetchedAt.Time,
|
RawOdds: rawOdds,
|
||||||
ExpiresAt: odds.ExpiresAt.Time,
|
FetchedAt: odds.FetchedAt.Time,
|
||||||
IsActive: odds.IsActive,
|
ExpiresAt: odds.ExpiresAt.Time,
|
||||||
|
IsActive: odds.IsActive,
|
||||||
}
|
}
|
||||||
|
|
||||||
return converted, nil
|
return converted, nil
|
||||||
|
|
@ -239,17 +241,11 @@ func (s *Store) GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID
|
||||||
func (s *Store) GetOddsByEventID(ctx context.Context, eventID int64, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
func (s *Store) GetOddsByEventID(ctx context.Context, eventID int64, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||||
odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{
|
odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
|
Status: filter.Status.ToPG(),
|
||||||
|
IsLive: filter.IsLive.ToPG(),
|
||||||
Limit: filter.Limit.ToPG(),
|
Limit: filter.Limit.ToPG(),
|
||||||
Offset: filter.Offset.ToPG(),
|
Offset: filter.Offset.ToPG(),
|
||||||
IsLive: pgtype.Bool{
|
Source: pgtype.Text{},
|
||||||
Bool: false,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
Status: pgtype.Text{
|
|
||||||
String: string(domain.STATUS_PENDING),
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
Source: pgtype.Text{},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -293,16 +289,17 @@ func (s *Store) GetOddsWithSettingsByEventID(ctx context.Context, eventID int64,
|
||||||
}
|
}
|
||||||
|
|
||||||
result[i] = domain.OddMarketWithSettings{
|
result[i] = domain.OddMarketWithSettings{
|
||||||
ID: o.ID,
|
ID: o.ID,
|
||||||
EventID: o.EventID,
|
EventID: o.EventID,
|
||||||
MarketType: o.MarketType,
|
MarketType: o.MarketType,
|
||||||
MarketName: o.MarketName,
|
MarketName: o.MarketName,
|
||||||
MarketCategory: o.MarketCategory,
|
MarketCategory: o.MarketCategory,
|
||||||
MarketID: o.MarketID,
|
MarketID: o.MarketID,
|
||||||
RawOdds: rawOdds,
|
NumberOfOutcomes: o.NumberOfOutcomes,
|
||||||
FetchedAt: o.FetchedAt.Time,
|
RawOdds: rawOdds,
|
||||||
ExpiresAt: o.ExpiresAt.Time,
|
FetchedAt: o.FetchedAt.Time,
|
||||||
IsActive: o.IsActive,
|
ExpiresAt: o.ExpiresAt.Time,
|
||||||
|
IsActive: o.IsActive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,3 +319,21 @@ func (s *Store) SaveOddsSetting(ctx context.Context, odd domain.CreateOddMarketS
|
||||||
}
|
}
|
||||||
return s.queries.SaveOddSettings(ctx, res)
|
return s.queries.SaveOddSettings(ctx, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateGlobalOddsSetting(ctx context.Context, odd domain.UpdateGlobalOddMarketSettings) error {
|
||||||
|
return s.queries.UpdateGlobalOddsSetting(ctx, dbgen.UpdateGlobalOddsSettingParams{
|
||||||
|
ID: odd.OddMarketID,
|
||||||
|
DefaultIsActive: odd.IsActive.ToPG(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error {
|
||||||
|
return s.queries.DeleteAllCompanyOddsSetting(ctx, companyID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, companyID int64, oddMarketID int64) error {
|
||||||
|
return s.queries.DeleteCompanyOddsSettingByOddMarketID(ctx, dbgen.DeleteCompanyOddsSettingByOddMarketIDParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
OddsMarketID: oddMarketID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,14 @@ import (
|
||||||
|
|
||||||
func convertRaffleOutcome(raffle dbgen.Raffle) domain.Raffle {
|
func convertRaffleOutcome(raffle dbgen.Raffle) domain.Raffle {
|
||||||
return domain.Raffle{
|
return domain.Raffle{
|
||||||
ID: raffle.ID,
|
ID: raffle.ID,
|
||||||
CompanyID: raffle.CompanyID,
|
CompanyID: raffle.CompanyID,
|
||||||
Name: raffle.Name,
|
Name: raffle.Name,
|
||||||
CreatedAt: raffle.CreatedAt.Time,
|
CreatedAt: raffle.CreatedAt.Time,
|
||||||
ExpiresAt: raffle.ExpiresAt.Time,
|
ExpiresAt: raffle.ExpiresAt.Time,
|
||||||
Type: raffle.Type,
|
TicketLimit: raffle.TicketLimit,
|
||||||
Status: raffle.Status,
|
Type: raffle.Type,
|
||||||
|
Status: raffle.Status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +49,8 @@ func convertCreateRaffle(raffle domain.CreateRaffle) dbgen.CreateRaffleParams {
|
||||||
Time: *raffle.ExpiresAt,
|
Time: *raffle.ExpiresAt,
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
Type: raffle.Type,
|
TicketLimit: raffle.TicketLimit,
|
||||||
|
Type: raffle.Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,3 +193,18 @@ func (s *Store) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32,
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error) {
|
||||||
|
return s.queries.GetRaffleTicketLimit(ctx, raffleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error) {
|
||||||
|
return s.queries.GetRaffleTicketCount(ctx, dbgen.GetRaffleTicketCountParams{
|
||||||
|
RaffleID: raffleID,
|
||||||
|
UserID: userID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) {
|
||||||
|
return s.queries.CheckSportRaffleHasFilter(ctx, raffleID)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ func convertDBShopBetDetail(bet dbgen.ShopBetDetail) domain.ShopBetDetail {
|
||||||
CompanyID: bet.CompanyID,
|
CompanyID: bet.CompanyID,
|
||||||
FullName: bet.CustomerFullName,
|
FullName: bet.CustomerFullName,
|
||||||
PhoneNumber: bet.CustomerPhoneNumber,
|
PhoneNumber: bet.CustomerPhoneNumber,
|
||||||
|
FastCode: bet.FastCode,
|
||||||
CashoutID: bet.CashoutID,
|
CashoutID: bet.CashoutID,
|
||||||
CashedOut: bet.CashedOut,
|
CashedOut: bet.CashedOut,
|
||||||
BetID: bet.BetID,
|
BetID: bet.BetID,
|
||||||
|
|
@ -63,7 +64,7 @@ func (s *Store) CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (do
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.ShopBet{}, err
|
return domain.ShopBet{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBShopBet(newShopBet), err
|
return convertDBShopBet(newShopBet), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +109,7 @@ func (s *Store) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDet
|
||||||
fmt.Printf("GetShopBetByID Repo BetID %d err %v \n", id, err.Error())
|
fmt.Printf("GetShopBetByID Repo BetID %d err %v \n", id, err.Error())
|
||||||
return domain.ShopBetDetail{}, err
|
return domain.ShopBetDetail{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBShopBetDetail(bet), nil
|
return convertDBShopBetDetail(bet), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ func (s *Store) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]do
|
||||||
Valid: filter.PageSize.Valid,
|
Valid: filter.PageSize.Valid,
|
||||||
},
|
},
|
||||||
Offset: pgtype.Int4{
|
Offset: pgtype.Int4{
|
||||||
Int32: int32(filter.Page.Value),
|
Int32: int32(filter.Page.Value * filter.PageSize.Value),
|
||||||
Valid: filter.Page.Valid,
|
Valid: filter.Page.Valid,
|
||||||
},
|
},
|
||||||
Query: pgtype.Text{
|
Query: pgtype.Text{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
|
@ -30,7 +29,7 @@ type VirtualGameRepository interface {
|
||||||
RemoveFavoriteGame(ctx context.Context, userID, gameID int64) error
|
RemoveFavoriteGame(ctx context.Context, userID, gameID int64) error
|
||||||
ListFavoriteGames(ctx context.Context, userID int64) ([]int64, error)
|
ListFavoriteGames(ctx context.Context, userID int64) ([]int64, error)
|
||||||
|
|
||||||
GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
// GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
||||||
GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error)
|
GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error)
|
||||||
CreateVirtualGameHistory(ctx context.Context, his *domain.VirtualGameHistory) error
|
CreateVirtualGameHistory(ctx context.Context, his *domain.VirtualGameHistory) error
|
||||||
|
|
||||||
|
|
@ -255,36 +254,36 @@ func (r *VirtualGameRepo) UpdateVirtualGameTransactionStatus(ctx context.Context
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
|
// func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
|
||||||
query := `SELECT
|
// query := `SELECT
|
||||||
COUNT(*) as total,
|
// COUNT(*) as total,
|
||||||
COUNT(CASE WHEN is_active = true THEN 1 END) as active,
|
// COUNT(CASE WHEN is_active = true THEN 1 END) as active,
|
||||||
COUNT(CASE WHEN is_active = false THEN 1 END) as inactive
|
// COUNT(CASE WHEN is_active = false THEN 1 END) as inactive
|
||||||
FROM virtual_games`
|
// FROM virtual_games`
|
||||||
|
|
||||||
args := []interface{}{}
|
// args := []interface{}{}
|
||||||
argPos := 1
|
// argPos := 1
|
||||||
|
|
||||||
// Add filters if provided
|
// // Add filters if provided
|
||||||
if filter.StartTime.Valid {
|
// if filter.StartTime.Valid {
|
||||||
query += fmt.Sprintf(" WHERE created_at >= $%d", argPos)
|
// query += fmt.Sprintf(" WHERE created_at >= $%d", argPos)
|
||||||
args = append(args, filter.StartTime.Value)
|
// args = append(args, filter.StartTime.Value)
|
||||||
argPos++
|
// argPos++
|
||||||
}
|
// }
|
||||||
if filter.EndTime.Valid {
|
// if filter.EndTime.Valid {
|
||||||
query += fmt.Sprintf(" AND created_at <= $%d", argPos)
|
// query += fmt.Sprintf(" AND created_at <= $%d", argPos)
|
||||||
args = append(args, filter.EndTime.Value)
|
// args = append(args, filter.EndTime.Value)
|
||||||
argPos++
|
// argPos++
|
||||||
}
|
// }
|
||||||
|
|
||||||
row := r.store.conn.QueryRow(ctx, query, args...)
|
// row := r.store.conn.QueryRow(ctx, query, args...)
|
||||||
err = row.Scan(&total, &active, &inactive)
|
// err = row.Scan(&total, &active, &inactive)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return 0, 0, 0, fmt.Errorf("failed to get game counts: %w", err)
|
// return 0, 0, 0, fmt.Errorf("failed to get game counts: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return total, active, inactive, nil
|
// return total, active, inactive, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (r *VirtualGameRepo) GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error) {
|
func (r *VirtualGameRepo) GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error) {
|
||||||
query := `SELECT game_id FROM virtual_game_histories WHERE user_id = $1 AND transaction_type = 'BET' ORDER BY created_at DESC LIMIT 100`
|
query := `SELECT game_id FROM virtual_game_histories WHERE user_id = $1 AND transaction_type = 'BET' ORDER BY created_at DESC LIMIT 100`
|
||||||
|
|
@ -315,4 +314,3 @@ func (r *VirtualGameRepo) ListAllVirtualGames(ctx context.Context, arg dbgen.Get
|
||||||
func (r *VirtualGameRepo) RemoveAllVirtualGames(ctx context.Context) error {
|
func (r *VirtualGameRepo) RemoveAllVirtualGames(ctx context.Context) error {
|
||||||
return r.store.queries.DeleteAllVirtualGames(ctx)
|
return r.store.queries.DeleteAllVirtualGames(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ func convertDBGetCustomerWallet(customerWallet dbgen.CustomerWalletDetail) domai
|
||||||
func (s *Store) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
|
func (s *Store) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
|
||||||
newWallet, err := s.queries.CreateWallet(ctx, convertCreateWallet(wallet))
|
newWallet, err := s.queries.CreateWallet(ctx, convertCreateWallet(wallet))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if IsUniqueViolation(err) {
|
||||||
|
return domain.Wallet{}, domain.ErrWalletIDDuplicate
|
||||||
|
}
|
||||||
return domain.Wallet{}, err
|
return domain.Wallet{}, err
|
||||||
}
|
}
|
||||||
return convertDBWallet(newWallet), nil
|
return convertDBWallet(newWallet), nil
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ func (s *Service) SendAdminErrorNotification(ctx context.Context, betID int64, s
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
for _, channel := range []domain.DeliveryChannel{
|
for _, channel := range []domain.DeliveryChannel{
|
||||||
domain.DeliveryChannelInApp,
|
domain.DeliveryChannelInApp,
|
||||||
domain.DeliveryChannelEmail,
|
// domain.DeliveryChannelEmail,
|
||||||
} {
|
} {
|
||||||
n := newBetResultNotification(user.ID, domain.NotificationLevelError, channel, headline, message, map[string]any{
|
n := newBetResultNotification(user.ID, domain.NotificationLevelError, channel, headline, message, map[string]any{
|
||||||
"status": status,
|
"status": status,
|
||||||
|
|
@ -247,7 +247,7 @@ func (s *Service) SendAdminErrorNotification(ctx context.Context, betID int64, s
|
||||||
}
|
}
|
||||||
func (s *Service) SendAdminLargeBetNotification(ctx context.Context, betID int64, totalWinnings float32, extra string, companyID int64) error {
|
func (s *Service) SendAdminLargeBetNotification(ctx context.Context, betID int64, totalWinnings float32, extra string, companyID int64) error {
|
||||||
|
|
||||||
headline := fmt.Sprintf("SYSTEM WARNING: High Risk Bet", betID, totalWinnings)
|
headline := "SYSTEM WARNING: High Risk Bet"
|
||||||
message := fmt.Sprintf("Bet #%d has been created with %v payout", betID, totalWinnings)
|
message := fmt.Sprintf("Bet #%d has been created with %v payout", betID, totalWinnings)
|
||||||
|
|
||||||
super_admin_users, _, err := s.userSvc.GetAllUsers(ctx, domain.UserFilter{
|
super_admin_users, _, err := s.userSvc.GetAllUsers(ctx, domain.UserFilter{
|
||||||
|
|
@ -283,7 +283,7 @@ func (s *Service) SendAdminLargeBetNotification(ctx context.Context, betID int64
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
for _, channel := range []domain.DeliveryChannel{
|
for _, channel := range []domain.DeliveryChannel{
|
||||||
domain.DeliveryChannelInApp,
|
domain.DeliveryChannelInApp,
|
||||||
domain.DeliveryChannelEmail,
|
// domain.DeliveryChannelEmail,
|
||||||
} {
|
} {
|
||||||
raw, _ := json.Marshal(map[string]any{
|
raw, _ := json.Marshal(map[string]any{
|
||||||
"winnings": totalWinnings,
|
"winnings": totalWinnings,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ type BetStore interface {
|
||||||
GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, int64, error)
|
GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, int64, error)
|
||||||
GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error)
|
GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error)
|
||||||
GetBetByFastCode(ctx context.Context, fastcode string) (domain.GetBet, error)
|
GetBetByFastCode(ctx context.Context, fastcode string) (domain.GetBet, error)
|
||||||
|
GetBetOutcomeViewByEventID(ctx context.Context, eventID int64, filter domain.BetOutcomeViewFilter) ([]domain.BetOutcomeViewRes, int64, error)
|
||||||
GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error)
|
GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error)
|
||||||
GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain.BetOutcome, error)
|
GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain.BetOutcome, error)
|
||||||
GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (int64, error)
|
GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (int64, error)
|
||||||
|
|
@ -25,7 +26,8 @@ type BetStore interface {
|
||||||
UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
|
UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
|
||||||
UpdateBetOutcomeStatusByBetID(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
|
UpdateBetOutcomeStatusByBetID(ctx context.Context, id int64, status domain.OutcomeStatus) (domain.BetOutcome, error)
|
||||||
UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error)
|
UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error)
|
||||||
|
UpdateBetOutcomeStatusForOddId(ctx context.Context, oddID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error)
|
||||||
|
BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) error
|
||||||
GetBetSummary(ctx context.Context, filter domain.ReportFilter) (
|
GetBetSummary(ctx context.Context, filter domain.ReportFilter) (
|
||||||
totalStakes domain.Currency,
|
totalStakes domain.Currency,
|
||||||
totalBets int64,
|
totalBets int64,
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,10 @@ var (
|
||||||
ErrGenerateRandomOutcome = errors.New("failed to generate any random outcome for events")
|
ErrGenerateRandomOutcome = errors.New("failed to generate any random outcome for events")
|
||||||
ErrOutcomesNotCompleted = errors.New("some bet outcomes are still pending")
|
ErrOutcomesNotCompleted = errors.New("some bet outcomes are still pending")
|
||||||
ErrEventHasBeenRemoved = errors.New("event has been removed")
|
ErrEventHasBeenRemoved = errors.New("event has been removed")
|
||||||
|
ErrEventHasBeenDisabled = errors.New("event has been disabled")
|
||||||
|
|
||||||
ErrEventHasNotEnded = errors.New("event has not ended yet")
|
ErrEventHasNotEnded = errors.New("event has not ended yet")
|
||||||
|
ErrOddHasBeenDisabled = errors.New("odd has been disabled")
|
||||||
ErrRawOddInvalid = errors.New("prematch Raw Odd is Invalid")
|
ErrRawOddInvalid = errors.New("prematch Raw Odd is Invalid")
|
||||||
ErrBranchIDRequired = errors.New("branch ID required for this role")
|
ErrBranchIDRequired = errors.New("branch ID required for this role")
|
||||||
ErrOutcomeLimit = errors.New("too many outcomes on a single bet")
|
ErrOutcomeLimit = errors.New("too many outcomes on a single bet")
|
||||||
|
|
@ -46,6 +48,8 @@ var (
|
||||||
ErrInvalidAmount = errors.New("invalid amount")
|
ErrInvalidAmount = errors.New("invalid amount")
|
||||||
ErrBetAmountTooHigh = errors.New("cannot create a bet with an amount above limit")
|
ErrBetAmountTooHigh = errors.New("cannot create a bet with an amount above limit")
|
||||||
ErrBetWinningTooHigh = errors.New("total Winnings over set limit")
|
ErrBetWinningTooHigh = errors.New("total Winnings over set limit")
|
||||||
|
|
||||||
|
ErrCompanyDeductedPercentInvalid = errors.New("invalid company deducted percentage")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
|
@ -106,10 +110,10 @@ func (s *Service) GenerateCashoutID() (string, error) {
|
||||||
return string(result), nil
|
return string(result), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketID int64, oddID int64) (domain.CreateBetOutcome, error) {
|
func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketID int64, oddID int64, companyID int64) (domain.CreateBetOutcome, error) {
|
||||||
oddIDStr := strconv.FormatInt(oddID, 10)
|
oddIDStr := strconv.FormatInt(oddID, 10)
|
||||||
|
|
||||||
event, err := s.eventSvc.GetEventByID(ctx, eventID)
|
event, err := s.eventSvc.GetEventWithSettingByID(ctx, eventID, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error("failed to fetch upcoming event by ID",
|
s.mongoLogger.Error("failed to fetch upcoming event by ID",
|
||||||
zap.Int64("event_id", eventID),
|
zap.Int64("event_id", eventID),
|
||||||
|
|
@ -118,6 +122,14 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
||||||
return domain.CreateBetOutcome{}, ErrEventHasBeenRemoved
|
return domain.CreateBetOutcome{}, ErrEventHasBeenRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !event.IsActive {
|
||||||
|
s.mongoLogger.Warn("attempting to create bet with disabled event",
|
||||||
|
zap.Int64("event_id", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return domain.CreateBetOutcome{}, ErrEventHasBeenDisabled
|
||||||
|
}
|
||||||
|
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
if event.StartTime.Before(currentTime) {
|
if event.StartTime.Before(currentTime) {
|
||||||
s.mongoLogger.Error("event has already started",
|
s.mongoLogger.Error("event has already started",
|
||||||
|
|
@ -128,7 +140,7 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
||||||
return domain.CreateBetOutcome{}, ErrEventHasNotEnded
|
return domain.CreateBetOutcome{}, ErrEventHasNotEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
odds, err := s.prematchSvc.GetOddsByMarketID(ctx, marketID, eventID)
|
odds, err := s.prematchSvc.GetOddsWithSettingsByMarketID(ctx, marketID, eventID, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error("failed to get raw odds by market ID",
|
s.mongoLogger.Error("failed to get raw odds by market ID",
|
||||||
zap.Int64("event_id", eventID),
|
zap.Int64("event_id", eventID),
|
||||||
|
|
@ -138,6 +150,15 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
||||||
return domain.CreateBetOutcome{}, err
|
return domain.CreateBetOutcome{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !odds.IsActive {
|
||||||
|
s.mongoLogger.Error("failed to get raw odds by market ID",
|
||||||
|
zap.Int64("event_id", eventID),
|
||||||
|
zap.Int64("market_id", marketID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return domain.CreateBetOutcome{}, ErrOddHasBeenDisabled
|
||||||
|
}
|
||||||
|
|
||||||
type rawOddType struct {
|
type rawOddType struct {
|
||||||
ID string
|
ID string
|
||||||
Name string
|
Name string
|
||||||
|
|
@ -255,7 +276,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
var totalOdds float32 = 1
|
var totalOdds float32 = 1
|
||||||
|
|
||||||
for _, outcomeReq := range req.Outcomes {
|
for _, outcomeReq := range req.Outcomes {
|
||||||
newOutcome, err := s.GenerateBetOutcome(ctx, outcomeReq.EventID, outcomeReq.MarketID, outcomeReq.OddID)
|
newOutcome, err := s.GenerateBetOutcome(ctx, outcomeReq.EventID, outcomeReq.MarketID, outcomeReq.OddID, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error("failed to generate outcome",
|
s.mongoLogger.Error("failed to generate outcome",
|
||||||
zap.Int64("event_id", outcomeReq.EventID),
|
zap.Int64("event_id", outcomeReq.EventID),
|
||||||
|
|
@ -303,8 +324,9 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
}
|
}
|
||||||
|
|
||||||
fastCode := helpers.GenerateFastCode()
|
fastCode := helpers.GenerateFastCode()
|
||||||
accumulator := calculateAccumulator(len(outcomes))
|
// accumulator := calculateAccumulator(len(outcomes))
|
||||||
amount := req.Amount + (req.Amount * accumulator)
|
// amount := req.Amount + (req.Amount * accumulator)
|
||||||
|
amount := req.Amount
|
||||||
|
|
||||||
newBet := domain.CreateBet{
|
newBet := domain.CreateBet{
|
||||||
Amount: domain.ToCurrency(amount),
|
Amount: domain.ToCurrency(amount),
|
||||||
|
|
@ -524,7 +546,27 @@ func (s *Service) DeductBetFromBranchWallet(ctx context.Context, amount float32,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if company.DeductedPercentage > 1 {
|
||||||
|
s.mongoLogger.Error("Invalid company deducted percentage",
|
||||||
|
zap.Int64("wallet_id", walletID),
|
||||||
|
zap.Float32("amount", company.DeductedPercentage),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return ErrCompanyDeductedPercentInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the amount that we take from a company/tenant when they
|
||||||
|
// create a bet. I.e. if its 5% (0.05), then thats the percentage we take every
|
||||||
deductedAmount := amount * company.DeductedPercentage
|
deductedAmount := amount * company.DeductedPercentage
|
||||||
|
|
||||||
|
if deductedAmount == 0 {
|
||||||
|
s.mongoLogger.Fatal("Amount",
|
||||||
|
zap.Int64("wallet_id", walletID),
|
||||||
|
zap.Float32("amount", deductedAmount),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
_, err = s.walletSvc.DeductFromWallet(ctx,
|
_, err = s.walletSvc.DeductFromWallet(ctx,
|
||||||
walletID, domain.ToCurrency(deductedAmount), domain.ValidInt64{
|
walletID, domain.ToCurrency(deductedAmount), domain.ValidInt64{
|
||||||
Value: userID,
|
Value: userID,
|
||||||
|
|
@ -848,6 +890,9 @@ func (s *Service) GetBetOutcomeByBetID(ctx context.Context, UserID int64) ([]dom
|
||||||
return s.betStore.GetBetOutcomeByBetID(ctx, UserID)
|
return s.betStore.GetBetOutcomeByBetID(ctx, UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetBetOutcomeViewByEventID(ctx context.Context, eventID int64, filter domain.BetOutcomeViewFilter) ([]domain.BetOutcomeViewRes, int64, error) {
|
||||||
|
return s.betStore.GetBetOutcomeViewByEventID(ctx, eventID, filter)
|
||||||
|
}
|
||||||
func (s *Service) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error) {
|
func (s *Service) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_filtered bool) ([]domain.BetOutcome, error) {
|
||||||
return s.betStore.GetBetOutcomeByEventID(ctx, eventID, is_filtered)
|
return s.betStore.GetBetOutcomeByEventID(ctx, eventID, is_filtered)
|
||||||
}
|
}
|
||||||
|
|
@ -1076,6 +1121,32 @@ func (s *Service) UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID in
|
||||||
return outcomes, nil
|
return outcomes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateBetOutcomeStatusForOddId(ctx context.Context, oddID int64, status domain.OutcomeStatus) ([]domain.BetOutcome, error) {
|
||||||
|
outcomes, err := s.betStore.UpdateBetOutcomeStatusForOddId(ctx, oddID, status)
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error("failed to update bet outcome status",
|
||||||
|
zap.Int64("oddID", oddID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return outcomes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) BulkUpdateBetOutcomeStatusForOddIds(ctx context.Context, oddID []int64, status domain.OutcomeStatus) error {
|
||||||
|
err := s.betStore.BulkUpdateBetOutcomeStatusForOddIds(ctx, oddID, status)
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error("failed to update bet outcome status by oddIds",
|
||||||
|
zap.Int64s("oddID", oddID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) SetBetToRemoved(ctx context.Context, id int64) error {
|
func (s *Service) SetBetToRemoved(ctx context.Context, id int64) error {
|
||||||
_, err := s.betStore.UpdateBetOutcomeStatusByBetID(ctx, id, domain.OUTCOME_STATUS_VOID)
|
_, err := s.betStore.UpdateBetOutcomeStatusByBetID(ctx, id, domain.OUTCOME_STATUS_VOID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type BranchStore interface {
|
||||||
GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error)
|
GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error)
|
||||||
GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error)
|
GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error)
|
||||||
GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error)
|
GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error)
|
||||||
SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error)
|
SearchBranchByName(ctx context.Context, name string, companyID domain.ValidInt64) ([]domain.BranchDetail, error)
|
||||||
UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error)
|
UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error)
|
||||||
DeleteBranch(ctx context.Context, id int64) error
|
DeleteBranch(ctx context.Context, id int64) error
|
||||||
CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
|
CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ func (s *Service) GetAllSupportedOperations(ctx context.Context) ([]domain.Suppo
|
||||||
return s.branchStore.GetAllSupportedOperations(ctx)
|
return s.branchStore.GetAllSupportedOperations(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error) {
|
func (s *Service) SearchBranchByName(ctx context.Context, name string, companyID domain.ValidInt64) ([]domain.BranchDetail, error) {
|
||||||
return s.branchStore.SearchBranchByName(ctx, name)
|
return s.branchStore.SearchBranchByName(ctx, name, companyID)
|
||||||
}
|
}
|
||||||
func (s *Service) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) {
|
func (s *Service) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) {
|
||||||
return s.branchStore.UpdateBranch(ctx, branch)
|
return s.branchStore.UpdateBranch(ctx, branch)
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ type CompanyStore interface {
|
||||||
GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error)
|
GetAllCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.GetCompany, error)
|
||||||
SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
|
SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
|
||||||
GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
|
GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
|
||||||
GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error)
|
GetCompanyBySlug(ctx context.Context, slug string) (domain.Company, error)
|
||||||
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (error)
|
||||||
DeleteCompany(ctx context.Context, id int64) error
|
DeleteCompany(ctx context.Context, id int64) error
|
||||||
|
|
||||||
GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,15 @@ func (s *Service) GetAllCompanies(ctx context.Context, filter domain.CompanyFilt
|
||||||
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) {
|
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) {
|
||||||
return s.companyStore.GetCompanyByID(ctx, id)
|
return s.companyStore.GetCompanyByID(ctx, id)
|
||||||
}
|
}
|
||||||
func (s *Service) GetCompanyIDBySlug(ctx context.Context, slug string) (int64, error){
|
func (s *Service) GetCompanyBySlug(ctx context.Context, slug string) (domain.Company, error) {
|
||||||
return s.companyStore.GetCompanyIDBySlug(ctx, slug)
|
return s.companyStore.GetCompanyBySlug(ctx, slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error) {
|
func (s *Service) SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error) {
|
||||||
return s.companyStore.SearchCompanyByName(ctx, name)
|
return s.companyStore.SearchCompanyByName(ctx, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
|
func (s *Service) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (error) {
|
||||||
return s.companyStore.UpdateCompany(ctx, company)
|
return s.companyStore.UpdateCompany(ctx, company)
|
||||||
}
|
}
|
||||||
func (s *Service) DeleteCompany(ctx context.Context, id int64) error {
|
func (s *Service) DeleteCompany(ctx context.Context, id int64) error {
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ func (s *Service) FetchAndStoreTournamentTemplates(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("✅ Successfully fetched and stored all tournament templates")
|
// fmt.Println("✅ Successfully fetched and stored all tournament templates")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,7 +367,7 @@ func (s *Service) FetchAndStoreTournamentStages(ctx context.Context) error {
|
||||||
for _, t := range tournaments {
|
for _, t := range tournaments {
|
||||||
// Compose URL for each tournament
|
// Compose URL for each tournament
|
||||||
url := fmt.Sprintf(
|
url := fmt.Sprintf(
|
||||||
"http://eapi.enetpulse.com/tournament_stage/list/?language_typeFK=3&tz=Europe/Sofia&tournamentFK=%s&username=%s&token=%s",
|
"https://eapi.enetpulse.com/tournament_stage/list/?language_typeFK=3&tz=Europe/Sofia&tournamentFK=%s&username=%s&token=%s",
|
||||||
t.TournamentID,
|
t.TournamentID,
|
||||||
s.cfg.EnetPulseConfig.UserName,
|
s.cfg.EnetPulseConfig.UserName,
|
||||||
s.cfg.EnetPulseConfig.Token,
|
s.cfg.EnetPulseConfig.Token,
|
||||||
|
|
@ -460,125 +460,13 @@ func (s *Service) GetAllTournamentStages(ctx context.Context) ([]domain.Enetpuls
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FetchAndStoreFixtures(ctx context.Context, date string) error {
|
func (s *Service) FetchAndStoreFixtures(ctx context.Context, date string) error {
|
||||||
// 1️⃣ Fetch all sports from the database
|
// 1️⃣ Fetch all sports from DB
|
||||||
sports, err := s.store.GetAllEnetpulseSports(ctx)
|
sports, err := s.store.GetAllEnetpulseSports(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch sports from DB: %w", err)
|
return fmt.Errorf("failed to fetch sports from DB: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Struct for decoding each fixture from API
|
// Define API fixture struct
|
||||||
type Fixture struct {
|
|
||||||
FixtureID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
SportFK string `json:"sportFK"`
|
|
||||||
TournamentFK string `json:"tournamentFK"`
|
|
||||||
TournamentName string `json:"tournament_name"`
|
|
||||||
StartDate string `json:"startdate"`
|
|
||||||
StatusType string `json:"status_type"`
|
|
||||||
HomeTeam string `json:"home_team"`
|
|
||||||
AwayTeam string `json:"away_team"`
|
|
||||||
HomeTeamID string `json:"home_team_id"`
|
|
||||||
AwayTeamID string `json:"away_team_id"`
|
|
||||||
HomeKitImage string `json:"home_kit_image"`
|
|
||||||
AwayKitImage string `json:"away_kit_image"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2️⃣ Loop through each sport
|
|
||||||
for _, sport := range sports {
|
|
||||||
if sport.SportID != "1" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
url := fmt.Sprintf(
|
|
||||||
"http://eapi.enetpulse.com/event/fixtures/?username=%s&token=%s&sportFK=%s&language_typeFK=3&date=%s",
|
|
||||||
s.cfg.EnetPulseConfig.UserName,
|
|
||||||
s.cfg.EnetPulseConfig.Token,
|
|
||||||
sport.SportID,
|
|
||||||
date,
|
|
||||||
)
|
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("creating fixtures request for sport %s: %v\n", sport.SportID, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("requesting fixtures for sport %s: %v\n", sport.SportID, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
body, _ := io.ReadAll(resp.Body)
|
|
||||||
fmt.Printf("failed to fetch fixtures for sport %s (status %d): %s\n",
|
|
||||||
sport.SportID, resp.StatusCode, string(body))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3️⃣ Decode API response
|
|
||||||
var fixturesResp struct {
|
|
||||||
Events map[string]Fixture `json:"events"`
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&fixturesResp); err != nil {
|
|
||||||
fmt.Printf("decoding fixtures response for sport %s: %v\n", sport.SportID, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4️⃣ Iterate over fixtures and store as events
|
|
||||||
for _, fx := range fixturesResp.Events {
|
|
||||||
// Conversions
|
|
||||||
sportID, _ := strconv.Atoi(fx.SportFK)
|
|
||||||
homeTeamID, _ := strconv.ParseInt(fx.HomeTeamID, 10, 64)
|
|
||||||
awayTeamID, _ := strconv.ParseInt(fx.AwayTeamID, 10, 64)
|
|
||||||
leagueID, _ := strconv.ParseInt(fx.TournamentFK, 10, 64)
|
|
||||||
startDate, _ := time.Parse("2006-01-02 15:04:05", fx.StartDate)
|
|
||||||
|
|
||||||
event := domain.CreateEvent{
|
|
||||||
SourceEventID: fx.FixtureID,
|
|
||||||
SportID: int32(sportID),
|
|
||||||
MatchName: fx.Name,
|
|
||||||
HomeTeam: fx.HomeTeam,
|
|
||||||
AwayTeam: fx.AwayTeam,
|
|
||||||
HomeTeamID: homeTeamID,
|
|
||||||
AwayTeamID: awayTeamID,
|
|
||||||
HomeTeamImage: fx.HomeKitImage,
|
|
||||||
AwayTeamImage: fx.AwayKitImage,
|
|
||||||
LeagueID: leagueID,
|
|
||||||
LeagueName: fx.TournamentName,
|
|
||||||
StartTime: startDate,
|
|
||||||
IsLive: false, // default, can update later from live feed
|
|
||||||
Status: domain.STATUS_PENDING, // map to enum if needed
|
|
||||||
Source: "EnetPulse", // custom enum constant
|
|
||||||
DefaultWinningUpperLimit: 0, // default, can adjust
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5️⃣ Save event in DB (UPSERT)
|
|
||||||
if err := s.store.SaveEvent(ctx, event); err != nil {
|
|
||||||
fmt.Printf("failed storing event %s: %v\n", fx.FixtureID, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("✅ Successfully fetched and stored events for sport %s\n", sport.SportID)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("✅ Completed fetching and storing events for all sports")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.EnetpulseFixture, error) {
|
|
||||||
var allFixtures []domain.EnetpulseFixture
|
|
||||||
|
|
||||||
// 1️⃣ Fetch all sports from the database
|
|
||||||
sports, err := s.store.GetAllEnetpulseSports(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to fetch sports from DB: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Struct for decoding each fixture from API
|
|
||||||
type Fixture struct {
|
type Fixture struct {
|
||||||
FixtureID string `json:"id"`
|
FixtureID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
@ -591,23 +479,22 @@ func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.Enet
|
||||||
TournamentTemplateName string `json:"tournament_template_name"`
|
TournamentTemplateName string `json:"tournament_template_name"`
|
||||||
SportName string `json:"sport_name"`
|
SportName string `json:"sport_name"`
|
||||||
Gender string `json:"gender"`
|
Gender string `json:"gender"`
|
||||||
StartDate string `json:"startdate"`
|
StartDate string `json:"startdate"` // ISO 8601
|
||||||
StatusType string `json:"status_type"`
|
StatusType string `json:"status_type"`
|
||||||
StatusDescFK string `json:"status_descFK"`
|
StatusDescFK string `json:"status_descFK"`
|
||||||
RoundTypeFK string `json:"round_typeFK"`
|
RoundTypeFK string `json:"round_typeFK"`
|
||||||
UpdatesCount string `json:"n"`
|
UpdatesCount string `json:"n"` // convert to int
|
||||||
LastUpdatedAt string `json:"ut"`
|
LastUpdatedAt string `json:"ut"` // parse to time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2️⃣ Loop through each sport
|
// 2️⃣ Loop through each sport
|
||||||
for _, sport := range sports {
|
for _, sport := range sports {
|
||||||
// Only fetch for sport "1" (Football)
|
|
||||||
if sport.SportID != "1" {
|
if sport.SportID != "1" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf(
|
url := fmt.Sprintf(
|
||||||
"http://eapi.enetpulse.com/event/fixtures/?username=%s&token=%s&sportFK=%s&language_typeFK=3&date=%s",
|
"https://eapi.enetpulse.com/event/fixtures/?username=%s&token=%s&sportFK=%s&language_typeFK=3&date=%s",
|
||||||
s.cfg.EnetPulseConfig.UserName,
|
s.cfg.EnetPulseConfig.UserName,
|
||||||
s.cfg.EnetPulseConfig.Token,
|
s.cfg.EnetPulseConfig.Token,
|
||||||
sport.SportID,
|
sport.SportID,
|
||||||
|
|
@ -616,7 +503,7 @@ func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.Enet
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("creating fixtures request for sport %s: %v\n", sport.SportID, err)
|
fmt.Printf("creating request for sport %s: %v\n", sport.SportID, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,29 +526,38 @@ func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.Enet
|
||||||
Events map[string]Fixture `json:"events"`
|
Events map[string]Fixture `json:"events"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&fixturesResp); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&fixturesResp); err != nil {
|
||||||
fmt.Printf("decoding fixtures response for sport %s: %v\n", sport.SportID, err)
|
fmt.Printf("decoding fixtures for sport %s: %v\n", sport.SportID, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4️⃣ Iterate over fixtures and store them
|
// 4️⃣ Iterate and upsert fixtures
|
||||||
for _, fx := range fixturesResp.Events {
|
for _, fx := range fixturesResp.Events {
|
||||||
tournamentFK, _ := strconv.Atoi(fx.TournamentFK)
|
// Parse StartDate and LastUpdatedAt
|
||||||
tournamentTemplateFK, _ := strconv.Atoi(fx.TournamentTemplateFK)
|
startDate, err := time.Parse(time.RFC3339, fx.StartDate)
|
||||||
tournamentStageFK, _ := strconv.Atoi(fx.TournamentStageFK)
|
if err != nil {
|
||||||
statusDescFK, _ := strconv.Atoi(fx.StatusDescFK)
|
fmt.Printf("invalid startDate for fixture %s: %v\n", fx.FixtureID, err)
|
||||||
roundTypeFK, _ := strconv.Atoi(fx.RoundTypeFK)
|
continue
|
||||||
updatesCount, _ := strconv.Atoi(fx.UpdatesCount)
|
}
|
||||||
|
lastUpdated, err := time.Parse(time.RFC3339, fx.LastUpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("invalid lastUpdatedAt for fixture %s: %v\n", fx.FixtureID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
startDate, _ := time.Parse(time.RFC3339, fx.StartDate)
|
// Convert UpdatesCount
|
||||||
lastUpdatedAt, _ := time.Parse(time.RFC3339, fx.LastUpdatedAt)
|
updatesCount, err := strconv.Atoi(fx.UpdatesCount)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("invalid updatesCount for fixture %s: %v\n", fx.FixtureID, err)
|
||||||
|
updatesCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
createFixture := domain.CreateEnetpulseFixture{
|
fixture := domain.CreateEnetpulseFixture{
|
||||||
FixtureID: fx.FixtureID,
|
FixtureID: fx.FixtureID,
|
||||||
Name: fx.Name,
|
Name: fx.Name,
|
||||||
SportFK: fx.SportFK,
|
SportFK: fx.SportFK,
|
||||||
TournamentFK: strconv.Itoa(tournamentFK),
|
TournamentFK: fx.TournamentFK,
|
||||||
TournamentTemplateFK: strconv.Itoa(tournamentTemplateFK),
|
TournamentTemplateFK: fx.TournamentTemplateFK,
|
||||||
TournamentStageFK: strconv.Itoa(tournamentStageFK),
|
TournamentStageFK: fx.TournamentStageFK,
|
||||||
TournamentStageName: fx.TournamentStageName,
|
TournamentStageName: fx.TournamentStageName,
|
||||||
TournamentName: fx.TournamentName,
|
TournamentName: fx.TournamentName,
|
||||||
TournamentTemplateName: fx.TournamentTemplateName,
|
TournamentTemplateName: fx.TournamentTemplateName,
|
||||||
|
|
@ -669,29 +565,150 @@ func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.Enet
|
||||||
Gender: fx.Gender,
|
Gender: fx.Gender,
|
||||||
StartDate: startDate,
|
StartDate: startDate,
|
||||||
StatusType: fx.StatusType,
|
StatusType: fx.StatusType,
|
||||||
StatusDescFK: strconv.Itoa(statusDescFK),
|
StatusDescFK: fx.StatusDescFK,
|
||||||
RoundTypeFK: strconv.Itoa(roundTypeFK),
|
RoundTypeFK: fx.RoundTypeFK,
|
||||||
UpdatesCount: updatesCount,
|
UpdatesCount: updatesCount,
|
||||||
LastUpdatedAt: lastUpdatedAt,
|
LastUpdatedAt: lastUpdated,
|
||||||
}
|
}
|
||||||
|
|
||||||
dbFixture, err := s.store.CreateEnetpulseFixture(ctx, createFixture)
|
// 5️⃣ Save fixture using UPSERT repository method
|
||||||
if err != nil {
|
if _, err := s.store.CreateEnetpulseFixture(ctx, fixture); err != nil {
|
||||||
fmt.Printf("failed storing fixture %s: %v\n", fx.FixtureID, err)
|
fmt.Printf("failed upserting fixture %s: %v\n", fx.FixtureID, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
allFixtures = append(allFixtures, dbFixture)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("✅ Successfully fetched and stored fixtures for sport %s\n", sport.SportID)
|
fmt.Printf("✅ Successfully fetched and stored fixtures for sport %s\n", sport.SportID)
|
||||||
break // stop after first relevant sport
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("✅ Completed fetching and storing fixtures for all sports")
|
return nil
|
||||||
return allFixtures, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// func (s *Service) FetchFixtures(ctx context.Context, date string) ([]domain.EnetpulseFixture, error) {
|
||||||
|
// var allFixtures []domain.EnetpulseFixture
|
||||||
|
|
||||||
|
// // 1️⃣ Fetch all sports from the database
|
||||||
|
// sports, err := s.store.GetAllEnetpulseSports(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("failed to fetch sports from DB: %w", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Struct for decoding each fixture from API
|
||||||
|
// type Fixture struct {
|
||||||
|
// FixtureID string `json:"id"`
|
||||||
|
// Name string `json:"name"`
|
||||||
|
// SportFK string `json:"sportFK"`
|
||||||
|
// TournamentFK string `json:"tournamentFK"`
|
||||||
|
// TournamentTemplateFK string `json:"tournament_templateFK"`
|
||||||
|
// TournamentStageFK string `json:"tournament_stageFK"`
|
||||||
|
// TournamentStageName string `json:"tournament_stage_name"`
|
||||||
|
// TournamentName string `json:"tournament_name"`
|
||||||
|
// TournamentTemplateName string `json:"tournament_template_name"`
|
||||||
|
// SportName string `json:"sport_name"`
|
||||||
|
// Gender string `json:"gender"`
|
||||||
|
// StartDate string `json:"startdate"`
|
||||||
|
// StatusType string `json:"status_type"`
|
||||||
|
// StatusDescFK string `json:"status_descFK"`
|
||||||
|
// RoundTypeFK string `json:"round_typeFK"`
|
||||||
|
// UpdatesCount string `json:"n"`
|
||||||
|
// LastUpdatedAt string `json:"ut"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 2️⃣ Loop through each sport
|
||||||
|
// for _, sport := range sports {
|
||||||
|
// // Only fetch for sport "1" (Football)
|
||||||
|
// if sport.SportID != "1" {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// url := fmt.Sprintf(
|
||||||
|
// "http://eapi.enetpulse.com/event/fixtures/?username=%s&token=%s&sportFK=%s&language_typeFK=3&date=%s",
|
||||||
|
// s.cfg.EnetPulseConfig.UserName,
|
||||||
|
// s.cfg.EnetPulseConfig.Token,
|
||||||
|
// sport.SportID,
|
||||||
|
// date,
|
||||||
|
// )
|
||||||
|
|
||||||
|
// req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("creating fixtures request for sport %s: %v\n", sport.SportID, err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// resp, err := s.httpClient.Do(req)
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("requesting fixtures for sport %s: %v\n", sport.SportID, err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// defer resp.Body.Close()
|
||||||
|
|
||||||
|
// if resp.StatusCode != http.StatusOK {
|
||||||
|
// body, _ := io.ReadAll(resp.Body)
|
||||||
|
// fmt.Printf("failed to fetch fixtures for sport %s (status %d): %s\n",
|
||||||
|
// sport.SportID, resp.StatusCode, string(body))
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 3️⃣ Decode API response
|
||||||
|
// var fixturesResp struct {
|
||||||
|
// Events map[string]Fixture `json:"events"`
|
||||||
|
// }
|
||||||
|
// if err := json.NewDecoder(resp.Body).Decode(&fixturesResp); err != nil {
|
||||||
|
// fmt.Printf("decoding fixtures response for sport %s: %v\n", sport.SportID, err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 4️⃣ Iterate over fixtures and store them
|
||||||
|
// for _, fx := range fixturesResp.Events {
|
||||||
|
// tournamentFK, _ := strconv.Atoi(fx.TournamentFK)
|
||||||
|
// tournamentTemplateFK, _ := strconv.Atoi(fx.TournamentTemplateFK)
|
||||||
|
// tournamentStageFK, _ := strconv.Atoi(fx.TournamentStageFK)
|
||||||
|
// statusDescFK, _ := strconv.Atoi(fx.StatusDescFK)
|
||||||
|
// roundTypeFK, _ := strconv.Atoi(fx.RoundTypeFK)
|
||||||
|
// updatesCount, _ := strconv.Atoi(fx.UpdatesCount)
|
||||||
|
|
||||||
|
// startDate, _ := time.Parse(time.RFC3339, fx.StartDate)
|
||||||
|
// lastUpdatedAt, _ := time.Parse(time.RFC3339, fx.LastUpdatedAt)
|
||||||
|
|
||||||
|
// createFixture := domain.CreateEnetpulseFixture{
|
||||||
|
// FixtureID: fx.FixtureID,
|
||||||
|
// Name: fx.Name,
|
||||||
|
// SportFK: fx.SportFK,
|
||||||
|
// TournamentFK: strconv.Itoa(tournamentFK),
|
||||||
|
// TournamentTemplateFK: strconv.Itoa(tournamentTemplateFK),
|
||||||
|
// TournamentStageFK: strconv.Itoa(tournamentStageFK),
|
||||||
|
// TournamentStageName: fx.TournamentStageName,
|
||||||
|
// TournamentName: fx.TournamentName,
|
||||||
|
// TournamentTemplateName: fx.TournamentTemplateName,
|
||||||
|
// SportName: fx.SportName,
|
||||||
|
// Gender: fx.Gender,
|
||||||
|
// StartDate: startDate,
|
||||||
|
// StatusType: fx.StatusType,
|
||||||
|
// StatusDescFK: strconv.Itoa(statusDescFK),
|
||||||
|
// RoundTypeFK: strconv.Itoa(roundTypeFK),
|
||||||
|
// UpdatesCount: updatesCount,
|
||||||
|
// LastUpdatedAt: lastUpdatedAt,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// dbFixture, err := s.store.CreateEnetpulseFixture(ctx, createFixture)
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("failed storing fixture %s: %v\n", fx.FixtureID, err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// allFixtures = append(allFixtures, dbFixture)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // fmt.Printf("✅ Successfully fetched and stored fixtures for sport %s\n", sport.SportID)
|
||||||
|
// break // stop after first relevant sport
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // fmt.Println("✅ Completed fetching and storing fixtures for all sports")
|
||||||
|
// return allFixtures, nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (s *Service) GetAllFixtures(ctx context.Context) ([]domain.EnetpulseFixture, error) {
|
func (s *Service) GetAllFixtures(ctx context.Context) ([]domain.EnetpulseFixture, error) {
|
||||||
// 1️⃣ Fetch all from store
|
// 1️⃣ Fetch all from store
|
||||||
fixtures, err := s.store.GetAllEnetpulseFixtures(ctx)
|
fixtures, err := s.store.GetAllEnetpulseFixtures(ctx)
|
||||||
|
|
@ -955,136 +972,141 @@ func (s *Service) GetAllOutcomeTypes(ctx context.Context) ([]domain.EnetpulseOut
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FetchAndStorePreodds(ctx context.Context) error {
|
func (s *Service) FetchAndStorePreodds(ctx context.Context) error {
|
||||||
// 1️⃣ Fetch all events from DB
|
// 1️⃣ Fetch all fixtures
|
||||||
fixtures, err := s.store.GetAllEnetpulseFixtures(ctx)
|
fixtures, err := s.store.GetAllEnetpulseFixtures(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch fixtures: %w", err)
|
return fmt.Errorf("failed to fetch fixtures: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// providerIDStr := strconv.Itoa(int(s.cfg.EnetPulseConfig.ProviderID))
|
// 2️⃣ Fetch all outcome types
|
||||||
|
outcomeTypes, err := s.store.GetAllEnetpulseOutcomeTypes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch outcome types: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 2️⃣ Loop through each fixture/event
|
// 3️⃣ Loop through each fixture
|
||||||
for _, fixture := range fixtures {
|
for _, fixture := range fixtures {
|
||||||
url := fmt.Sprintf(
|
// 4️⃣ Loop through each outcome type
|
||||||
"http://eapi.enetpulse.com/preodds/event/?objectFK=%s&odds_providerFK=%s&username=%s&token=%s",
|
for _, outcome := range outcomeTypes {
|
||||||
fixture.FixtureID,
|
url := fmt.Sprintf(
|
||||||
s.cfg.EnetPulseConfig.ProviderID,
|
"http://eapi.enetpulse.com/preodds/event/?objectFK=%s&odds_providerFK=%s&outcome_typeFK=%s&username=%s&token=%s",
|
||||||
s.cfg.EnetPulseConfig.UserName,
|
fixture.FixtureID,
|
||||||
s.cfg.EnetPulseConfig.Token,
|
s.cfg.EnetPulseConfig.ProviderID,
|
||||||
)
|
outcome.OutcomeTypeID,
|
||||||
|
s.cfg.EnetPulseConfig.UserName,
|
||||||
|
s.cfg.EnetPulseConfig.Token,
|
||||||
|
)
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
|
||||||
// optionally log error and continue to next fixture
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.httpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode API response
|
|
||||||
var preoddsResp struct {
|
|
||||||
Preodds map[string]struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
OutcomeTypeFK string `json:"outcome_typeFK"`
|
|
||||||
OutcomeScopeFK string `json:"outcome_scopeFK"`
|
|
||||||
OutcomeSubtypeFK string `json:"outcome_subtypeFK"`
|
|
||||||
EventParticipantNumber string `json:"event_participant_number"`
|
|
||||||
Iparam string `json:"iparam"`
|
|
||||||
Iparam2 string `json:"iparam2"`
|
|
||||||
Dparam string `json:"dparam"`
|
|
||||||
Dparam2 string `json:"dparam2"`
|
|
||||||
Sparam string `json:"sparam"`
|
|
||||||
N string `json:"n"`
|
|
||||||
UT string `json:"ut"`
|
|
||||||
BettingOffers []struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
BettingOfferStatusFK int32 `json:"bettingoffer_status_fk"`
|
|
||||||
OddsProviderFK int32 `json:"odds_provider_fk"`
|
|
||||||
Odds float64 `json:"odds"`
|
|
||||||
OddsOld float64 `json:"odds_old"`
|
|
||||||
Active string `json:"active"`
|
|
||||||
CouponKey string `json:"coupon_key"`
|
|
||||||
N string `json:"n"`
|
|
||||||
UT string `json:"ut"`
|
|
||||||
} `json:"bettingoffers"`
|
|
||||||
} `json:"preodds"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&preoddsResp); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate and store preodds and nested betting offers
|
|
||||||
for _, p := range preoddsResp.Preodds {
|
|
||||||
updatesCount := 0
|
|
||||||
if p.N != "" {
|
|
||||||
if n, err := strconv.Atoi(p.N); err == nil {
|
|
||||||
updatesCount = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUpdatedAt, _ := time.Parse(time.RFC3339, p.UT)
|
|
||||||
|
|
||||||
eventParticipantNumber := int32(0)
|
|
||||||
if p.EventParticipantNumber != "" {
|
|
||||||
if epn, err := strconv.Atoi(p.EventParticipantNumber); err == nil {
|
|
||||||
eventParticipantNumber = int32(epn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createPreodds := domain.CreateEnetpulsePreodds{
|
|
||||||
PreoddsID: p.ID,
|
|
||||||
EventFK: fixture.FixtureID,
|
|
||||||
OutcomeTypeFK: string(p.OutcomeTypeFK),
|
|
||||||
OutcomeScopeFK: string(p.OutcomeScopeFK),
|
|
||||||
OutcomeSubtypeFK: string(p.OutcomeSubtypeFK),
|
|
||||||
EventParticipantNumber: int(eventParticipantNumber),
|
|
||||||
IParam: p.Iparam,
|
|
||||||
IParam2: p.Iparam2,
|
|
||||||
DParam: p.Dparam,
|
|
||||||
DParam2: p.Dparam2,
|
|
||||||
SParam: p.Sparam,
|
|
||||||
UpdatesCount: int(updatesCount),
|
|
||||||
LastUpdatedAt: lastUpdatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
storedPreodds, err := s.store.CreateEnetpulsePreodds(ctx, createPreodds)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range p.BettingOffers {
|
resp, err := s.httpClient.Do(req)
|
||||||
bettingUpdates := 0
|
if err != nil {
|
||||||
if o.N != "" {
|
continue
|
||||||
if n, err := strconv.Atoi(o.N); err == nil {
|
}
|
||||||
bettingUpdates = n
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var preoddsResp struct {
|
||||||
|
Preodds map[string]struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
OutcomeTypeFK string `json:"outcome_typeFK"`
|
||||||
|
OutcomeScopeFK string `json:"outcome_scopeFK"`
|
||||||
|
OutcomeSubtypeFK string `json:"outcome_subtypeFK"`
|
||||||
|
EventParticipantNumber string `json:"event_participant_number"`
|
||||||
|
Iparam string `json:"iparam"`
|
||||||
|
Iparam2 string `json:"iparam2"`
|
||||||
|
Dparam string `json:"dparam"`
|
||||||
|
Dparam2 string `json:"dparam2"`
|
||||||
|
Sparam string `json:"sparam"`
|
||||||
|
N string `json:"n"`
|
||||||
|
UT string `json:"ut"`
|
||||||
|
BettingOffers []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
BettingOfferStatusFK int32 `json:"bettingoffer_status_fk"`
|
||||||
|
OddsProviderFK int32 `json:"odds_provider_fk"`
|
||||||
|
Odds float64 `json:"odds"`
|
||||||
|
OddsOld float64 `json:"odds_old"`
|
||||||
|
Active string `json:"active"`
|
||||||
|
CouponKey string `json:"coupon_key"`
|
||||||
|
N string `json:"n"`
|
||||||
|
UT string `json:"ut"`
|
||||||
|
} `json:"bettingoffers"`
|
||||||
|
} `json:"preodds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&preoddsResp); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range preoddsResp.Preodds {
|
||||||
|
updatesCount := 0
|
||||||
|
if p.N != "" {
|
||||||
|
if n, err := strconv.Atoi(p.N); err == nil {
|
||||||
|
updatesCount = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bettingLastUpdatedAt, _ := time.Parse(time.RFC3339, o.UT)
|
lastUpdatedAt, _ := time.Parse(time.RFC3339, p.UT)
|
||||||
|
|
||||||
createOffer := domain.CreateEnetpulsePreoddsBettingOffer{
|
eventParticipantNumber := int32(0)
|
||||||
BettingOfferID: o.ID,
|
if p.EventParticipantNumber != "" {
|
||||||
PreoddsFK: storedPreodds.PreoddsID,
|
if epn, err := strconv.Atoi(p.EventParticipantNumber); err == nil {
|
||||||
BettingOfferStatusFK: o.BettingOfferStatusFK,
|
eventParticipantNumber = int32(epn)
|
||||||
OddsProviderFK: o.OddsProviderFK,
|
}
|
||||||
Odds: o.Odds,
|
|
||||||
OddsOld: o.OddsOld,
|
|
||||||
Active: o.Active,
|
|
||||||
CouponKey: o.CouponKey,
|
|
||||||
UpdatesCount: int(bettingUpdates),
|
|
||||||
LastUpdatedAt: bettingLastUpdatedAt,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = s.store.CreateEnetpulsePreoddsBettingOffer(ctx, createOffer)
|
createPreodds := domain.CreateEnetpulsePreodds{
|
||||||
|
PreoddsID: p.ID,
|
||||||
|
EventFK: fixture.FixtureID,
|
||||||
|
OutcomeTypeFK: outcome.OutcomeTypeID,
|
||||||
|
OutcomeScopeFK: string(p.OutcomeScopeFK),
|
||||||
|
OutcomeSubtypeFK: string(p.OutcomeSubtypeFK),
|
||||||
|
EventParticipantNumber: int(eventParticipantNumber),
|
||||||
|
IParam: p.Iparam,
|
||||||
|
IParam2: p.Iparam2,
|
||||||
|
DParam: p.Dparam,
|
||||||
|
DParam2: p.Dparam2,
|
||||||
|
SParam: p.Sparam,
|
||||||
|
UpdatesCount: int(updatesCount),
|
||||||
|
LastUpdatedAt: lastUpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
storedPreodds, err := s.store.CreateEnetpulsePreodds(ctx, createPreodds)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range p.BettingOffers {
|
||||||
|
bettingUpdates := 0
|
||||||
|
if o.N != "" {
|
||||||
|
if n, err := strconv.Atoi(o.N); err == nil {
|
||||||
|
bettingUpdates = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bettingLastUpdatedAt, _ := time.Parse(time.RFC3339, o.UT)
|
||||||
|
|
||||||
|
createOffer := domain.CreateEnetpulsePreoddsBettingOffer{
|
||||||
|
BettingOfferID: o.ID,
|
||||||
|
PreoddsFK: storedPreodds.PreoddsID,
|
||||||
|
BettingOfferStatusFK: o.BettingOfferStatusFK,
|
||||||
|
OddsProviderFK: o.OddsProviderFK,
|
||||||
|
Odds: o.Odds,
|
||||||
|
OddsOld: o.OddsOld,
|
||||||
|
Active: o.Active,
|
||||||
|
CouponKey: o.CouponKey,
|
||||||
|
UpdatesCount: int(bettingUpdates),
|
||||||
|
LastUpdatedAt: bettingLastUpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = s.store.CreateEnetpulsePreoddsBettingOffer(ctx, createOffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1208,6 +1230,16 @@ func (s *Service) GetAllBettingOffers(ctx context.Context) ([]domain.EnetpulsePr
|
||||||
return offers, nil
|
return offers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetFixturesWithPreodds(ctx context.Context) ([]domain.EnetpulseFixtureWithPreodds, error) {
|
||||||
|
// 1️⃣ Fetch fixtures and their associated preodds from the repository
|
||||||
|
fixtures, err := s.store.GetFixturesWithPreodds(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch fixtures with preodds from DB: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixtures, nil
|
||||||
|
}
|
||||||
|
|
||||||
// helper to safely parse string to int32
|
// helper to safely parse string to int32
|
||||||
// func parseStringToInt32(s string) int32 {
|
// func parseStringToInt32(s string) int32 {
|
||||||
// if s == "" {
|
// if s == "" {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ type Service interface {
|
||||||
UpdateEventMonitored(ctx context.Context, eventID int64, IsMonitored bool) error
|
UpdateEventMonitored(ctx context.Context, eventID int64, IsMonitored bool) error
|
||||||
GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
|
GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
|
||||||
GetEventWithSettingByID(ctx context.Context, ID int64, companyID int64) (domain.EventWithSettings, error)
|
GetEventWithSettingByID(ctx context.Context, ID int64, companyID int64) (domain.EventWithSettings, error)
|
||||||
UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error
|
UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error
|
||||||
|
UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error
|
||||||
GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error)
|
GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -491,8 +491,11 @@ func (s *service) GetEventWithSettingByID(ctx context.Context, ID int64, company
|
||||||
return s.store.GetEventWithSettingByID(ctx, ID, companyID)
|
return s.store.GetEventWithSettingByID(ctx, ID, companyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
func (s *service) UpdateTenantEventSettings(ctx context.Context, event domain.UpdateTenantEventSettings) error {
|
||||||
return s.store.UpdateEventSettings(ctx, event)
|
return s.store.UpdateTenantEventSettings(ctx, event)
|
||||||
|
}
|
||||||
|
func (s *service) UpdateGlobalEventSettings(ctx context.Context, event domain.UpdateGlobalEventSettings) error {
|
||||||
|
return s.store.UpdateGlobalEventSettings(ctx, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error) {
|
func (s *service) GetSportAndLeagueIDs(ctx context.Context, eventID int64) ([]int64, error) {
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,67 @@
|
||||||
package kafka
|
package kafka
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"context"
|
// "context"
|
||||||
"encoding/json"
|
// "encoding/json"
|
||||||
"log"
|
// "log"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws"
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws"
|
||||||
"github.com/segmentio/kafka-go"
|
// "github.com/segmentio/kafka-go"
|
||||||
)
|
// )
|
||||||
|
|
||||||
type WalletConsumer struct {
|
// type WalletConsumer struct {
|
||||||
reader *kafka.Reader
|
// reader *kafka.Reader
|
||||||
hub *ws.NotificationHub
|
// hub *ws.NotificationHub
|
||||||
topic string
|
// topic string
|
||||||
groupID string
|
// groupID string
|
||||||
brokers []string
|
// brokers []string
|
||||||
}
|
// }
|
||||||
|
|
||||||
func NewWalletConsumer(brokers []string, topic, groupID string, hub *ws.NotificationHub) *WalletConsumer {
|
// func NewWalletConsumer(brokers []string, topic, groupID string, hub *ws.NotificationHub) *WalletConsumer {
|
||||||
return &WalletConsumer{
|
// return &WalletConsumer{
|
||||||
brokers: brokers,
|
// brokers: brokers,
|
||||||
topic: topic,
|
// topic: topic,
|
||||||
groupID: groupID,
|
// groupID: groupID,
|
||||||
hub: hub,
|
// hub: hub,
|
||||||
reader: kafka.NewReader(kafka.ReaderConfig{
|
// reader: kafka.NewReader(kafka.ReaderConfig{
|
||||||
Brokers: brokers,
|
// Brokers: brokers,
|
||||||
GroupID: groupID,
|
// GroupID: groupID,
|
||||||
Topic: topic,
|
// Topic: topic,
|
||||||
}),
|
// }),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *WalletConsumer) Start(ctx context.Context) {
|
// func (c *WalletConsumer) Start(ctx context.Context) {
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
m, err := c.reader.ReadMessage(ctx)
|
// m, err := c.reader.ReadMessage(ctx)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("Error reading wallet Kafka message: %v", err)
|
// log.Printf("Error reading wallet Kafka message: %v", err)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
var evt event.WalletEvent
|
// var evt event.WalletEvent
|
||||||
if err := json.Unmarshal(m.Value, &evt); err != nil {
|
// if err := json.Unmarshal(m.Value, &evt); err != nil {
|
||||||
log.Printf("Failed to unmarshal wallet event: %v", err)
|
// log.Printf("Failed to unmarshal wallet event: %v", err)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
payload := map[string]interface{}{
|
// payload := map[string]interface{}{
|
||||||
"type": evt.EventType,
|
// "type": evt.EventType,
|
||||||
"wallet_id": evt.WalletID,
|
// "wallet_id": evt.WalletID,
|
||||||
"user_id": evt.UserID,
|
// "user_id": evt.UserID,
|
||||||
"balance": evt.Balance,
|
// "balance": evt.Balance,
|
||||||
"wallet_type": evt.WalletType,
|
// "wallet_type": evt.WalletType,
|
||||||
"trigger": evt.Trigger,
|
// "trigger": evt.Trigger,
|
||||||
"recipient_id": evt.UserID,
|
// "recipient_id": evt.UserID,
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Broadcast to appropriate WebSocket clients
|
// // Broadcast to appropriate WebSocket clients
|
||||||
c.hub.Broadcast <- payload
|
// c.hub.Broadcast <- payload
|
||||||
}
|
// }
|
||||||
}()
|
// }()
|
||||||
}
|
// }
|
||||||
|
|
||||||
// func (c *WalletConsumer) Shutdown() error {
|
// func (c *WalletConsumer) Shutdown() error {
|
||||||
// return c.reader.Close()
|
// return c.reader.Close()
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,36 @@
|
||||||
package kafka
|
package kafka
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"context"
|
// "context"
|
||||||
"encoding/json"
|
// "encoding/json"
|
||||||
"time"
|
// "time"
|
||||||
|
|
||||||
"github.com/segmentio/kafka-go"
|
// "github.com/segmentio/kafka-go"
|
||||||
)
|
// )
|
||||||
|
|
||||||
type Producer struct {
|
// type Producer struct {
|
||||||
writer *kafka.Writer
|
// writer *kafka.Writer
|
||||||
}
|
// }
|
||||||
|
|
||||||
func NewProducer(brokers []string, topic string) *Producer {
|
// func NewProducer(brokers []string, topic string) *Producer {
|
||||||
return &Producer{
|
// return &Producer{
|
||||||
writer: &kafka.Writer{
|
// writer: &kafka.Writer{
|
||||||
Addr: kafka.TCP(brokers...),
|
// Addr: kafka.TCP(brokers...),
|
||||||
Topic: topic,
|
// Topic: topic,
|
||||||
Balancer: &kafka.LeastBytes{},
|
// Balancer: &kafka.LeastBytes{},
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (p *Producer) Publish(ctx context.Context, key string, event any) error {
|
// func (p *Producer) Publish(ctx context.Context, key string, event any) error {
|
||||||
msgBytes, err := json.Marshal(event)
|
// msgBytes, err := json.Marshal(event)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
return p.writer.WriteMessages(ctx, kafka.Message{
|
// return p.writer.WriteMessages(ctx, kafka.Message{
|
||||||
Key: []byte(key),
|
// Key: []byte(key),
|
||||||
Value: msgBytes,
|
// Value: msgBytes,
|
||||||
Time: time.Now(),
|
// Time: time.Now(),
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ import (
|
||||||
type Service interface {
|
type Service interface {
|
||||||
SaveLeague(ctx context.Context, league domain.CreateLeague) error
|
SaveLeague(ctx context.Context, league domain.CreateLeague) error
|
||||||
SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error
|
SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error
|
||||||
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error)
|
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error)
|
||||||
GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error)
|
GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error)
|
||||||
CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error)
|
CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error)
|
||||||
UpdateLeague(ctx context.Context, league domain.UpdateLeague) error
|
UpdateLeague(ctx context.Context, league domain.UpdateLeague) error
|
||||||
|
UpdateGlobalLeagueSettings(ctx context.Context, league domain.UpdateGlobalLeagueSettings) error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func (s *service) SaveLeagueSettings(ctx context.Context, leagueSettings domain.
|
||||||
return s.store.SaveLeagueSettings(ctx, leagueSettings)
|
return s.store.SaveLeagueSettings(ctx, leagueSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error) {
|
||||||
return s.store.GetAllLeagues(ctx, filter)
|
return s.store.GetAllLeagues(ctx, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,3 +40,7 @@ func (s *service) CheckLeagueSupport(ctx context.Context, leagueID int64, compan
|
||||||
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||||
return s.store.UpdateLeague(ctx, league)
|
return s.store.UpdateLeague(ctx, league)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) UpdateGlobalLeagueSettings(ctx context.Context, league domain.UpdateGlobalLeagueSettings) error {
|
||||||
|
return s.store.UpdateGlobalLeagueSettings(ctx, league)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package notificationservice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// "errors"
|
// "errors"
|
||||||
|
|
@ -12,19 +11,19 @@ import (
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||||
"github.com/segmentio/kafka-go"
|
// "github.com/segmentio/kafka-go"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws"
|
||||||
// afro "github.com/amanuelabay/afrosms-go"
|
// afro "github.com/amanuelabay/afrosms-go"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/redis/go-redis/v9"
|
// "github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
|
@ -39,8 +38,6 @@ type Service struct {
|
||||||
messengerSvc *messenger.Service
|
messengerSvc *messenger.Service
|
||||||
mongoLogger *zap.Logger
|
mongoLogger *zap.Logger
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
redisClient *redis.Client
|
|
||||||
reader *kafka.Reader
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(repo repository.NotificationRepository,
|
func New(repo repository.NotificationRepository,
|
||||||
|
|
@ -49,17 +46,8 @@ func New(repo repository.NotificationRepository,
|
||||||
cfg *config.Config,
|
cfg *config.Config,
|
||||||
messengerSvc *messenger.Service,
|
messengerSvc *messenger.Service,
|
||||||
userSvc *user.Service,
|
userSvc *user.Service,
|
||||||
kafkaBrokers []string,
|
|
||||||
) *Service {
|
) *Service {
|
||||||
hub := ws.NewNotificationHub()
|
hub := ws.NewNotificationHub()
|
||||||
rdb := redis.NewClient(&redis.Options{
|
|
||||||
Addr: cfg.RedisAddr, // e.g., "redis:6379"
|
|
||||||
})
|
|
||||||
walletReader := kafka.NewReader(kafka.ReaderConfig{
|
|
||||||
Brokers: kafkaBrokers,
|
|
||||||
Topic: "wallet-balance-topic",
|
|
||||||
GroupID: "notification-service-group", // Each service should have its own group
|
|
||||||
})
|
|
||||||
|
|
||||||
svc := &Service{
|
svc := &Service{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
|
@ -72,15 +60,13 @@ func New(repo repository.NotificationRepository,
|
||||||
messengerSvc: messengerSvc,
|
messengerSvc: messengerSvc,
|
||||||
userSvc: userSvc,
|
userSvc: userSvc,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
redisClient: rdb,
|
|
||||||
reader: walletReader,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go hub.Run()
|
go hub.Run()
|
||||||
go svc.startWorker()
|
go svc.startWorker()
|
||||||
go svc.startRetryWorker()
|
go svc.startRetryWorker()
|
||||||
go svc.RunRedisSubscriber(context.Background())
|
// go svc.RunRedisSubscriber(context.Background())
|
||||||
go svc.StartKafkaConsumer(context.Background())
|
// go svc.StartKafkaConsumer(context.Background())
|
||||||
|
|
||||||
return svc
|
return svc
|
||||||
}
|
}
|
||||||
|
|
@ -484,189 +470,192 @@ func (s *Service) CountUnreadNotifications(ctx context.Context, recipient_id int
|
||||||
return s.repo.CountUnreadNotifications(ctx, recipient_id)
|
return s.repo.CountUnreadNotifications(ctx, recipient_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) DeleteOldNotifications(ctx context.Context) error {
|
||||||
|
return s.repo.DeleteOldNotifications(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// func (s *Service) GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error){
|
// func (s *Service) GetNotificationCounts(ctx context.Context, filter domain.ReportFilter) (total, read, unread int64, err error){
|
||||||
// return s.repo.Get(ctx, filter)
|
// return s.repo.Get(ctx, filter)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (s *Service) RunRedisSubscriber(ctx context.Context) {
|
// func (s *Service) RunRedisSubscriber(ctx context.Context) {
|
||||||
pubsub := s.redisClient.Subscribe(ctx, "live_metrics")
|
// pubsub := s.redisClient.Subscribe(ctx, "live_metrics")
|
||||||
defer pubsub.Close()
|
// defer pubsub.Close()
|
||||||
|
|
||||||
ch := pubsub.Channel()
|
// ch := pubsub.Channel()
|
||||||
for msg := range ch {
|
// for msg := range ch {
|
||||||
var parsed map[string]interface{}
|
// var parsed map[string]interface{}
|
||||||
if err := json.Unmarshal([]byte(msg.Payload), &parsed); err != nil {
|
// if err := json.Unmarshal([]byte(msg.Payload), &parsed); err != nil {
|
||||||
// s.logger.Error("invalid Redis message format", "payload", msg.Payload, "error", err)
|
// // s.logger.Error("invalid Redis message format", "payload", msg.Payload, "error", err)
|
||||||
s.mongoLogger.Error("invalid Redis message format",
|
// s.mongoLogger.Error("invalid Redis message format",
|
||||||
zap.String("payload", msg.Payload),
|
// zap.String("payload", msg.Payload),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
// zap.Time("timestamp", time.Now()),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
eventType, _ := parsed["type"].(string)
|
// eventType, _ := parsed["type"].(string)
|
||||||
payload := parsed["payload"]
|
// payload := parsed["payload"]
|
||||||
recipientID, hasRecipient := parsed["recipient_id"]
|
// recipientID, hasRecipient := parsed["recipient_id"]
|
||||||
recipientType, _ := parsed["recipient_type"].(string)
|
// recipientType, _ := parsed["recipient_type"].(string)
|
||||||
|
|
||||||
message := map[string]interface{}{
|
// message := map[string]interface{}{
|
||||||
"type": eventType,
|
// "type": eventType,
|
||||||
"payload": payload,
|
// "payload": payload,
|
||||||
}
|
// }
|
||||||
|
|
||||||
if hasRecipient {
|
// if hasRecipient {
|
||||||
message["recipient_id"] = recipientID
|
// message["recipient_id"] = recipientID
|
||||||
message["recipient_type"] = recipientType
|
// message["recipient_type"] = recipientType
|
||||||
}
|
// }
|
||||||
|
|
||||||
s.Hub.Broadcast <- message
|
// s.Hub.Broadcast <- message
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *Service) UpdateLiveWalletMetrics(ctx context.Context, companies []domain.GetCompany, branches []domain.BranchWallet) error {
|
// func (s *Service) UpdateLiveWalletMetrics(ctx context.Context, companies []domain.GetCompany, branches []domain.BranchWallet) error {
|
||||||
const key = "live_metrics"
|
// const key = "live_metrics"
|
||||||
|
|
||||||
companyBalances := make([]domain.CompanyWalletBalance, 0, len(companies))
|
// companyBalances := make([]domain.CompanyWalletBalance, 0, len(companies))
|
||||||
for _, c := range companies {
|
// for _, c := range companies {
|
||||||
companyBalances = append(companyBalances, domain.CompanyWalletBalance{
|
// companyBalances = append(companyBalances, domain.CompanyWalletBalance{
|
||||||
CompanyID: c.ID,
|
// CompanyID: c.ID,
|
||||||
CompanyName: c.Name,
|
// CompanyName: c.Name,
|
||||||
Balance: float64(c.WalletBalance.Float32()),
|
// Balance: float64(c.WalletBalance.Float32()),
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
branchBalances := make([]domain.BranchWalletBalance, 0, len(branches))
|
// branchBalances := make([]domain.BranchWalletBalance, 0, len(branches))
|
||||||
for _, b := range branches {
|
// for _, b := range branches {
|
||||||
branchBalances = append(branchBalances, domain.BranchWalletBalance{
|
// branchBalances = append(branchBalances, domain.BranchWalletBalance{
|
||||||
BranchID: b.ID,
|
// BranchID: b.ID,
|
||||||
BranchName: b.Name,
|
// BranchName: b.Name,
|
||||||
CompanyID: b.CompanyID,
|
// CompanyID: b.CompanyID,
|
||||||
Balance: float64(b.Balance.Float32()),
|
// Balance: float64(b.Balance.Float32()),
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
payload := domain.LiveWalletMetrics{
|
// payload := domain.LiveWalletMetrics{
|
||||||
Timestamp: time.Now(),
|
// Timestamp: time.Now(),
|
||||||
CompanyBalances: companyBalances,
|
// CompanyBalances: companyBalances,
|
||||||
BranchBalances: branchBalances,
|
// BranchBalances: branchBalances,
|
||||||
}
|
// }
|
||||||
|
|
||||||
updatedData, err := json.Marshal(payload)
|
// updatedData, err := json.Marshal(payload)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
if err := s.redisClient.Set(ctx, key, updatedData, 0).Err(); err != nil {
|
// if err := s.redisClient.Set(ctx, key, updatedData, 0).Err(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
if err := s.redisClient.Publish(ctx, key, updatedData).Err(); err != nil {
|
// if err := s.redisClient.Publish(ctx, key, updatedData).Err(); err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *Service) GetLiveMetrics(ctx context.Context) (domain.LiveMetric, error) {
|
// func (s *Service) GetLiveMetrics(ctx context.Context) (domain.LiveMetric, error) {
|
||||||
const key = "live_metrics"
|
// const key = "live_metrics"
|
||||||
var metric domain.LiveMetric
|
// var metric domain.LiveMetric
|
||||||
|
|
||||||
val, err := s.redisClient.Get(ctx, key).Result()
|
// val, err := s.redisClient.Get(ctx, key).Result()
|
||||||
if err == redis.Nil {
|
// if err == redis.Nil {
|
||||||
// Key does not exist yet, return zero-valued struct
|
// // Key does not exist yet, return zero-valued struct
|
||||||
return domain.LiveMetric{}, nil
|
// return domain.LiveMetric{}, nil
|
||||||
} else if err != nil {
|
// } else if err != nil {
|
||||||
return domain.LiveMetric{}, err
|
// return domain.LiveMetric{}, err
|
||||||
}
|
// }
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(val), &metric); err != nil {
|
// if err := json.Unmarshal([]byte(val), &metric); err != nil {
|
||||||
return domain.LiveMetric{}, err
|
// return domain.LiveMetric{}, err
|
||||||
}
|
// }
|
||||||
|
|
||||||
return metric, nil
|
// return metric, nil
|
||||||
}
|
// }
|
||||||
|
// func (s *Service) StartKafkaConsumer(ctx context.Context) {
|
||||||
|
// go func() {
|
||||||
|
// for {
|
||||||
|
// m, err := s.reader.ReadMessage(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// if err == context.Canceled {
|
||||||
|
// s.mongoLogger.Info("[NotificationSvc.KafkaConsumer] Stopped by context")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Error reading message",
|
||||||
|
// zap.Error(err),
|
||||||
|
// zap.Time("timestamp", time.Now()),
|
||||||
|
// )
|
||||||
|
// time.Sleep(1 * time.Second) // backoff
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
func (s *Service) StartKafkaConsumer(ctx context.Context) {
|
// var walletEvent event.WalletEvent
|
||||||
go func() {
|
// if err := json.Unmarshal(m.Value, &walletEvent); err != nil {
|
||||||
for {
|
// s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Failed to unmarshal wallet event",
|
||||||
m, err := s.reader.ReadMessage(ctx)
|
// zap.String("message", string(m.Value)),
|
||||||
if err != nil {
|
// zap.Error(err),
|
||||||
if err == context.Canceled {
|
// zap.Time("timestamp", time.Now()),
|
||||||
s.mongoLogger.Info("[NotificationSvc.KafkaConsumer] Stopped by context")
|
// )
|
||||||
return
|
// continue
|
||||||
}
|
// }
|
||||||
s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Error reading message",
|
|
||||||
zap.Error(err),
|
|
||||||
zap.Time("timestamp", time.Now()),
|
|
||||||
)
|
|
||||||
time.Sleep(1 * time.Second) // backoff
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var walletEvent event.WalletEvent
|
// raw, _ := json.Marshal(map[string]any{
|
||||||
if err := json.Unmarshal(m.Value, &walletEvent); err != nil {
|
// "balance": walletEvent.Balance.Float32(),
|
||||||
s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Failed to unmarshal wallet event",
|
// "type": walletEvent.WalletType,
|
||||||
zap.String("message", string(m.Value)),
|
// "timestamp": time.Now(),
|
||||||
zap.Error(err),
|
// })
|
||||||
zap.Time("timestamp", time.Now()),
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
raw, _ := json.Marshal(map[string]any{
|
// headline := ""
|
||||||
"balance": walletEvent.Balance.Float32(),
|
// message := ""
|
||||||
"type": walletEvent.WalletType,
|
// var receiver domain.NotificationRecieverSide
|
||||||
"timestamp": time.Now(),
|
// switch walletEvent.WalletType {
|
||||||
})
|
|
||||||
|
|
||||||
headline := ""
|
// case domain.StaticWalletType:
|
||||||
message := ""
|
// headline = "Referral and Bonus Wallet Updated"
|
||||||
var receiver domain.NotificationRecieverSide
|
// message = fmt.Sprintf("Your referral and bonus wallet balance is now %.2f", walletEvent.Balance.Float32())
|
||||||
switch walletEvent.WalletType {
|
// receiver = domain.NotificationRecieverSideCustomer
|
||||||
|
// case domain.RegularWalletType:
|
||||||
|
// headline = "Wallet Updated"
|
||||||
|
// message = fmt.Sprintf("Your wallet balance is now %.2f", walletEvent.Balance.Float32())
|
||||||
|
// receiver = domain.NotificationRecieverSideCustomer
|
||||||
|
// case domain.BranchWalletType:
|
||||||
|
// headline = "Branch Wallet Updated"
|
||||||
|
// message = fmt.Sprintf("branch wallet balance is now %.2f", walletEvent.Balance.Float32())
|
||||||
|
// receiver = domain.NotificationRecieverSideBranchManager
|
||||||
|
// case domain.CompanyWalletType:
|
||||||
|
// headline = "Company Wallet Updated"
|
||||||
|
// message = fmt.Sprintf("company wallet balance is now %.2f", walletEvent.Balance.Float32())
|
||||||
|
// receiver = domain.NotificationRecieverSideAdmin
|
||||||
|
// }
|
||||||
|
// // Handle the wallet event: send notification
|
||||||
|
// notification := &domain.Notification{
|
||||||
|
// RecipientID: walletEvent.UserID,
|
||||||
|
// DeliveryChannel: domain.DeliveryChannelInApp,
|
||||||
|
// Reciever: receiver,
|
||||||
|
// Type: domain.NotificationTypeWalletUpdated,
|
||||||
|
// DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
// IsRead: false,
|
||||||
|
// Level: domain.NotificationLevelInfo,
|
||||||
|
// Priority: 2,
|
||||||
|
// Metadata: raw,
|
||||||
|
// Payload: domain.NotificationPayload{
|
||||||
|
// Headline: headline,
|
||||||
|
// Message: message,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
case domain.StaticWalletType:
|
// if err := s.SendNotification(ctx, notification); err != nil {
|
||||||
headline = "Referral and Bonus Wallet Updated"
|
// s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Failed to send notification",
|
||||||
message = fmt.Sprintf("Your referral and bonus wallet balance is now %.2f", walletEvent.Balance.Float32())
|
// zap.Error(err),
|
||||||
receiver = domain.NotificationRecieverSideCustomer
|
// zap.Time("timestamp", time.Now()),
|
||||||
case domain.RegularWalletType:
|
// )
|
||||||
headline = "Wallet Updated"
|
// }
|
||||||
message = fmt.Sprintf("Your wallet balance is now %.2f", walletEvent.Balance.Float32())
|
// }
|
||||||
receiver = domain.NotificationRecieverSideCustomer
|
// }()
|
||||||
case domain.BranchWalletType:
|
// }
|
||||||
headline = "Branch Wallet Updated"
|
|
||||||
message = fmt.Sprintf("branch wallet balance is now %.2f", walletEvent.Balance.Float32())
|
|
||||||
receiver = domain.NotificationRecieverSideBranchManager
|
|
||||||
case domain.CompanyWalletType:
|
|
||||||
headline = "Company Wallet Updated"
|
|
||||||
message = fmt.Sprintf("company wallet balance is now %.2f", walletEvent.Balance.Float32())
|
|
||||||
receiver = domain.NotificationRecieverSideAdmin
|
|
||||||
}
|
|
||||||
// Handle the wallet event: send notification
|
|
||||||
notification := &domain.Notification{
|
|
||||||
RecipientID: walletEvent.UserID,
|
|
||||||
DeliveryChannel: domain.DeliveryChannelInApp,
|
|
||||||
Reciever: receiver,
|
|
||||||
Type: domain.NotificationTypeWalletUpdated,
|
|
||||||
DeliveryStatus: domain.DeliveryStatusPending,
|
|
||||||
IsRead: false,
|
|
||||||
Level: domain.NotificationLevelInfo,
|
|
||||||
Priority: 2,
|
|
||||||
Metadata: raw,
|
|
||||||
Payload: domain.NotificationPayload{
|
|
||||||
Headline: headline,
|
|
||||||
Message: message,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.SendNotification(ctx, notification); err != nil {
|
|
||||||
s.mongoLogger.Error("[NotificationSvc.KafkaConsumer] Failed to send notification",
|
|
||||||
zap.Error(err),
|
|
||||||
zap.Time("timestamp", time.Now()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (s *Service) UpdateLiveWalletMetricForWallet(ctx context.Context, wallet domain.Wallet) {
|
// func (s *Service) UpdateLiveWalletMetricForWallet(ctx context.Context, wallet domain.Wallet) {
|
||||||
// var (
|
// var (
|
||||||
|
|
|
||||||
|
|
@ -17,31 +17,17 @@ type Service interface {
|
||||||
GetALLPrematchOdds(ctx context.Context) ([]domain.OddMarket, error)
|
GetALLPrematchOdds(ctx context.Context) ([]domain.OddMarket, error)
|
||||||
// GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.OddMarket, error)
|
// GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.OddMarket, error)
|
||||||
DeleteOddsForEvent(ctx context.Context, eventID string) error
|
DeleteOddsForEvent(ctx context.Context, eventID string) error
|
||||||
|
|
||||||
GetOddByID(ctx context.Context, id int64) (domain.OddMarket, error)
|
GetOddByID(ctx context.Context, id int64) (domain.OddMarket, error)
|
||||||
GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID int64) (domain.OddMarketWithSettings, error)
|
GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID int64) (domain.OddMarketWithSettings, error)
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
SaveOddsSetting(ctx context.Context, odd domain.CreateOddMarketSettings) error
|
SaveOddsSetting(ctx context.Context, odd domain.CreateOddMarketSettings) error
|
||||||
|
UpdateGlobalOddsSetting(ctx context.Context, odd domain.UpdateGlobalOddMarketSettings) error
|
||||||
|
DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error
|
||||||
|
DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, companyID int64, oddMarketID int64) error
|
||||||
|
|
||||||
// Odd History
|
// Odd History
|
||||||
InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error)
|
InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error)
|
||||||
GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
|
GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
|
||||||
GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
|
GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error)
|
||||||
|
|
||||||
// Disabling Odds
|
|
||||||
InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error)
|
|
||||||
GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error)
|
|
||||||
GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error)
|
|
||||||
GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error)
|
|
||||||
DeleteDisabledOddsByID(ctx context.Context, id int64) error
|
|
||||||
DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error
|
|
||||||
|
|
||||||
// Custom Odds
|
|
||||||
// InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error)
|
|
||||||
// GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error)
|
|
||||||
// GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error)
|
|
||||||
// GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error)
|
|
||||||
// DeleteCustomOddByID(ctx context.Context, id int64) error
|
|
||||||
// DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error
|
|
||||||
// DeleteCustomOddByEventID(ctx context.Context, eventID string) error
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -557,13 +557,14 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID int64, fi, secti
|
||||||
}
|
}
|
||||||
|
|
||||||
marketRecord := domain.CreateOddMarket{
|
marketRecord := domain.CreateOddMarket{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
MarketCategory: sectionName,
|
MarketCategory: sectionName,
|
||||||
MarketType: marketType,
|
MarketType: marketType,
|
||||||
MarketName: market.Name,
|
MarketName: market.Name,
|
||||||
MarketID: marketIDint,
|
MarketID: marketIDint,
|
||||||
UpdatedAt: updatedAt,
|
NumberOfOutcomes: int64(len(market.Odds)),
|
||||||
Odds: marketOdds,
|
UpdatedAt: updatedAt,
|
||||||
|
Odds: marketOdds,
|
||||||
// bwin won't reach this code so bet365 is hardcoded for now
|
// bwin won't reach this code so bet365 is hardcoded for now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -676,6 +677,10 @@ func (s *ServiceImpl) SaveOddsSetting(ctx context.Context, odd domain.CreateOddM
|
||||||
return s.store.SaveOddsSetting(ctx, odd)
|
return s.store.SaveOddsSetting(ctx, odd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) UpdateGlobalOddsSetting(ctx context.Context, odd domain.UpdateGlobalOddMarketSettings) error {
|
||||||
|
return s.store.UpdateGlobalOddsSetting(ctx, odd)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) SaveOddsSettingReq(ctx context.Context, companyID int64, req domain.CreateOddMarketSettingsReq) error {
|
func (s *ServiceImpl) SaveOddsSettingReq(ctx context.Context, companyID int64, req domain.CreateOddMarketSettingsReq) error {
|
||||||
|
|
||||||
odd, err := s.GetOddsWithSettingsByID(ctx, req.OddMarketID, companyID)
|
odd, err := s.GetOddsWithSettingsByID(ctx, req.OddMarketID, companyID)
|
||||||
|
|
@ -741,6 +746,14 @@ func (s *ServiceImpl) DeleteOddsForEvent(ctx context.Context, eventID int64) err
|
||||||
return s.store.DeleteOddsForEvent(ctx, eventID)
|
return s.store.DeleteOddsForEvent(ctx, eventID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) DeleteAllCompanyOddsSetting(ctx context.Context, companyID int64) error {
|
||||||
|
return s.store.DeleteAllCompanyOddsSetting(ctx, companyID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) DeleteCompanyOddsSettingByOddMarketID(ctx context.Context, companyID int64, oddMarketID int64) error {
|
||||||
|
return s.store.DeleteCompanyOddsSettingByOddMarketID(ctx, companyID, oddMarketID)
|
||||||
|
}
|
||||||
|
|
||||||
// func getString(v interface{}) string {
|
// func getString(v interface{}) string {
|
||||||
// if str, ok := v.(string); ok {
|
// if str, ok := v.(string); ok {
|
||||||
// return str
|
// return str
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,12 @@ type RaffleStore interface {
|
||||||
CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error
|
CreateRaffleWinner(ctx context.Context, raffleWinnerParams domain.RaffleWinnerParams) error
|
||||||
SetRaffleComplete(ctx context.Context, raffleID int32) error
|
SetRaffleComplete(ctx context.Context, raffleID int32) error
|
||||||
CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error)
|
CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error)
|
||||||
|
CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error)
|
||||||
|
|
||||||
CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error)
|
CreateRaffleTicket(ctx context.Context, raffleTicketParams domain.CreateRaffleTicket) (domain.RaffleTicket, error)
|
||||||
GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error)
|
GetUserRaffleTickets(ctx context.Context, userID int32) ([]domain.RaffleTicketRes, error)
|
||||||
SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error
|
SuspendRaffleTicket(ctx context.Context, raffleTicketID int32) error
|
||||||
UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error
|
UnSuspendRaffleTicket(ctx context.Context, raffleID int32) error
|
||||||
|
GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error)
|
||||||
|
GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,3 +64,15 @@ func (s *Service) UnSuspendRaffleTicket(ctx context.Context, raffleID int32) err
|
||||||
func (s *Service) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) {
|
func (s *Service) CheckValidSportRaffleFilter(ctx context.Context, raffleID int32, sportID, leagueID int64) (bool, error) {
|
||||||
return s.raffleStore.CheckValidSportRaffleFilter(ctx, raffleID, sportID, leagueID)
|
return s.raffleStore.CheckValidSportRaffleFilter(ctx, raffleID, sportID, leagueID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) CheckSportRaffleHasFilter(ctx context.Context, raffleID int32) (bool, error) {
|
||||||
|
return s.raffleStore.CheckSportRaffleHasFilter(ctx, raffleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetRaffleTicketCount(ctx context.Context, raffleID, userID int32) (int64, error) {
|
||||||
|
return s.raffleStore.GetRaffleTicketCount(ctx, raffleID, userID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetRaffleTicketLimit(ctx context.Context, raffleID int32) (int32, error) {
|
||||||
|
return s.raffleStore.GetRaffleTicketLimit(ctx, raffleID)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,11 @@ func (s *Service) GetDashboardSummary(ctx context.Context, filter domain.ReportF
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get sport/game metrics
|
// Get sport/game metrics
|
||||||
summary.TotalGames, summary.ActiveGames, summary.InactiveGames, err = s.virtulaGamesStore.GetGameCounts(ctx, filter)
|
// summary.TotalGames, summary.ActiveGames, summary.InactiveGames, err = s.virtulaGamesStore.GetGameCounts(ctx, filter)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
s.logger.Error("failed to get game counts", "error", err)
|
// s.logger.Error("failed to get game counts", "error", err)
|
||||||
return domain.DashboardSummary{}, err
|
// return domain.DashboardSummary{}, err
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Get company metrics
|
// Get company metrics
|
||||||
summary.TotalCompanies, summary.ActiveCompanies, summary.InactiveCompanies, err = s.companyStore.GetCompanyCounts(ctx, filter)
|
summary.TotalCompanies, summary.ActiveCompanies, summary.InactiveCompanies, err = s.companyStore.GetCompanyCounts(ctx, filter)
|
||||||
|
|
|
||||||
292
internal/services/result/notification.go
Normal file
292
internal/services/result/notification.go
Normal file
|
|
@ -0,0 +1,292 @@
|
||||||
|
package result
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) CheckAndSendResultNotifications(ctx context.Context, createdAfter time.Time) error {
|
||||||
|
|
||||||
|
resultLog, err := s.repo.GetAllResultLog(ctx, domain.ResultLogFilter{
|
||||||
|
CreatedAfter: domain.ValidTime{
|
||||||
|
Value: createdAfter,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error(
|
||||||
|
"Failed to get result log",
|
||||||
|
zap.Time("CreatedAfter", createdAfter),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resultLog) == 0 {
|
||||||
|
s.mongoLogger.Info(
|
||||||
|
"No results found for check and send result notification",
|
||||||
|
zap.Time("CreatedAfter", createdAfter),
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
totalResultLog := domain.ResultLog{
|
||||||
|
StatusNotFinishedCount: resultLog[0].StatusNotFinishedCount,
|
||||||
|
StatusPostponedCount: resultLog[0].StatusPostponedCount,
|
||||||
|
}
|
||||||
|
for _, log := range resultLog {
|
||||||
|
// Add all the bets
|
||||||
|
totalResultLog.StatusNotFinishedBets += log.StatusNotFinishedBets
|
||||||
|
totalResultLog.StatusPostponedBets += log.StatusPostponedBets
|
||||||
|
totalResultLog.StatusToBeFixedBets += log.StatusToBeFixedBets
|
||||||
|
totalResultLog.StatusRemovedBets += log.StatusRemovedBets
|
||||||
|
totalResultLog.StatusEndedBets += log.StatusEndedBets
|
||||||
|
|
||||||
|
totalResultLog.StatusToBeFixedCount += log.StatusToBeFixedCount
|
||||||
|
totalResultLog.StatusRemovedCount += log.StatusRemovedCount
|
||||||
|
totalResultLog.StatusEndedCount += log.StatusEndedCount
|
||||||
|
totalResultLog.RemovedCount += log.RemovedCount
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.SendAdminResultStatusErrorNotification(ctx, totalResultLog, createdAfter, time.Now())
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error(
|
||||||
|
"Failed to send admin result status notification",
|
||||||
|
zap.Time("CreatedAfter", createdAfter),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildHeadlineAndMessage(counts domain.ResultLog, createdAfter time.Time, endTime time.Time) (string, string) {
|
||||||
|
period := fmt.Sprintf("%s - %s", createdAfter.Format("02 Jan 2006"), endTime.Format("02 Jan 2006"))
|
||||||
|
|
||||||
|
totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount
|
||||||
|
totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets + counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets
|
||||||
|
if totalIssues == 0 {
|
||||||
|
return "✅ Successfully Processed Event Results", fmt.Sprintf(
|
||||||
|
"%d total ended events with %d total bets. No issues detected", counts.StatusEndedCount, totalBets,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := []string{}
|
||||||
|
if counts.StatusNotFinishedCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d unfinished with %d bets", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusToBeFixedCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d to-fix with %d bets", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusPostponedCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d postponed with %d bets", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusRemovedCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d removed with %d bets", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusEndedCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d ended with %d bets", counts.StatusEndedCount, counts.StatusEndedBets))
|
||||||
|
}
|
||||||
|
|
||||||
|
headline := "⚠️ Issues Found Processing Event Results"
|
||||||
|
message := fmt.Sprintf("Processed expired event results (%s): %s. Please review pending entries.",
|
||||||
|
period, strings.Join(parts, ", "))
|
||||||
|
return headline, message
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildHeadlineAndMessageEmail(counts domain.ResultLog, user domain.User, createdAfter time.Time, endTime time.Time) (string, string, string) {
|
||||||
|
period := fmt.Sprintf("%s - %s", createdAfter.Format("02 Jan 2006"), endTime.Format("02 Jan 2006"))
|
||||||
|
|
||||||
|
totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount +
|
||||||
|
counts.StatusPostponedCount + counts.StatusRemovedCount
|
||||||
|
totalEvents := counts.StatusEndedCount + counts.StatusNotFinishedCount +
|
||||||
|
counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount
|
||||||
|
totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets +
|
||||||
|
counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets
|
||||||
|
|
||||||
|
greeting := fmt.Sprintf("Hi %s %s,", user.FirstName, user.LastName)
|
||||||
|
|
||||||
|
if totalIssues == 0 {
|
||||||
|
headline := "✅ Weekly Results Report — All Events Processed Successfully"
|
||||||
|
plain := fmt.Sprintf(`%s
|
||||||
|
|
||||||
|
Weekly Results Summary (%s):
|
||||||
|
- %d Ended Events
|
||||||
|
- %d Total Bets
|
||||||
|
|
||||||
|
All events were processed successfully, and no issues were detected.
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
The System`, greeting, period, counts.StatusEndedCount, totalBets)
|
||||||
|
|
||||||
|
html := fmt.Sprintf(`<p>%s</p>
|
||||||
|
<h2>Weekly Results Summary</h2>
|
||||||
|
<p><em>Period: %s</em></p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>%d Ended Events</strong></li>
|
||||||
|
<li><strong>%d Total Bets</strong></li>
|
||||||
|
</ul>
|
||||||
|
<p>All events were processed successfully, and no issues were detected.</p>
|
||||||
|
<p>Best regards,<br>The System</p>`,
|
||||||
|
greeting, period, counts.StatusEndedCount, totalBets)
|
||||||
|
|
||||||
|
return headline, plain, html
|
||||||
|
}
|
||||||
|
|
||||||
|
partsPlain := []string{}
|
||||||
|
partsHTML := []string{}
|
||||||
|
|
||||||
|
if counts.StatusNotFinishedCount > 0 {
|
||||||
|
partsPlain = append(partsPlain,
|
||||||
|
fmt.Sprintf("- %d Incomplete Events (%d Bets)", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
||||||
|
partsHTML = append(partsHTML,
|
||||||
|
fmt.Sprintf("<li><strong>%d Incomplete Events</strong> (%d Bets)</li>", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusToBeFixedCount > 0 {
|
||||||
|
partsPlain = append(partsPlain,
|
||||||
|
fmt.Sprintf("- %d Requires Review (%d Bets)", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
||||||
|
partsHTML = append(partsHTML,
|
||||||
|
fmt.Sprintf("<li><strong>%d Requires Review</strong> (%d Bets)</li>", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusPostponedCount > 0 {
|
||||||
|
partsPlain = append(partsPlain,
|
||||||
|
fmt.Sprintf("- %d Postponed Events (%d Bets)", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
||||||
|
partsHTML = append(partsHTML,
|
||||||
|
fmt.Sprintf("<li><strong>%d Postponed Events</strong> (%d Bets)</li>", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusRemovedCount > 0 {
|
||||||
|
partsPlain = append(partsPlain,
|
||||||
|
fmt.Sprintf("- %d Discarded Events (%d Bets)", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
||||||
|
partsHTML = append(partsHTML,
|
||||||
|
fmt.Sprintf("<li><strong>%d Discarded Events</strong> (%d Bets)</li>", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
||||||
|
}
|
||||||
|
if counts.StatusEndedCount > 0 {
|
||||||
|
partsPlain = append(partsPlain,
|
||||||
|
fmt.Sprintf("- %d Successfully Ended Events (%d Bets)", counts.StatusEndedCount, counts.StatusEndedBets))
|
||||||
|
partsHTML = append(partsHTML,
|
||||||
|
fmt.Sprintf("<li><strong>%d Successfully Ended Events</strong> (%d Bets)</li>", counts.StatusEndedCount, counts.StatusEndedBets))
|
||||||
|
}
|
||||||
|
|
||||||
|
headline := "⚠️ Weekly Results Report — Review Required"
|
||||||
|
|
||||||
|
plain := fmt.Sprintf(`%s
|
||||||
|
|
||||||
|
Weekly Results Summary (%s):
|
||||||
|
%s
|
||||||
|
|
||||||
|
Totals:
|
||||||
|
- %d Events Processed
|
||||||
|
- %d Total Bets
|
||||||
|
|
||||||
|
Next Steps:
|
||||||
|
Some events require your attention. Please log into the admin dashboard to review pending issues.
|
||||||
|
|
||||||
|
Best regards,
|
||||||
|
The System`,
|
||||||
|
greeting,
|
||||||
|
period,
|
||||||
|
strings.Join(partsPlain, "\n"),
|
||||||
|
totalEvents,
|
||||||
|
totalBets,
|
||||||
|
)
|
||||||
|
|
||||||
|
html := fmt.Sprintf(`<p>%s</p>
|
||||||
|
<h2>Weekly Results Summary</h2>
|
||||||
|
<p><em>Period: %s</em></p>
|
||||||
|
<ul>
|
||||||
|
%s
|
||||||
|
</ul>
|
||||||
|
<h3>Totals</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>%d Events Processed</strong></li>
|
||||||
|
<li><strong>%d Total Bets</strong></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Next Steps:</strong><br>Some events require your attention. Please <a href="https://admin.fortunebets.net">log into the admin dashboard</a> to review pending issues.</p>
|
||||||
|
<p>Best regards,<br>The System</p>`,
|
||||||
|
greeting,
|
||||||
|
period,
|
||||||
|
strings.Join(partsHTML, "\n"),
|
||||||
|
totalEvents,
|
||||||
|
totalBets,
|
||||||
|
)
|
||||||
|
|
||||||
|
return headline, plain, html
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) SendAdminResultStatusErrorNotification(
|
||||||
|
ctx context.Context,
|
||||||
|
counts domain.ResultLog,
|
||||||
|
createdAfter time.Time,
|
||||||
|
endTime time.Time,
|
||||||
|
) error {
|
||||||
|
|
||||||
|
superAdmins, _, err := s.userSvc.GetAllUsers(ctx, domain.UserFilter{
|
||||||
|
Role: string(domain.RoleSuperAdmin),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error("failed to get super_admin recipients", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
metaBytes, err := json.Marshal(counts)
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error("failed to marshal metadata", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
headline, message := buildHeadlineAndMessage(counts, createdAfter, endTime)
|
||||||
|
|
||||||
|
notification := &domain.Notification{
|
||||||
|
ErrorSeverity: domain.NotificationErrorSeverityHigh,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
|
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||||
|
Level: domain.NotificationLevelWarning,
|
||||||
|
Reciever: domain.NotificationRecieverSideAdmin,
|
||||||
|
DeliveryChannel: domain.DeliveryChannelInApp,
|
||||||
|
Payload: domain.NotificationPayload{
|
||||||
|
Headline: headline,
|
||||||
|
Message: message,
|
||||||
|
},
|
||||||
|
Priority: 2,
|
||||||
|
Metadata: metaBytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
var sendErrors []error
|
||||||
|
for _, user := range superAdmins {
|
||||||
|
notification.RecipientID = user.ID
|
||||||
|
if err := s.notificationSvc.SendNotification(ctx, notification); err != nil {
|
||||||
|
s.mongoLogger.Error("failed to send admin notification",
|
||||||
|
zap.Int64("admin_id", user.ID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
sendErrors = append(sendErrors, err)
|
||||||
|
}
|
||||||
|
// notification.DeliveryChannel = domain.DeliveryChannelEmail
|
||||||
|
if user.Email == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
subject, plain, html := buildHeadlineAndMessageEmail(counts, user, createdAfter, endTime)
|
||||||
|
if err := s.messengerSvc.SendEmail(ctx, user.Email, plain, html, subject); err != nil {
|
||||||
|
s.mongoLogger.Error("failed to send admin result report email",
|
||||||
|
zap.Int64("admin_id", user.ID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
sendErrors = append(sendErrors, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sendErrors) > 0 {
|
||||||
|
return fmt.Errorf("sent with partial failure: %d errors", len(sendErrors))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -262,7 +262,6 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
|
||||||
eventLogger := s.mongoLogger.With(
|
eventLogger := s.mongoLogger.With(
|
||||||
zap.Int64("eventID", event.ID),
|
zap.Int64("eventID", event.ID),
|
||||||
)
|
)
|
||||||
|
|
||||||
result, err := s.FetchB365Result(ctx, event.SourceEventID)
|
result, err := s.FetchB365Result(ctx, event.SourceEventID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == ErrEventIsNotActive {
|
if err == ErrEventIsNotActive {
|
||||||
|
|
@ -457,276 +456,6 @@ func (s *Service) FetchB365ResultAndUpdateBets(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CheckAndSendResultNotifications(ctx context.Context, createdAfter time.Time) error {
|
|
||||||
|
|
||||||
resultLog, err := s.repo.GetAllResultLog(ctx, domain.ResultLogFilter{
|
|
||||||
CreatedAfter: domain.ValidTime{
|
|
||||||
Value: createdAfter,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
s.mongoLogger.Error(
|
|
||||||
"Failed to get result log",
|
|
||||||
zap.Time("CreatedAfter", createdAfter),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(resultLog) == 0 {
|
|
||||||
s.mongoLogger.Info(
|
|
||||||
"No results found for check and send result notification",
|
|
||||||
zap.Time("CreatedAfter", createdAfter),
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
totalResultLog := domain.ResultLog{
|
|
||||||
StatusNotFinishedCount: resultLog[0].StatusNotFinishedCount,
|
|
||||||
StatusPostponedCount: resultLog[0].StatusPostponedCount,
|
|
||||||
}
|
|
||||||
for _, log := range resultLog {
|
|
||||||
// Add all the bets
|
|
||||||
totalResultLog.StatusNotFinishedBets += log.StatusNotFinishedBets
|
|
||||||
totalResultLog.StatusPostponedBets += log.StatusPostponedBets
|
|
||||||
totalResultLog.StatusToBeFixedBets += log.StatusToBeFixedBets
|
|
||||||
totalResultLog.StatusRemovedBets += log.StatusRemovedBets
|
|
||||||
totalResultLog.StatusEndedBets += log.StatusEndedBets
|
|
||||||
|
|
||||||
totalResultLog.StatusToBeFixedCount += log.StatusToBeFixedCount
|
|
||||||
totalResultLog.StatusRemovedCount += log.StatusRemovedCount
|
|
||||||
totalResultLog.StatusEndedCount += log.StatusEndedCount
|
|
||||||
totalResultLog.RemovedCount += log.RemovedCount
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.SendAdminResultStatusErrorNotification(ctx, totalResultLog)
|
|
||||||
if err != nil {
|
|
||||||
s.mongoLogger.Error(
|
|
||||||
"Failed to send admin result status notification",
|
|
||||||
zap.Time("CreatedAfter", createdAfter),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildHeadlineAndMessage(counts domain.ResultLog) (string, string) {
|
|
||||||
|
|
||||||
totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount
|
|
||||||
totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets + counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets
|
|
||||||
if totalIssues == 0 {
|
|
||||||
return "✅ Successfully Processed Event Results", fmt.Sprintf(
|
|
||||||
"%d total ended events with %d total bets. No issues detected", counts.StatusEndedCount, totalBets,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := []string{}
|
|
||||||
if counts.StatusNotFinishedCount > 0 {
|
|
||||||
parts = append(parts, fmt.Sprintf("%d unfinished with %d bets", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusToBeFixedCount > 0 {
|
|
||||||
parts = append(parts, fmt.Sprintf("%d to-fix with %d bets", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusPostponedCount > 0 {
|
|
||||||
parts = append(parts, fmt.Sprintf("%d postponed with %d bets", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusRemovedCount > 0 {
|
|
||||||
parts = append(parts, fmt.Sprintf("%d removed with %d bets", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusEndedCount > 0 {
|
|
||||||
parts = append(parts, fmt.Sprintf("%d ended with %d bets", counts.StatusEndedCount, counts.StatusEndedBets))
|
|
||||||
}
|
|
||||||
|
|
||||||
headline := "⚠️ Issues Found Processing Event Results"
|
|
||||||
message := fmt.Sprintf("Processed expired event results: %s. Please review pending entries.", strings.Join(parts, ", "))
|
|
||||||
return headline, message
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildHeadlineAndMessageEmail(counts domain.ResultLog, user domain.User) (string, string, string) {
|
|
||||||
totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount +
|
|
||||||
counts.StatusPostponedCount + counts.StatusRemovedCount
|
|
||||||
totalEvents := counts.StatusEndedCount + counts.StatusNotFinishedCount +
|
|
||||||
counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount
|
|
||||||
totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets +
|
|
||||||
counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets
|
|
||||||
|
|
||||||
greeting := fmt.Sprintf("Hi %s %s,", user.FirstName, user.LastName)
|
|
||||||
|
|
||||||
if totalIssues == 0 {
|
|
||||||
headline := "✅ Weekly Results Report — All Events Processed Successfully"
|
|
||||||
plain := fmt.Sprintf(`%s
|
|
||||||
|
|
||||||
Weekly Results Summary:
|
|
||||||
- %d Ended Events
|
|
||||||
- %d Total Bets
|
|
||||||
|
|
||||||
All events were processed successfully, and no issues were detected.
|
|
||||||
|
|
||||||
Best regards,
|
|
||||||
The System`, greeting, counts.StatusEndedCount, totalBets)
|
|
||||||
|
|
||||||
html := fmt.Sprintf(`<p>%s</p>
|
|
||||||
<h2>Weekly Results Summary</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>%d Ended Events</strong></li>
|
|
||||||
<li><strong>%d Total Bets</strong></li>
|
|
||||||
</ul>
|
|
||||||
<p>All events were processed successfully, and no issues were detected.</p>
|
|
||||||
<p>Best regards,<br>The System</p>`,
|
|
||||||
greeting, counts.StatusEndedCount, totalBets)
|
|
||||||
|
|
||||||
return headline, plain, html
|
|
||||||
}
|
|
||||||
|
|
||||||
partsPlain := []string{}
|
|
||||||
partsHTML := []string{}
|
|
||||||
|
|
||||||
if counts.StatusNotFinishedCount > 0 {
|
|
||||||
partsPlain = append(partsPlain,
|
|
||||||
fmt.Sprintf("- %d Incomplete Events (%d Bets)", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
|
||||||
partsHTML = append(partsHTML,
|
|
||||||
fmt.Sprintf("<li><strong>%d Incomplete Events</strong> (%d Bets)</li>", counts.StatusNotFinishedCount, counts.StatusNotFinishedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusToBeFixedCount > 0 {
|
|
||||||
partsPlain = append(partsPlain,
|
|
||||||
fmt.Sprintf("- %d Requires Review (%d Bets)", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
|
||||||
partsHTML = append(partsHTML,
|
|
||||||
fmt.Sprintf("<li><strong>%d Requires Review</strong> (%d Bets)</li>", counts.StatusToBeFixedCount, counts.StatusToBeFixedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusPostponedCount > 0 {
|
|
||||||
partsPlain = append(partsPlain,
|
|
||||||
fmt.Sprintf("- %d Postponed Events (%d Bets)", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
|
||||||
partsHTML = append(partsHTML,
|
|
||||||
fmt.Sprintf("<li><strong>%d Postponed Events</strong> (%d Bets)</li>", counts.StatusPostponedCount, counts.StatusPostponedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusRemovedCount > 0 {
|
|
||||||
partsPlain = append(partsPlain,
|
|
||||||
fmt.Sprintf("- %d Discarded Events (%d Bets)", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
|
||||||
partsHTML = append(partsHTML,
|
|
||||||
fmt.Sprintf("<li><strong>%d Discarded Events</strong> (%d Bets)</li>", counts.StatusRemovedCount, counts.StatusRemovedBets))
|
|
||||||
}
|
|
||||||
if counts.StatusEndedCount > 0 {
|
|
||||||
partsPlain = append(partsPlain,
|
|
||||||
fmt.Sprintf("- %d Successfully Ended Events (%d Bets)", counts.StatusEndedCount, counts.StatusEndedBets))
|
|
||||||
partsHTML = append(partsHTML,
|
|
||||||
fmt.Sprintf("<li><strong>%d Successfully Ended Events</strong> (%d Bets)</li>", counts.StatusEndedCount, counts.StatusEndedBets))
|
|
||||||
}
|
|
||||||
|
|
||||||
headline := "⚠️ Weekly Results Report — Review Required"
|
|
||||||
|
|
||||||
plain := fmt.Sprintf(`%s
|
|
||||||
|
|
||||||
Weekly Results Summary:
|
|
||||||
%s
|
|
||||||
|
|
||||||
Totals:
|
|
||||||
- %d Events Processed
|
|
||||||
- %d Total Bets
|
|
||||||
|
|
||||||
Next Steps:
|
|
||||||
Some events require your attention. Please log into the admin dashboard to review pending issues.
|
|
||||||
|
|
||||||
Best regards,
|
|
||||||
The System`,
|
|
||||||
greeting,
|
|
||||||
strings.Join(partsPlain, "\n"),
|
|
||||||
totalEvents,
|
|
||||||
totalBets,
|
|
||||||
)
|
|
||||||
|
|
||||||
html := fmt.Sprintf(`<p>%s</p>
|
|
||||||
<h2>Weekly Results Summary</h2>
|
|
||||||
<ul>
|
|
||||||
%s
|
|
||||||
</ul>
|
|
||||||
<h3>Totals</h3>
|
|
||||||
<ul>
|
|
||||||
<li><strong>%d Events Processed</strong></li>
|
|
||||||
<li><strong>%d Total Bets</strong></li>
|
|
||||||
</ul>
|
|
||||||
<p><strong>Next Steps:</strong><br>Some events require your attention. Please <a href="https://admin.fortunebets.net">log into the admin dashboard</a> to review pending issues.</p>
|
|
||||||
<p>Best regards,<br>The System</p>`,
|
|
||||||
greeting,
|
|
||||||
strings.Join(partsHTML, "\n"),
|
|
||||||
totalEvents,
|
|
||||||
totalBets,
|
|
||||||
)
|
|
||||||
|
|
||||||
return headline, plain, html
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) SendAdminResultStatusErrorNotification(
|
|
||||||
ctx context.Context,
|
|
||||||
counts domain.ResultLog,
|
|
||||||
) error {
|
|
||||||
|
|
||||||
superAdmins, _, err := s.userSvc.GetAllUsers(ctx, domain.UserFilter{
|
|
||||||
Role: string(domain.RoleSuperAdmin),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
s.mongoLogger.Error("failed to get super_admin recipients", zap.Error(err))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
metaBytes, err := json.Marshal(counts)
|
|
||||||
if err != nil {
|
|
||||||
s.mongoLogger.Error("failed to marshal metadata", zap.Error(err))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
headline, message := buildHeadlineAndMessage(counts)
|
|
||||||
|
|
||||||
notification := &domain.Notification{
|
|
||||||
ErrorSeverity: domain.NotificationErrorSeverityHigh,
|
|
||||||
DeliveryStatus: domain.DeliveryStatusPending,
|
|
||||||
IsRead: false,
|
|
||||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
|
||||||
Level: domain.NotificationLevelWarning,
|
|
||||||
Reciever: domain.NotificationRecieverSideAdmin,
|
|
||||||
DeliveryChannel: domain.DeliveryChannelInApp,
|
|
||||||
Payload: domain.NotificationPayload{
|
|
||||||
Headline: headline,
|
|
||||||
Message: message,
|
|
||||||
},
|
|
||||||
Priority: 2,
|
|
||||||
Metadata: metaBytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
var sendErrors []error
|
|
||||||
for _, user := range superAdmins {
|
|
||||||
notification.RecipientID = user.ID
|
|
||||||
if err := s.notificationSvc.SendNotification(ctx, notification); err != nil {
|
|
||||||
s.mongoLogger.Error("failed to send admin notification",
|
|
||||||
zap.Int64("admin_id", user.ID),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
sendErrors = append(sendErrors, err)
|
|
||||||
}
|
|
||||||
// notification.DeliveryChannel = domain.DeliveryChannelEmail
|
|
||||||
if user.Email == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
subject, plain, html := buildHeadlineAndMessageEmail(counts, user)
|
|
||||||
if err := s.messengerSvc.SendEmail(ctx, user.Email, plain, html, subject); err != nil {
|
|
||||||
s.mongoLogger.Error("failed to send admin result report email",
|
|
||||||
zap.Int64("admin_id", user.ID),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
sendErrors = append(sendErrors, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(sendErrors) > 0 {
|
|
||||||
return fmt.Errorf("sent with partial failure: %d errors", len(sendErrors))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CheckAndUpdateExpiredB365Events(ctx context.Context) (int64, error) {
|
func (s *Service) CheckAndUpdateExpiredB365Events(ctx context.Context) (int64, error) {
|
||||||
events, _, err := s.repo.GetAllEvents(ctx, domain.EventFilter{
|
events, _, err := s.repo.GetAllEvents(ctx, domain.EventFilter{
|
||||||
LastStartTime: domain.ValidTime{
|
LastStartTime: domain.ValidTime{
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ func (s *Service) CreateShopDeposit(ctx context.Context, userID int64, role doma
|
||||||
// }
|
// }
|
||||||
|
|
||||||
newTransaction, err := s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
newTransaction, err := s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
||||||
Amount: domain.Currency(req.Amount),
|
Amount: domain.ToCurrency(req.Amount),
|
||||||
BranchID: branchID,
|
BranchID: branchID,
|
||||||
CompanyID: companyID,
|
CompanyID: companyID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ type VirtualGameService interface {
|
||||||
ProcessTournamentWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error)
|
ProcessTournamentWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error)
|
||||||
ProcessPromoWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error)
|
ProcessPromoWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error)
|
||||||
|
|
||||||
GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
// GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error)
|
||||||
ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error)
|
ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error)
|
||||||
RecommendGames(ctx context.Context, userID int64) ([]domain.GameRecommendation, error)
|
RecommendGames(ctx context.Context, userID int64) ([]domain.GameRecommendation, error)
|
||||||
AddFavoriteGame(ctx context.Context, userID, gameID int64) error
|
AddFavoriteGame(ctx context.Context, userID, gameID int64) error
|
||||||
|
|
|
||||||
|
|
@ -657,9 +657,9 @@ func (s *service) verifySignature(callback *domain.PopOKCallback) bool {
|
||||||
return expected == callback.Signature
|
return expected == callback.Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
|
// func (s *service) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) {
|
||||||
return s.repo.GetGameCounts(ctx, filter)
|
// return s.repo.GetGameCounts(ctx, filter)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *service) ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error) {
|
func (s *service) ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error) {
|
||||||
now := time.Now().Format("02-01-2006 15:04:05") // dd-mm-yyyy hh:mm:ss
|
now := time.Now().Format("02-01-2006 15:04:05") // dd-mm-yyyy hh:mm:ss
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitiateDirectDeposit creates a pending deposit request
|
// InitiateDirectDeposit creates a pending deposit request
|
||||||
|
|
@ -73,8 +72,8 @@ func (s *Service) VerifyDirectDeposit(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish wallet update event
|
// Publish wallet update event
|
||||||
go s.publishWalletUpdate(ctx, deposit.WalletID, deposit.Wallet.UserID,
|
// go s.publishWalletUpdate(ctx, deposit.WalletID, deposit.Wallet.UserID,
|
||||||
deposit.Wallet.Balance+deposit.Amount, "direct_deposit_verified")
|
// deposit.Wallet.Balance+deposit.Amount, "direct_deposit_verified")
|
||||||
|
|
||||||
// Update deposit status
|
// Update deposit status
|
||||||
deposit.Status = domain.DepositStatusCompleted
|
deposit.Status = domain.DepositStatusCompleted
|
||||||
|
|
@ -206,12 +205,12 @@ func (s *Service) notifyCustomerVerificationResult(ctx context.Context, deposit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) publishWalletUpdate(ctx context.Context, walletID, userID int64, newBalance domain.Currency, trigger string) {
|
// func (s *Service) publishWalletUpdate(ctx context.Context, walletID, userID int64, newBalance domain.Currency, trigger string) {
|
||||||
s.kafkaProducer.Publish(ctx, fmt.Sprint(walletID), event.WalletEvent{
|
// s.kafkaProducer.Publish(ctx, fmt.Sprint(walletID), event.WalletEvent{
|
||||||
EventType: event.WalletBalanceUpdated,
|
// EventType: event.WalletBalanceUpdated,
|
||||||
WalletID: walletID,
|
// WalletID: walletID,
|
||||||
UserID: userID,
|
// UserID: userID,
|
||||||
Balance: newBalance,
|
// Balance: newBalance,
|
||||||
Trigger: trigger,
|
// Trigger: trigger,
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@ package wallet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) GetAdminNotificationRecipients(ctx context.Context, walletID int64, walletType domain.WalletType) ([]int64, error) {
|
func (s *Service) GetAdminNotificationRecipients(ctx context.Context, walletID int64, walletType domain.WalletType) ([]int64, error) {
|
||||||
|
|
@ -63,12 +65,65 @@ func (s *Service) GetAdminNotificationRecipients(ctx context.Context, walletID i
|
||||||
return recipients, nil
|
return recipients, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) SendWalletUpdateNotification(ctx context.Context, wallet domain.Wallet) error {
|
||||||
|
raw, _ := json.Marshal(map[string]any{
|
||||||
|
"balance": wallet.Balance.Float32(),
|
||||||
|
"type": wallet.Type,
|
||||||
|
"timestamp": time.Now(),
|
||||||
|
})
|
||||||
|
|
||||||
|
headline := ""
|
||||||
|
message := ""
|
||||||
|
var receiver domain.NotificationRecieverSide
|
||||||
|
switch wallet.Type {
|
||||||
|
case domain.StaticWalletType:
|
||||||
|
headline = "Referral and Bonus Wallet Updated"
|
||||||
|
message = fmt.Sprintf("Your referral and bonus wallet balance is now %.2f", wallet.Balance.Float32())
|
||||||
|
receiver = domain.NotificationRecieverSideCustomer
|
||||||
|
case domain.RegularWalletType:
|
||||||
|
headline = "Wallet Updated"
|
||||||
|
message = fmt.Sprintf("Your wallet balance is now %.2f", wallet.Balance.Float32())
|
||||||
|
receiver = domain.NotificationRecieverSideCustomer
|
||||||
|
case domain.BranchWalletType:
|
||||||
|
headline = "Branch Wallet Updated"
|
||||||
|
message = fmt.Sprintf("branch wallet balance is now %.2f", wallet.Balance.Float32())
|
||||||
|
receiver = domain.NotificationRecieverSideBranchManager
|
||||||
|
case domain.CompanyWalletType:
|
||||||
|
headline = "Company Wallet Updated"
|
||||||
|
message = fmt.Sprintf("company wallet balance is now %.2f", wallet.Balance.Float32())
|
||||||
|
receiver = domain.NotificationRecieverSideAdmin
|
||||||
|
}
|
||||||
|
// Handle the wallet event: send notification
|
||||||
|
notification := &domain.Notification{
|
||||||
|
RecipientID: wallet.UserID,
|
||||||
|
DeliveryChannel: domain.DeliveryChannelInApp,
|
||||||
|
Reciever: receiver,
|
||||||
|
Type: domain.NotificationTypeWalletUpdated,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
|
Level: domain.NotificationLevelInfo,
|
||||||
|
Priority: 2,
|
||||||
|
Metadata: raw,
|
||||||
|
Payload: domain.NotificationPayload{
|
||||||
|
Headline: headline,
|
||||||
|
Message: message,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.notificationSvc.SendNotification(ctx, notification); err != nil {
|
||||||
|
s.mongoLogger.Error("[WalletSvc.SendWalletUpdateNotification] Failed to send notification",
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWallet domain.Wallet) error {
|
func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWallet domain.Wallet) error {
|
||||||
// Send different messages
|
// Send different messages
|
||||||
|
|
||||||
// Send notification to admin team
|
// Send notification to admin team
|
||||||
adminNotification := &domain.Notification{
|
adminNotification := &domain.Notification{
|
||||||
ErrorSeverity: "low",
|
ErrorSeverity: "low",
|
||||||
|
|
@ -115,16 +170,16 @@ func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWalle
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
adminNotification.DeliveryChannel = domain.DeliveryChannelEmail
|
// adminNotification.DeliveryChannel = domain.DeliveryChannelEmail
|
||||||
|
|
||||||
if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
// if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
||||||
s.mongoLogger.Error("failed to send email admin notification",
|
// s.mongoLogger.Error("failed to send email admin notification",
|
||||||
zap.Int64("admin_id", adminID),
|
// zap.Int64("admin_id", adminID),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
// zap.Time("timestamp", time.Now()),
|
||||||
)
|
// )
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package wallet
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/kafka"
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/kafka"
|
||||||
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
|
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
@ -18,7 +18,6 @@ type Service struct {
|
||||||
userSvc *user.Service
|
userSvc *user.Service
|
||||||
mongoLogger *zap.Logger
|
mongoLogger *zap.Logger
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
kafkaProducer *kafka.Producer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(
|
func NewService(
|
||||||
|
|
@ -29,7 +28,6 @@ func NewService(
|
||||||
userSvc *user.Service,
|
userSvc *user.Service,
|
||||||
mongoLogger *zap.Logger,
|
mongoLogger *zap.Logger,
|
||||||
logger *slog.Logger,
|
logger *slog.Logger,
|
||||||
kafkaProducer *kafka.Producer,
|
|
||||||
) *Service {
|
) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
walletStore: walletStore,
|
walletStore: walletStore,
|
||||||
|
|
@ -40,6 +38,5 @@ func NewService(
|
||||||
userSvc: userSvc,
|
userSvc: userSvc,
|
||||||
mongoLogger: mongoLogger,
|
mongoLogger: mongoLogger,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
kafkaProducer: kafkaProducer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,11 @@ func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiver
|
||||||
|
|
||||||
senderWallet, err := s.GetWalletByID(ctx, senderID)
|
senderWallet, err := s.GetWalletByID(ctx, senderID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return domain.Transfer{}, err
|
return domain.Transfer{}, err
|
||||||
}
|
}
|
||||||
|
if !senderWallet.IsActive {
|
||||||
|
return domain.Transfer{}, ErrWalletIsDisabled
|
||||||
|
}
|
||||||
|
|
||||||
if !senderWallet.IsTransferable {
|
if !senderWallet.IsTransferable {
|
||||||
fmt.Printf("Error: %d Sender Wallet is not transferable \n", senderWallet.ID)
|
fmt.Printf("Error: %d Sender Wallet is not transferable \n", senderWallet.ID)
|
||||||
|
|
@ -65,7 +67,9 @@ func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiver
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Transfer{}, err
|
return domain.Transfer{}, err
|
||||||
}
|
}
|
||||||
|
if !receiverWallet.IsActive {
|
||||||
|
return domain.Transfer{}, ErrWalletIsDisabled
|
||||||
|
}
|
||||||
if !receiverWallet.IsTransferable {
|
if !receiverWallet.IsTransferable {
|
||||||
fmt.Printf("Error: %d Receiver Wallet is not transferable \n", senderWallet.ID)
|
fmt.Printf("Error: %d Receiver Wallet is not transferable \n", senderWallet.ID)
|
||||||
return domain.Transfer{}, ErrReceiverWalletNotTransferable
|
return domain.Transfer{}, ErrReceiverWalletNotTransferable
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,17 @@ package wallet
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
// "fmt"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
"go.uber.org/zap"
|
||||||
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrBalanceInsufficient = errors.New("wallet balance is insufficient")
|
ErrBalanceInsufficient = errors.New("wallet balance is insufficient")
|
||||||
|
ErrWalletIsDisabled = errors.New("wallet is disabled")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
|
func (s *Service) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
|
||||||
|
|
@ -82,26 +85,37 @@ func (s *Service) GetAllBranchWallets(ctx context.Context) ([]domain.BranchWalle
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error {
|
func (s *Service) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error {
|
||||||
err := s.walletStore.UpdateBalance(ctx, id, balance)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
wallet, err := s.GetWalletByID(ctx, id)
|
wallet, err := s.GetWalletByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
if !wallet.IsActive {
|
||||||
s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.UserID), event.WalletEvent{
|
return ErrWalletIsDisabled
|
||||||
EventType: event.WalletBalanceUpdated,
|
}
|
||||||
WalletID: wallet.ID,
|
|
||||||
UserID: wallet.UserID,
|
err = s.walletStore.UpdateBalance(ctx, id, balance)
|
||||||
Balance: balance,
|
if err != nil {
|
||||||
WalletType: wallet.Type,
|
return err
|
||||||
Trigger: "UpdateBalance",
|
}
|
||||||
})
|
|
||||||
}()
|
// go func() {
|
||||||
|
// s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.UserID), event.WalletEvent{
|
||||||
|
// EventType: event.WalletBalanceUpdated,
|
||||||
|
// WalletID: wallet.ID,
|
||||||
|
// UserID: wallet.UserID,
|
||||||
|
// Balance: balance,
|
||||||
|
// WalletType: wallet.Type,
|
||||||
|
// Trigger: "UpdateBalance",
|
||||||
|
// })
|
||||||
|
// }()
|
||||||
|
|
||||||
|
if err := s.SendWalletUpdateNotification(ctx, wallet); err != nil {
|
||||||
|
s.mongoLogger.Info("Failed to send wallet update notification",
|
||||||
|
zap.Int64("wallet_id", wallet.ID),
|
||||||
|
zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -112,22 +126,29 @@ func (s *Service) AddToWallet(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Transfer{}, err
|
return domain.Transfer{}, err
|
||||||
}
|
}
|
||||||
|
if !wallet.IsActive {
|
||||||
|
return domain.Transfer{}, ErrWalletIsDisabled
|
||||||
|
}
|
||||||
err = s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount)
|
err = s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Transfer{}, err
|
return domain.Transfer{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
// go func() {
|
||||||
s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.ID), event.WalletEvent{
|
// s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.ID), event.WalletEvent{
|
||||||
EventType: event.WalletBalanceUpdated,
|
// EventType: event.WalletBalanceUpdated,
|
||||||
WalletID: wallet.ID,
|
// WalletID: wallet.ID,
|
||||||
UserID: wallet.UserID,
|
// UserID: wallet.UserID,
|
||||||
Balance: wallet.Balance + amount,
|
// Balance: wallet.Balance + amount,
|
||||||
WalletType: wallet.Type,
|
// WalletType: wallet.Type,
|
||||||
Trigger: "AddToWallet",
|
// Trigger: "AddToWallet",
|
||||||
})
|
// })
|
||||||
}()
|
// }()
|
||||||
|
if err := s.SendWalletUpdateNotification(ctx, wallet); err != nil {
|
||||||
|
s.mongoLogger.Info("Failed to send wallet update notification",
|
||||||
|
zap.Int64("wallet_id", wallet.ID),
|
||||||
|
zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
// Log the transfer here for reference
|
// Log the transfer here for reference
|
||||||
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
|
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
|
||||||
|
|
@ -153,6 +174,9 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
|
||||||
return domain.Transfer{}, err
|
return domain.Transfer{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !wallet.IsActive {
|
||||||
|
return domain.Transfer{}, ErrWalletIsDisabled
|
||||||
|
}
|
||||||
if wallet.Balance < amount {
|
if wallet.Balance < amount {
|
||||||
// Send Wallet low to admin
|
// Send Wallet low to admin
|
||||||
if wallet.Type == domain.CompanyWalletType || wallet.Type == domain.BranchWalletType {
|
if wallet.Type == domain.CompanyWalletType || wallet.Type == domain.BranchWalletType {
|
||||||
|
|
@ -173,8 +197,11 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
|
||||||
}
|
}
|
||||||
|
|
||||||
balance := wallet.Balance.Float32()
|
balance := wallet.Balance.Float32()
|
||||||
if balance < thresholds[0] {
|
for _, thresholds := range thresholds {
|
||||||
s.SendAdminWalletLowNotification(ctx, wallet)
|
if thresholds < balance && thresholds > (balance-amount.Float32()) {
|
||||||
|
s.SendAdminWalletLowNotification(ctx, wallet)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,16 +211,22 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
|
||||||
return domain.Transfer{}, nil
|
return domain.Transfer{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
// go func() {
|
||||||
s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.ID), event.WalletEvent{
|
// s.kafkaProducer.Publish(ctx, fmt.Sprint(wallet.ID), event.WalletEvent{
|
||||||
EventType: event.WalletBalanceUpdated,
|
// EventType: event.WalletBalanceUpdated,
|
||||||
WalletID: wallet.ID,
|
// WalletID: wallet.ID,
|
||||||
UserID: wallet.UserID,
|
// UserID: wallet.UserID,
|
||||||
Balance: wallet.Balance - amount,
|
// Balance: wallet.Balance - amount,
|
||||||
WalletType: wallet.Type,
|
// WalletType: wallet.Type,
|
||||||
Trigger: "DeductFromWallet",
|
// Trigger: "DeductFromWallet",
|
||||||
})
|
// })
|
||||||
}()
|
// }()
|
||||||
|
|
||||||
|
if err := s.SendWalletUpdateNotification(ctx, wallet); err != nil {
|
||||||
|
s.mongoLogger.Info("Failed to send wallet update notification",
|
||||||
|
zap.Int64("wallet_id", wallet.ID),
|
||||||
|
zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
// Log the transfer here for reference
|
// Log the transfer here for reference
|
||||||
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
|
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
betSvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
betSvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||||
enetpulse "github.com/SamuelTariku/FortuneBet-Backend/internal/services/enet_pulse"
|
enetpulse "github.com/SamuelTariku/FortuneBet-Backend/internal/services/enet_pulse"
|
||||||
eventsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
eventsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
|
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
|
||||||
oddssvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
oddssvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
|
||||||
resultsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
resultsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
|
||||||
|
|
@ -108,7 +109,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
mongoLogger.Info("Cron jobs started for event and odds services")
|
mongoLogger.Info("Cron jobs started for event and odds services")
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartTicketCrons(ticketService ticket.Service, mongoLogger *zap.Logger) {
|
func StartCleanupCrons(ticketService ticket.Service, notificationSvc *notificationservice.Service, mongoLogger *zap.Logger) {
|
||||||
c := cron.New(cron.WithSeconds())
|
c := cron.New(cron.WithSeconds())
|
||||||
|
|
||||||
schedule := []struct {
|
schedule := []struct {
|
||||||
|
|
@ -128,6 +129,19 @@ func StartTicketCrons(ticketService ticket.Service, mongoLogger *zap.Logger) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
spec: "0 0 0 * * 1", // Every Monday (Weekly)
|
||||||
|
task: func() {
|
||||||
|
mongoLogger.Info("Deleting old notifications")
|
||||||
|
if err := notificationSvc.DeleteOldNotifications(context.Background()); err != nil {
|
||||||
|
mongoLogger.Error("Failed to remove old notifications",
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
mongoLogger.Info("Successfully deleted old notifications")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, job := range schedule {
|
for _, job := range schedule {
|
||||||
|
|
@ -261,7 +275,7 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreSports(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreSports(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store sports", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store sports", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing sports")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing sports\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2️⃣ Tournament Templates
|
// 2️⃣ Tournament Templates
|
||||||
|
|
@ -269,7 +283,7 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreTournamentTemplates(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreTournamentTemplates(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store tournament templates", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store tournament templates", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing tournament templates")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing tournament templates\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3️⃣ Tournaments
|
// 3️⃣ Tournaments
|
||||||
|
|
@ -277,7 +291,7 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreTournaments(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreTournaments(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store tournaments", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store tournaments", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing tournaments")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing tournaments\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4️⃣ Tournament Stages
|
// 4️⃣ Tournament Stages
|
||||||
|
|
@ -285,16 +299,16 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreTournamentStages(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreTournamentStages(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store tournament stages", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store tournament stages", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing tournament stages")
|
mongoLogger.Info("✅ \n\nCompleted fetching and storing tournament stages\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5️⃣ Fixtures
|
// // 5️⃣ Fixtures
|
||||||
mongoLogger.Info("Began fetching and storing fixtures cron task")
|
mongoLogger.Info("Began fetching and storing fixtures cron task")
|
||||||
today := time.Now().Format("2006-01-02")
|
today := time.Now().Format("2006-01-02")
|
||||||
if err := enetPulseSvc.FetchAndStoreFixtures(ctx, today); err != nil {
|
if err := enetPulseSvc.FetchAndStoreFixtures(ctx, today); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store fixtures", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store fixtures", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing fixtures")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing fixtures\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6️⃣ Results
|
// 6️⃣ Results
|
||||||
|
|
@ -302,7 +316,7 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreResults(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreResults(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store results", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store results", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing results")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing results\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7 Outcome Types
|
// 7 Outcome Types
|
||||||
|
|
@ -310,15 +324,15 @@ func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger
|
||||||
if err := enetPulseSvc.FetchAndStoreOutcomeTypes(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStoreOutcomeTypes(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store outcome_types", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store outcome_types", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing outcome_types")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing outcome_types\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8 Outcome Types
|
// 8 Preodds
|
||||||
mongoLogger.Info("Began fetching and storing preodds cron task")
|
mongoLogger.Info("Began fetching and storing preodds cron task")
|
||||||
if err := enetPulseSvc.FetchAndStorePreodds(ctx); err != nil {
|
if err := enetPulseSvc.FetchAndStorePreodds(ctx); err != nil {
|
||||||
mongoLogger.Error("Failed to fetch and store preodds", zap.Error(err))
|
mongoLogger.Error("Failed to fetch and store preodds", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
mongoLogger.Info("✅ Completed fetching and storing preodds")
|
mongoLogger.Info("\n\n✅ Completed fetching and storing preodds\n\n")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -103,25 +103,25 @@ func (h *Handler) CreateAdmin(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create admin:"+err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create admin:"+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.CompanyID != nil {
|
// if req.CompanyID != nil {
|
||||||
_, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
// _, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
||||||
ID: *req.CompanyID,
|
// ID: *req.CompanyID,
|
||||||
AdminID: domain.ValidInt64{
|
// AdminID: domain.ValidInt64{
|
||||||
Value: newUser.ID,
|
// Value: newUser.ID,
|
||||||
Valid: true,
|
// Valid: true,
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
h.mongoLoggerSvc.Error("failed to update company with new admin",
|
// h.mongoLoggerSvc.Error("failed to update company with new admin",
|
||||||
zap.Int64("status_code", fiber.StatusInternalServerError),
|
// zap.Int64("status_code", fiber.StatusInternalServerError),
|
||||||
zap.Int64("company_id", *req.CompanyID),
|
// zap.Int64("company_id", *req.CompanyID),
|
||||||
zap.Int64("admin_id", newUser.ID),
|
// zap.Int64("admin_id", newUser.ID),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
// zap.Time("timestamp", time.Now()),
|
||||||
)
|
// )
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company"+err.Error())
|
// return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company"+err.Error())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
h.mongoLoggerSvc.Info("admin created successfully",
|
h.mongoLoggerSvc.Info("admin created successfully",
|
||||||
zap.Int64("admin_id", newUser.ID),
|
zap.Int64("admin_id", newUser.ID),
|
||||||
|
|
@ -196,7 +196,7 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
|
||||||
Valid: true,
|
Valid: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companyFilter := int64(c.QueryInt("company_id"))
|
companyFilter := int64(c.QueryInt("company_id"))
|
||||||
filter := domain.UserFilter{
|
filter := domain.UserFilter{
|
||||||
Role: string(domain.RoleAdmin),
|
Role: string(domain.RoleAdmin),
|
||||||
|
|
@ -283,7 +283,7 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
|
||||||
zap.Time("timestamp", time.Now()),
|
zap.Time("timestamp", time.Now()),
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value, int(total))
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value+1, int(total))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAdminByID godoc
|
// GetAdminByID godoc
|
||||||
|
|
@ -451,24 +451,24 @@ func (h *Handler) UpdateAdmin(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update admin:"+err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update admin:"+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.CompanyID != nil {
|
// if req.CompanyID != nil {
|
||||||
_, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
// _, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
|
||||||
ID: *req.CompanyID,
|
// ID: *req.CompanyID,
|
||||||
AdminID: domain.ValidInt64{
|
// AdminID: domain.ValidInt64{
|
||||||
Value: AdminID,
|
// Value: AdminID,
|
||||||
Valid: true,
|
// Valid: true,
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
h.mongoLoggerSvc.Error("UpdateAdmin failed to update company",
|
// h.mongoLoggerSvc.Error("UpdateAdmin failed to update company",
|
||||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
zap.Int64("admin_id", AdminID),
|
// zap.Int64("admin_id", AdminID),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
// zap.Time("timestamp", time.Now()),
|
||||||
)
|
// )
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company:"+err.Error())
|
// return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company:"+err.Error())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
h.mongoLoggerSvc.Info("UpdateAdmin succeeded",
|
h.mongoLoggerSvc.Info("UpdateAdmin succeeded",
|
||||||
zap.Int("status_code", fiber.StatusOK),
|
zap.Int("status_code", fiber.StatusOK),
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ type loginAdminRes struct {
|
||||||
func (h *Handler) LoginAdmin(c *fiber.Ctx) error {
|
func (h *Handler) LoginAdmin(c *fiber.Ctx) error {
|
||||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
if !companyID.Valid {
|
if !companyID.Valid {
|
||||||
h.BadRequestLogger().Error("invalid company id")
|
h.BadRequestLogger().Error("invalid company id")
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
||||||
}
|
}
|
||||||
var req loginAdminReq
|
var req loginAdminReq
|
||||||
|
|
|
||||||
|
|
@ -259,24 +259,53 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI
|
||||||
sportAndLeagueIDs = append(sportAndLeagueIDs, ids)
|
sportAndLeagueIDs = append(sportAndLeagueIDs, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("sportAndLeagueIDs: ", sportAndLeagueIDs)
|
|
||||||
|
|
||||||
for _, raffle := range raffles {
|
for _, raffle := range raffles {
|
||||||
// TODO: only fetch pending raffles from db
|
// TODO: only fetch pending raffles from db
|
||||||
if raffle.Status == "completed" {
|
if raffle.Status == "completed" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// only require one sport and league combo to be valide to make the raffle ticket
|
raffleTicketLimit, err := h.raffleSvc.GetRaffleTicketLimit(c.Context(), raffle.ID)
|
||||||
foundValid := false
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check raffle ticke count
|
||||||
|
userTicketCount, err := h.raffleSvc.GetRaffleTicketCount(c.Context(), raffle.ID, int32(userID))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if userTicketCount == int64(raffleTicketLimit) {
|
||||||
|
h.mongoLoggerSvc.Info("User reached max ticket count allowed for current raffle",
|
||||||
|
zap.Int("status_code", fiber.StatusForbidden),
|
||||||
|
zap.Int64("raffleID", int64(raffle.ID)),
|
||||||
|
zap.Int64("userID", userID),
|
||||||
|
zap.Int64("companyID", companyID),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty raffle filter means there is no filter (all is allowed)
|
||||||
|
hasFilter, err := h.raffleSvc.CheckSportRaffleHasFilter(c.Context(), raffle.ID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
foundValid := !hasFilter
|
||||||
|
|
||||||
|
// only require one sport and league combo to be valid to make the raffle ticket
|
||||||
for _, sportAndLeagueID := range sportAndLeagueIDs {
|
for _, sportAndLeagueID := range sportAndLeagueIDs {
|
||||||
|
if foundValid {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
res, err := h.raffleSvc.CheckValidSportRaffleFilter(c.Context(), raffle.ID, sportAndLeagueID[0], sportAndLeagueID[1])
|
res, err := h.raffleSvc.CheckValidSportRaffleFilter(c.Context(), raffle.ID, sportAndLeagueID[0], sportAndLeagueID[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(sportAndLeagueID, res)
|
|
||||||
|
|
||||||
foundValid = foundValid || res
|
foundValid = foundValid || res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,7 +318,7 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI
|
||||||
UserID: int32(userID),
|
UserID: int32(userID),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := h.raffleSvc.CreateRaffleTicket(c.Context(), raffleTicket)
|
_, err = h.raffleSvc.CreateRaffleTicket(c.Context(), raffleTicket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Error("Failed to create raffle ticket",
|
h.mongoLoggerSvc.Error("Failed to create raffle ticket",
|
||||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
|
|
@ -552,6 +581,25 @@ func (h *Handler) GetAllBet(c *fiber.Ctx) error {
|
||||||
Valid: true,
|
Valid: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var companyID domain.ValidInt64
|
||||||
|
companyIDQuery := c.Query("company_id")
|
||||||
|
if companyIDQuery != "" {
|
||||||
|
companyIDParsed, err := strconv.ParseInt(companyIDQuery, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.mongoLoggerSvc.Info("invalid company_id format",
|
||||||
|
zap.String("company_id", companyIDQuery),
|
||||||
|
zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid company_id format")
|
||||||
|
}
|
||||||
|
companyID = domain.ValidInt64{
|
||||||
|
Value: companyIDParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
bets, total, err := h.betSvc.GetAllBets(c.Context(), domain.BetFilter{
|
bets, total, err := h.betSvc.GetAllBets(c.Context(), domain.BetFilter{
|
||||||
IsShopBet: isShopBet,
|
IsShopBet: isShopBet,
|
||||||
Query: searchString,
|
Query: searchString,
|
||||||
|
|
@ -560,6 +608,7 @@ func (h *Handler) GetAllBet(c *fiber.Ctx) error {
|
||||||
Status: statusFilter,
|
Status: statusFilter,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
|
CompanyID: companyID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Error("Failed to get all bets",
|
h.mongoLoggerSvc.Error("Failed to get all bets",
|
||||||
|
|
@ -594,7 +643,6 @@ func (h *Handler) GetAllTenantBets(c *fiber.Ctx) error {
|
||||||
h.BadRequestLogger().Error("invalid company id", zap.Any("company_id", companyID))
|
h.BadRequestLogger().Error("invalid company id", zap.Any("company_id", companyID))
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
||||||
}
|
}
|
||||||
role := c.Locals("role").(domain.Role)
|
|
||||||
|
|
||||||
page := c.QueryInt("page", 1)
|
page := c.QueryInt("page", 1)
|
||||||
pageSize := c.QueryInt("page_size", 10)
|
pageSize := c.QueryInt("page_size", 10)
|
||||||
|
|
@ -608,7 +656,7 @@ func (h *Handler) GetAllTenantBets(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
var isShopBet domain.ValidBool
|
var isShopBet domain.ValidBool
|
||||||
isShopBetQuery := c.Query("is_shop")
|
isShopBetQuery := c.Query("is_shop")
|
||||||
if isShopBetQuery != "" && role == domain.RoleSuperAdmin {
|
if isShopBetQuery != "" {
|
||||||
isShopBetParse, err := strconv.ParseBool(isShopBetQuery)
|
isShopBetParse, err := strconv.ParseBool(isShopBetQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Info("failed to parse is_shop_bet",
|
h.mongoLoggerSvc.Info("failed to parse is_shop_bet",
|
||||||
|
|
@ -726,6 +774,8 @@ func (h *Handler) GetAllTenantBets(c *fiber.Ctx) error {
|
||||||
// @Failure 500 {object} response.APIResponse
|
// @Failure 500 {object} response.APIResponse
|
||||||
// @Router /api/v1/sport/bet/{id} [get]
|
// @Router /api/v1/sport/bet/{id} [get]
|
||||||
func (h *Handler) GetBetByID(c *fiber.Ctx) error {
|
func (h *Handler) GetBetByID(c *fiber.Ctx) error {
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
|
||||||
betID := c.Params("id")
|
betID := c.Params("id")
|
||||||
id, err := strconv.ParseInt(betID, 10, 64)
|
id, err := strconv.ParseInt(betID, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -751,6 +801,15 @@ func (h *Handler) GetBetByID(c *fiber.Ctx) error {
|
||||||
|
|
||||||
res := domain.ConvertBet(bet)
|
res := domain.ConvertBet(bet)
|
||||||
|
|
||||||
|
if companyID.Valid && bet.CompanyID != companyID.Value {
|
||||||
|
h.mongoLoggerSvc.Warn("Warn - Company is trying to access another companies bet",
|
||||||
|
zap.Int64("betID", id),
|
||||||
|
zap.Int("status_code", fiber.StatusNotFound),
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Failed to retrieve bet")
|
||||||
|
}
|
||||||
// h.mongoLoggerSvc.Info("Bet retrieved successfully",
|
// h.mongoLoggerSvc.Info("Bet retrieved successfully",
|
||||||
// zap.Int64("betID", id),
|
// zap.Int64("betID", id),
|
||||||
// zap.Int("status_code", fiber.StatusOK),
|
// zap.Int("status_code", fiber.StatusOK),
|
||||||
|
|
|
||||||
|
|
@ -611,6 +611,8 @@ func (h *Handler) GetAllBranches(c *fiber.Ctx) error {
|
||||||
// @Failure 500 {object} response.APIResponse
|
// @Failure 500 {object} response.APIResponse
|
||||||
// @Router /api/v1/search/branch [get]
|
// @Router /api/v1/search/branch [get]
|
||||||
func (h *Handler) SearchBranch(c *fiber.Ctx) error {
|
func (h *Handler) SearchBranch(c *fiber.Ctx) error {
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
|
||||||
// Get search query from request
|
// Get search query from request
|
||||||
searchQuery := c.Query("q")
|
searchQuery := c.Query("q")
|
||||||
if searchQuery == "" {
|
if searchQuery == "" {
|
||||||
|
|
@ -622,7 +624,7 @@ func (h *Handler) SearchBranch(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the service to search for branches
|
// Call the service to search for branches
|
||||||
branches, err := h.branchSvc.SearchBranchByName(c.Context(), searchQuery)
|
branches, err := h.branchSvc.SearchBranchByName(c.Context(), searchQuery, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Info("Failed to search branches",
|
h.mongoLoggerSvc.Info("Failed to search branches",
|
||||||
zap.String("query", searchQuery),
|
zap.String("query", searchQuery),
|
||||||
|
|
|
||||||
|
|
@ -227,11 +227,8 @@ func (h *Handler) GetAllCashiers(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
cashiers, total, err := h.userSvc.GetAllCashiers(c.Context(), domain.UserFilter{
|
cashiers, total, err := h.userSvc.GetAllCashiers(c.Context(), filter)
|
||||||
Query: searchString,
|
|
||||||
CreatedBefore: createdBefore,
|
|
||||||
CreatedAfter: createdAfter,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Error("failed to get all cashiers",
|
h.mongoLoggerSvc.Error("failed to get all cashiers",
|
||||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -82,17 +83,31 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error {
|
||||||
AdminID: user.ID,
|
AdminID: user.ID,
|
||||||
WalletID: newWallet.ID,
|
WalletID: newWallet.ID,
|
||||||
DeductedPercentage: req.DeductedPercentage,
|
DeductedPercentage: req.DeductedPercentage,
|
||||||
|
Slug: req.Slug,
|
||||||
|
IsActive: req.IsActive,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, domain.ErrWalletIDDuplicate) {
|
||||||
|
h.mongoLoggerSvc.Error("CreateCompanyReq failed to create company",
|
||||||
|
zap.Int64("userID", user.ID),
|
||||||
|
zap.String("name", req.Name),
|
||||||
|
zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
)
|
||||||
|
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "this admin already has a company assigned to him")
|
||||||
|
}
|
||||||
|
|
||||||
h.mongoLoggerSvc.Error("CreateCompanyReq failed to create company",
|
h.mongoLoggerSvc.Error("CreateCompanyReq failed to create company",
|
||||||
zap.Int64("userID", user.ID),
|
zap.Int64("userID", user.ID),
|
||||||
zap.String("name", req.Name),
|
zap.String("name", req.Name),
|
||||||
zap.String("Name", req.Name),
|
|
||||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
zap.Time("timestamp", time.Now()),
|
||||||
)
|
)
|
||||||
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,11 +376,12 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
company, err := h.companySvc.UpdateCompany(c.Context(), domain.ConvertUpdateCompanyReq(req))
|
err = h.companySvc.UpdateCompany(c.Context(), domain.ConvertUpdateCompanyReq(req, id))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.mongoLoggerSvc.Error("Failed to update company",
|
h.mongoLoggerSvc.Error("Failed to update company",
|
||||||
zap.Int64("companyID", id),
|
zap.Int64("companyID", id),
|
||||||
|
zap.Any("req", req),
|
||||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
zap.Time("timestamp", time.Now()),
|
zap.Time("timestamp", time.Now()),
|
||||||
|
|
@ -373,9 +389,7 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
res := domain.ConvertCompany(company)
|
return response.WriteJSON(c, fiber.StatusOK, "Company Updated", nil, nil)
|
||||||
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Company Updated", res, nil)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,62 @@ func (h *Handler) GetAllResults(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllPreodds godoc
|
||||||
|
// @Summary Get all preodds
|
||||||
|
// @Description Fetches all EnetPulse pre-match odds stored in the database
|
||||||
|
// @Tags EnetPulse - Preodds
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} domain.Response{data=[]domain.EnetpulsePreodds}
|
||||||
|
// @Failure 502 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/enetpulse/preodds [get]
|
||||||
|
func (h *Handler) GetAllPreodds(c *fiber.Ctx) error {
|
||||||
|
// Call service
|
||||||
|
preodds, err := h.enetPulseSvc.GetAllPreodds(c.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Println("GetAllPreodds error:", err)
|
||||||
|
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||||
|
Message: "Failed to fetch EnetPulse preodds",
|
||||||
|
Error: err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "EnetPulse preodds fetched successfully",
|
||||||
|
Data: preodds,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
Success: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFixturesWithPreodds godoc
|
||||||
|
// @Summary Get fixtures with preodds
|
||||||
|
// @Description Fetches all EnetPulse fixtures along with their associated pre-match odds
|
||||||
|
// @Tags EnetPulse - Fixtures
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} domain.Response{data=[]domain.EnetpulseFixtureWithPreodds}
|
||||||
|
// @Failure 502 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/enetpulse/fixtures/preodds [get]
|
||||||
|
func (h *Handler) GetFixturesWithPreodds(c *fiber.Ctx) error {
|
||||||
|
// Call service
|
||||||
|
fixtures, err := h.enetPulseSvc.GetFixturesWithPreodds(c.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Println("GetFixturesWithPreodds error:", err)
|
||||||
|
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
|
||||||
|
Message: "Failed to fetch EnetPulse fixtures with preodds",
|
||||||
|
Error: err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return success response
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "EnetPulse fixtures with preodds fetched successfully",
|
||||||
|
Data: fixtures,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
Success: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Helper: parse comma-separated string into []int
|
// Helper: parse comma-separated string into []int
|
||||||
func parseIntSlice(input string) []int {
|
func parseIntSlice(input string) []int {
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,40 @@ func (h *Handler) GetAllEvents(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isActiveQuery := c.Query("is_active")
|
||||||
|
var isActive domain.ValidBool
|
||||||
|
if isActiveQuery != "" {
|
||||||
|
isActiveParsed, err := strconv.ParseBool(isActiveQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("Failed to parse isActive",
|
||||||
|
zap.String("is_active", isActiveQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Failed to parse is_active")
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive = domain.ValidBool{
|
||||||
|
Value: isActiveParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statusQuery := c.Query("status")
|
||||||
|
var eventStatus domain.ValidEventStatus
|
||||||
|
if statusQuery != "" {
|
||||||
|
eventStatusParsed, err := domain.ParseEventStatus(statusQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("Failed to parse statusQuery",
|
||||||
|
zap.String("is_featured", isFeaturedQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid event status string")
|
||||||
|
}
|
||||||
|
eventStatus = domain.ValidEventStatus{
|
||||||
|
Value: eventStatusParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
events, total, err := h.eventSvc.GetAllEvents(
|
events, total, err := h.eventSvc.GetAllEvents(
|
||||||
c.Context(), domain.EventFilter{
|
c.Context(), domain.EventFilter{
|
||||||
SportID: sportID,
|
SportID: sportID,
|
||||||
|
|
@ -146,6 +180,8 @@ func (h *Handler) GetAllEvents(c *fiber.Ctx) error {
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
CountryCode: countryCode,
|
CountryCode: countryCode,
|
||||||
Featured: isFeatured,
|
Featured: isFeatured,
|
||||||
|
Active: isActive,
|
||||||
|
Status: eventStatus,
|
||||||
})
|
})
|
||||||
|
|
||||||
// fmt.Printf("League ID: %v", leagueID)
|
// fmt.Printf("League ID: %v", leagueID)
|
||||||
|
|
@ -234,22 +270,27 @@ func (h *Handler) GetTenantUpcomingEvents(c *fiber.Ctx) error {
|
||||||
Valid: searchQuery != "",
|
Valid: searchQuery != "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// firstStartTimeQuery := c.Query("first_start_time")
|
firstStartTimeQuery := c.Query("first_start_time")
|
||||||
// var firstStartTime domain.ValidTime
|
var firstStartTime domain.ValidTime
|
||||||
// if firstStartTimeQuery != "" {
|
if firstStartTimeQuery != "" {
|
||||||
// firstStartTimeParsed, err := time.Parse(time.RFC3339, firstStartTimeQuery)
|
firstStartTimeParsed, err := time.Parse(time.RFC3339, firstStartTimeQuery)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// h.BadRequestLogger().Info("invalid start_time format",
|
h.BadRequestLogger().Info("invalid start_time format",
|
||||||
// zap.String("first_start_time", firstStartTimeQuery),
|
zap.String("first_start_time", firstStartTimeQuery),
|
||||||
// zap.Error(err),
|
zap.Error(err),
|
||||||
// )
|
)
|
||||||
// return fiber.NewError(fiber.StatusBadRequest, "Invalid start_time format")
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid start_time format")
|
||||||
// }
|
}
|
||||||
// firstStartTime = domain.ValidTime{
|
firstStartTime = domain.ValidTime{
|
||||||
// Value: firstStartTimeParsed,
|
Value: firstStartTimeParsed,
|
||||||
// Valid: true,
|
Valid: true,
|
||||||
// }
|
}
|
||||||
// }
|
} else {
|
||||||
|
firstStartTime = domain.ValidTime{
|
||||||
|
Value: time.Now(),
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastStartTimeQuery := c.Query("last_start_time")
|
lastStartTimeQuery := c.Query("last_start_time")
|
||||||
var lastStartTime domain.ValidTime
|
var lastStartTime domain.ValidTime
|
||||||
|
|
@ -297,10 +338,7 @@ func (h *Handler) GetTenantUpcomingEvents(c *fiber.Ctx) error {
|
||||||
SportID: sportID,
|
SportID: sportID,
|
||||||
LeagueID: leagueID,
|
LeagueID: leagueID,
|
||||||
Query: searchString,
|
Query: searchString,
|
||||||
FirstStartTime: domain.ValidTime{
|
FirstStartTime: firstStartTime,
|
||||||
Value: time.Now(),
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
LastStartTime: lastStartTime,
|
LastStartTime: lastStartTime,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
|
|
@ -334,6 +372,200 @@ func (h *Handler) GetTenantUpcomingEvents(c *fiber.Ctx) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary Retrieve all upcoming events with settings
|
||||||
|
// @Description Retrieve all upcoming events settings from the database
|
||||||
|
// @Tags prematch
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param page query int false "Page number"
|
||||||
|
// @Param page_size query int false "Page size"
|
||||||
|
// @Param league_id query string false "League ID Filter"
|
||||||
|
// @Param sport_id query string false "Sport ID Filter"
|
||||||
|
// @Param cc query string false "Country Code Filter"
|
||||||
|
// @Param first_start_time query string false "Start Time"
|
||||||
|
// @Param last_start_time query string false "End Time"
|
||||||
|
// @Success 200 {array} domain.BaseEvent
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /api/v1/{tenant_slug}/events [get]
|
||||||
|
func (h *Handler) GetTenantEvents(c *fiber.Ctx) error {
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
if !companyID.Valid {
|
||||||
|
h.BadRequestLogger().Error("invalid company id")
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
leagueIDQuery := c.Query("league_id")
|
||||||
|
var leagueID domain.ValidInt64
|
||||||
|
if leagueIDQuery != "" {
|
||||||
|
leagueIDInt, err := strconv.ParseInt(leagueIDQuery, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("invalid league id",
|
||||||
|
zap.String("league_id", leagueIDQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
||||||
|
}
|
||||||
|
leagueID = domain.ValidInt64{
|
||||||
|
Value: leagueIDInt,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sportIDQuery := c.Query("sport_id")
|
||||||
|
var sportID domain.ValidInt32
|
||||||
|
if sportIDQuery != "" {
|
||||||
|
sportIDint, err := strconv.Atoi(sportIDQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("invalid sport id",
|
||||||
|
zap.String("sportID", sportIDQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid sport id")
|
||||||
|
}
|
||||||
|
sportID = domain.ValidInt32{
|
||||||
|
Value: int32(sportIDint),
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
searchQuery := c.Query("query")
|
||||||
|
searchString := domain.ValidString{
|
||||||
|
Value: searchQuery,
|
||||||
|
Valid: searchQuery != "",
|
||||||
|
}
|
||||||
|
|
||||||
|
firstStartTimeQuery := c.Query("first_start_time")
|
||||||
|
var firstStartTime domain.ValidTime
|
||||||
|
if firstStartTimeQuery != "" {
|
||||||
|
firstStartTimeParsed, err := time.Parse(time.RFC3339, firstStartTimeQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("invalid start_time format",
|
||||||
|
zap.String("first_start_time", firstStartTimeQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid start_time format")
|
||||||
|
}
|
||||||
|
firstStartTime = domain.ValidTime{
|
||||||
|
Value: firstStartTimeParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastStartTimeQuery := c.Query("last_start_time")
|
||||||
|
var lastStartTime domain.ValidTime
|
||||||
|
if lastStartTimeQuery != "" {
|
||||||
|
lastStartTimeParsed, err := time.Parse(time.RFC3339, lastStartTimeQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("invalid last_start_time format",
|
||||||
|
zap.String("last_start_time", lastStartTimeQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid start_time format")
|
||||||
|
}
|
||||||
|
lastStartTime = domain.ValidTime{
|
||||||
|
Value: lastStartTimeParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countryCodeQuery := c.Query("cc")
|
||||||
|
countryCode := domain.ValidString{
|
||||||
|
Value: countryCodeQuery,
|
||||||
|
Valid: countryCodeQuery != "",
|
||||||
|
}
|
||||||
|
|
||||||
|
isFeaturedQuery := c.Query("is_featured")
|
||||||
|
var isFeatured domain.ValidBool
|
||||||
|
if isFeaturedQuery != "" {
|
||||||
|
isFeaturedParsed, err := strconv.ParseBool(isFeaturedQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("Failed to parse isFeatured",
|
||||||
|
zap.String("is_featured", isFeaturedQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Failed to parse is_featured")
|
||||||
|
}
|
||||||
|
|
||||||
|
isFeatured = domain.ValidBool{
|
||||||
|
Value: isFeaturedParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isActiveQuery := c.Query("is_active")
|
||||||
|
var isActive domain.ValidBool
|
||||||
|
if isActiveQuery != "" {
|
||||||
|
isActiveParsed, err := strconv.ParseBool(isActiveQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("Failed to parse isActive",
|
||||||
|
zap.String("is_active", isActiveQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Failed to parse is_active")
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive = domain.ValidBool{
|
||||||
|
Value: isActiveParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statusQuery := c.Query("status")
|
||||||
|
var eventStatus domain.ValidEventStatus
|
||||||
|
if statusQuery != "" {
|
||||||
|
eventStatusParsed, err := domain.ParseEventStatus(statusQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("Failed to parse statusQuery",
|
||||||
|
zap.String("is_featured", isFeaturedQuery),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid event status string")
|
||||||
|
}
|
||||||
|
eventStatus = domain.ValidEventStatus{
|
||||||
|
Value: eventStatusParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events, total, err := h.eventSvc.GetEventsWithSettings(
|
||||||
|
c.Context(), companyID.Value, domain.EventFilter{
|
||||||
|
SportID: sportID,
|
||||||
|
LeagueID: leagueID,
|
||||||
|
Query: searchString,
|
||||||
|
FirstStartTime: firstStartTime,
|
||||||
|
LastStartTime: lastStartTime,
|
||||||
|
Limit: limit,
|
||||||
|
Offset: offset,
|
||||||
|
CountryCode: countryCode,
|
||||||
|
Featured: isFeatured,
|
||||||
|
Status: eventStatus,
|
||||||
|
Active: isActive,
|
||||||
|
})
|
||||||
|
|
||||||
|
// fmt.Printf("League ID: %v", leagueID)
|
||||||
|
if err != nil {
|
||||||
|
h.InternalServerErrorLogger().Error("Failed to retrieve all upcoming events",
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
res := domain.ConvertEventWithSettingResList(events)
|
||||||
|
|
||||||
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "All upcoming events retrieved successfully", res, nil, page, int(total))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
type TopLeaguesRes struct {
|
type TopLeaguesRes struct {
|
||||||
Leagues []TopLeague `json:"leagues"`
|
Leagues []TopLeague `json:"leagues"`
|
||||||
}
|
}
|
||||||
|
|
@ -483,6 +715,145 @@ func (h *Handler) GetTenantEventByID(c *fiber.Ctx) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary Retrieve bet outcomes by event id
|
||||||
|
// @Description Retrieve bet outcomes by event id
|
||||||
|
// @Tags prematch
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "ID"
|
||||||
|
// @Success 200 {object} domain.BaseEvent
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /api/v1/tenant/{tenant_slug}/events/{id}/bets [get]
|
||||||
|
func (h *Handler) GetTenantBetsByEventID(c *fiber.Ctx) error {
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
if !companyID.Valid {
|
||||||
|
h.BadRequestLogger().Error("invalid company id")
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
|
||||||
|
}
|
||||||
|
|
||||||
|
idStr := c.Params("id")
|
||||||
|
eventID, err := strconv.ParseInt(idStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse event id", zap.String("id", idStr))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Missing id")
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Params("status")
|
||||||
|
var status domain.ValidOutcomeStatus
|
||||||
|
if statusQuery != "" {
|
||||||
|
statusIntParse, err := strconv.ParseInt(statusQuery, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse status", zap.String("status", statusQuery))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid status query")
|
||||||
|
}
|
||||||
|
|
||||||
|
statusParsed, err := domain.ParseOutcomeStatus(int(statusIntParse))
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse status", zap.String("status", statusQuery))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid status query")
|
||||||
|
}
|
||||||
|
|
||||||
|
status = domain.ValidOutcomeStatus{
|
||||||
|
Value: statusParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, total, err := h.betSvc.GetBetOutcomeViewByEventID(c.Context(), eventID, domain.BetOutcomeViewFilter{
|
||||||
|
OutcomeStatus: status,
|
||||||
|
CompanyID: companyID,
|
||||||
|
Limit: limit,
|
||||||
|
Offset: offset,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.InternalServerErrorLogger().Error("Failed to get upcoming event by id",
|
||||||
|
zap.Int64("eventID", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "Bet Outcomes retrieved successfully", res, nil, page, int(total))
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Retrieve bet outcomes by event id
|
||||||
|
// @Description Retrieve bet outcomes by event id
|
||||||
|
// @Tags prematch
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "ID"
|
||||||
|
// @Success 200 {object} domain.BaseEvent
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /api/v1/events/{id}/bets [get]
|
||||||
|
func (h *Handler) GetBetsByEventID(c *fiber.Ctx) error {
|
||||||
|
idStr := c.Params("id")
|
||||||
|
eventID, err := strconv.ParseInt(idStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse event id", zap.String("id", idStr))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Missing id")
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Params("status")
|
||||||
|
var status domain.ValidOutcomeStatus
|
||||||
|
if statusQuery != "" {
|
||||||
|
statusIntParse, err := strconv.ParseInt(statusQuery, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse status", zap.String("status", statusQuery))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid status query")
|
||||||
|
}
|
||||||
|
|
||||||
|
statusParsed, err := domain.ParseOutcomeStatus(int(statusIntParse))
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse status", zap.String("status", statusQuery))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid status query")
|
||||||
|
}
|
||||||
|
|
||||||
|
status = domain.ValidOutcomeStatus{
|
||||||
|
Value: statusParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, total, err := h.betSvc.GetBetOutcomeViewByEventID(c.Context(), eventID, domain.BetOutcomeViewFilter{
|
||||||
|
OutcomeStatus: status,
|
||||||
|
Limit: limit,
|
||||||
|
Offset: offset,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.InternalServerErrorLogger().Error("Failed to get upcoming event by id",
|
||||||
|
zap.Int64("eventID", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "Bet Outcomes retrieved successfully", res, nil, page, int(total))
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateEventStatusReq struct {
|
type UpdateEventStatusReq struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,9 +890,9 @@ func (h *Handler) SetEventStatusToRemoved(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateEventSettingsReq struct {
|
type UpdateEventSettingsReq struct {
|
||||||
Featured *bool `json:"is_featured" example:"true"`
|
Featured *bool `json:"is_featured" example:"true"`
|
||||||
IsActive *bool `json:"is_active" example:"true"`
|
IsActive *bool `json:"is_active" example:"true"`
|
||||||
WinningUpperLimit *int `json:"winning_upper_limit" example:"10000"`
|
WinningUpperLimit *int64 `json:"winning_upper_limit" example:"10000"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateEventSettings godoc
|
// UpdateEventSettings godoc
|
||||||
|
|
@ -534,8 +905,72 @@ type UpdateEventSettingsReq struct {
|
||||||
// @Success 200 {object} response.APIResponse
|
// @Success 200 {object} response.APIResponse
|
||||||
// @Failure 400 {object} response.APIResponse
|
// @Failure 400 {object} response.APIResponse
|
||||||
// @Failure 500 {object} response.APIResponse
|
// @Failure 500 {object} response.APIResponse
|
||||||
// @Router /api/v1/tenant/{tenant_slug}/events/{id}/settings [put]
|
// @Router /api/v1/events/{id}/settings [put]
|
||||||
func (h *Handler) UpdateEventSettings(c *fiber.Ctx) error {
|
func (h *Handler) UpdateEventSettings(c *fiber.Ctx) error {
|
||||||
|
eventIDStr := c.Params("id")
|
||||||
|
|
||||||
|
eventID, err := strconv.ParseInt(eventIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.BadRequestLogger().Error("invalid event id")
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid event id")
|
||||||
|
}
|
||||||
|
|
||||||
|
var req UpdateEventSettingsReq
|
||||||
|
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.BadRequestLogger().Info("Failed to parse event id",
|
||||||
|
zap.Int64("eventID", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
logFields := []zap.Field{
|
||||||
|
zap.Int64("eventID", eventID),
|
||||||
|
zap.Any("is_featured", req.Featured),
|
||||||
|
zap.Any("is_active", req.IsActive),
|
||||||
|
zap.Any("winning_upper_limit", req.WinningUpperLimit),
|
||||||
|
}
|
||||||
|
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 update event settings",
|
||||||
|
append(logFields, zap.String("errMsg", errMsg))...,
|
||||||
|
)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.eventSvc.UpdateGlobalEventSettings(c.Context(), domain.UpdateGlobalEventSettings{
|
||||||
|
EventID: eventID,
|
||||||
|
IsFeatured: domain.ConvertBoolPtr(req.Featured),
|
||||||
|
IsActive: domain.ConvertBoolPtr(req.IsActive),
|
||||||
|
WinningUpperLimit: domain.ConvertInt64Ptr(req.WinningUpperLimit),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.InternalServerErrorLogger().Error("Failed to update event settings", append(logFields, zap.Error(err))...)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Event updated successfully", nil, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTenantEventSettings godoc
|
||||||
|
// @Summary update the event settings
|
||||||
|
// @Description Update the event settings
|
||||||
|
// @Tags event
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Event ID"
|
||||||
|
// @Success 200 {object} response.APIResponse
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /api/v1/tenant/{tenant_slug}/events/{id}/settings [put]
|
||||||
|
func (h *Handler) UpdateTenantEventSettings(c *fiber.Ctx) error {
|
||||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
if !companyID.Valid {
|
if !companyID.Valid {
|
||||||
h.BadRequestLogger().Error("invalid company id")
|
h.BadRequestLogger().Error("invalid company id")
|
||||||
|
|
@ -579,12 +1014,12 @@ func (h *Handler) UpdateEventSettings(c *fiber.Ctx) error {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.eventSvc.UpdateEventSettings(c.Context(), domain.CreateEventSettings{
|
err = h.eventSvc.UpdateTenantEventSettings(c.Context(), domain.UpdateTenantEventSettings{
|
||||||
CompanyID: companyID.Value,
|
CompanyID: companyID.Value,
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
IsFeatured: domain.ConvertBoolPtr(req.Featured),
|
IsFeatured: domain.ConvertBoolPtr(req.Featured),
|
||||||
IsActive: domain.ConvertBoolPtr(req.IsActive),
|
IsActive: domain.ConvertBoolPtr(req.IsActive),
|
||||||
WinningUpperLimit: domain.ConvertIntPtr(req.WinningUpperLimit),
|
WinningUpperLimit: domain.ConvertInt64Ptr(req.WinningUpperLimit),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error {
|
||||||
|
|
||||||
limit := domain.ValidInt64{
|
limit := domain.ValidInt64{
|
||||||
Value: int64(pageSize),
|
Value: int64(pageSize),
|
||||||
Valid: pageSize == 0,
|
Valid: pageSize != 0,
|
||||||
}
|
}
|
||||||
offset := domain.ValidInt64{
|
offset := domain.ValidInt64{
|
||||||
Value: int64(page - 1),
|
Value: int64(page - 1),
|
||||||
|
|
@ -54,7 +54,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error {
|
||||||
sportIDQuery := c.Query("sport_id")
|
sportIDQuery := c.Query("sport_id")
|
||||||
var sportID domain.ValidInt32
|
var sportID domain.ValidInt32
|
||||||
if sportIDQuery != "" {
|
if sportIDQuery != "" {
|
||||||
sportIDint, err := strconv.Atoi(sportIDQuery)
|
sportIDint, err := strconv.ParseInt(sportIDQuery, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.BadRequestLogger().Info("invalid sport id",
|
h.BadRequestLogger().Info("invalid sport id",
|
||||||
zap.String("sport_id", sportIDQuery),
|
zap.String("sport_id", sportIDQuery),
|
||||||
|
|
@ -86,7 +86,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error {
|
||||||
zap.Bool("sport_id_valid", sportID.Valid),
|
zap.Bool("sport_id_valid", sportID.Valid),
|
||||||
}
|
}
|
||||||
|
|
||||||
leagues, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{
|
leagues, total, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{
|
||||||
CountryCode: countryCode,
|
CountryCode: countryCode,
|
||||||
IsActive: isActive,
|
IsActive: isActive,
|
||||||
SportID: sportID,
|
SportID: sportID,
|
||||||
|
|
@ -104,7 +104,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error {
|
||||||
|
|
||||||
res := domain.ConvertBaseLeagueResList(leagues)
|
res := domain.ConvertBaseLeagueResList(leagues)
|
||||||
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "All leagues retrieved", res, nil)
|
return response.WritePaginatedJSON(c, fiber.StatusOK, "All leagues retrieved successfully", res, nil, page, int(total))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllLeaguesForTenant godoc
|
// GetAllLeaguesForTenant godoc
|
||||||
|
|
@ -156,7 +156,7 @@ func (h *Handler) GetAllLeaguesForTenant(c *fiber.Ctx) error {
|
||||||
sportIDQuery := c.Query("sport_id")
|
sportIDQuery := c.Query("sport_id")
|
||||||
var sportID domain.ValidInt32
|
var sportID domain.ValidInt32
|
||||||
if sportIDQuery != "" {
|
if sportIDQuery != "" {
|
||||||
sportIDint, err := strconv.Atoi(sportIDQuery)
|
sportIDint, err := strconv.ParseInt(sportIDQuery, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.BadRequestLogger().Info("invalid sport id",
|
h.BadRequestLogger().Info("invalid sport id",
|
||||||
zap.String("sport_id", sportIDQuery),
|
zap.String("sport_id", sportIDQuery),
|
||||||
|
|
@ -235,7 +235,7 @@ func (h *Handler) SetLeagueActive(c *fiber.Ctx) error {
|
||||||
if leagueIdStr == "" {
|
if leagueIdStr == "" {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "Missing league id")
|
return fiber.NewError(fiber.StatusBadRequest, "Missing league id")
|
||||||
}
|
}
|
||||||
leagueId, err := strconv.Atoi(leagueIdStr)
|
leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +266,7 @@ func (h *Handler) SetLeagueActive(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{
|
if err := h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{
|
||||||
LeagueID: int64(leagueId),
|
LeagueID: leagueId,
|
||||||
CompanyID: companyID.Value,
|
CompanyID: companyID.Value,
|
||||||
IsActive: domain.ValidBool{
|
IsActive: domain.ValidBool{
|
||||||
Value: req.IsActive,
|
Value: req.IsActive,
|
||||||
|
|
@ -308,7 +308,7 @@ func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error {
|
||||||
if leagueIdStr == "" {
|
if leagueIdStr == "" {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "Missing league id")
|
return fiber.NewError(fiber.StatusBadRequest, "Missing league id")
|
||||||
}
|
}
|
||||||
leagueId, err := strconv.Atoi(leagueIdStr)
|
leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +336,7 @@ func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
err = h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{
|
err = h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{
|
||||||
LeagueID: int64(leagueId),
|
LeagueID: leagueId,
|
||||||
CompanyID: companyID.Value,
|
CompanyID: companyID.Value,
|
||||||
IsFeatured: domain.ValidBool{
|
IsFeatured: domain.ValidBool{
|
||||||
Value: req.IsFeatured,
|
Value: req.IsFeatured,
|
||||||
|
|
@ -351,3 +351,45 @@ func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error {
|
||||||
h.SuccessResLogger().Info("League Featured has been successfully updated", queryLogFields...)
|
h.SuccessResLogger().Info("League Featured has been successfully updated", queryLogFields...)
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil)
|
return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) UpdateGlobalLeagueSetting(c *fiber.Ctx) error {
|
||||||
|
leagueIdStr := c.Params("id")
|
||||||
|
if leagueIdStr == "" {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Missing league id")
|
||||||
|
}
|
||||||
|
leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "invalid league id")
|
||||||
|
}
|
||||||
|
|
||||||
|
var req domain.UpdateLeagueSettingsReq
|
||||||
|
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.BadRequestLogger().Info("UpdateLeagueSettingsReq failed to parse request body", zap.String("league_id", leagueIdStr), zap.Error(err))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Failed to parse request body:"+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().Info("Failed to validate UpdateLeagueSettingsReq", zap.Error(err))
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.leagueSvc.UpdateGlobalLeagueSettings(c.Context(), domain.UpdateGlobalLeagueSettings{
|
||||||
|
ID: leagueId,
|
||||||
|
DefaultIsActive: domain.ConvertBoolPtr(req.IsActive),
|
||||||
|
DefaultIsFeatured: domain.ConvertBoolPtr(req.IsFeatured),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.InternalServerErrorLogger().Error("Failed to update league", zap.Error(err), zap.String("leagueId", leagueIdStr))
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error())
|
||||||
|
}
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user