fix: resolved issue on event, odds and creating a bet
This commit is contained in:
parent
1c7c7e5731
commit
6b09c3c8d2
|
|
@ -112,13 +112,11 @@ func main() {
|
|||
|
||||
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
||||
userSvc := user.NewService(store, store, messengerSvc, cfg)
|
||||
eventSvc := event.New(cfg.Bet365Token, store, domain.MongoDBLogger)
|
||||
eventSvc := event.New(cfg.Bet365Token, store, *settingSvc, domain.MongoDBLogger)
|
||||
oddsSvc := odds.New(store, cfg, eventSvc, logger, domain.MongoDBLogger)
|
||||
notificationRepo := repository.NewNotificationRepository(store)
|
||||
virtuaGamesRepo := repository.NewVirtualGameRepository(store)
|
||||
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
|
||||
|
||||
var notificatioStore notificationservice.NotificationStore
|
||||
// var userStore user.UserStore
|
||||
|
||||
// Initialize producer
|
||||
|
|
@ -130,7 +128,6 @@ func main() {
|
|||
wallet.WalletStore(store),
|
||||
wallet.TransferStore(store),
|
||||
wallet.DirectDepositStore(store),
|
||||
notificatioStore,
|
||||
notificationSvc,
|
||||
userSvc,
|
||||
domain.MongoDBLogger,
|
||||
|
|
@ -153,7 +150,7 @@ func main() {
|
|||
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
|
||||
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
||||
veliCLient := veli.NewClient(cfg, walletSvc)
|
||||
veliVirtualGameService := veli.New(virtualGameSvc,vitualGameRepo, veliCLient, walletSvc, wallet.TransferStore(store), cfg)
|
||||
veliVirtualGameService := veli.New(virtualGameSvc, vitualGameRepo, veliCLient, walletSvc, wallet.TransferStore(store), cfg)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
-- Locations Initial Data
|
||||
INSERT INTO branch_locations (key, value)
|
||||
VALUES ('addis_ababa', 'Addis Ababa'),
|
||||
|
|
@ -75,7 +74,6 @@ VALUES ('addis_ababa', 'Addis Ababa'),
|
|||
('agaro', 'Agaro') ON CONFLICT (key) DO
|
||||
UPDATE
|
||||
SET value = EXCLUDED.value;
|
||||
|
||||
-- Settings Initial Data
|
||||
INSERT INTO global_settings (key, value)
|
||||
VALUES ('sms_provider', 'afro_message'),
|
||||
|
|
@ -84,8 +82,8 @@ VALUES ('sms_provider', 'afro_message'),
|
|||
('daily_ticket_limit', '50'),
|
||||
('total_winnings_limit', '1000000'),
|
||||
('amount_for_bet_referral', '1000000'),
|
||||
('cashback_amount_cap', '1000') ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
('cashback_amount_cap', '1000'),
|
||||
('default_winning_limit', '5000000') ON CONFLICT (key) DO NOTHING;
|
||||
-- Users
|
||||
INSERT INTO users (
|
||||
id,
|
||||
|
|
@ -224,7 +222,7 @@ VALUES (
|
|||
),
|
||||
(
|
||||
3,
|
||||
20000,
|
||||
100000000 ,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
|
|
@ -237,7 +235,7 @@ VALUES (
|
|||
),
|
||||
(
|
||||
4,
|
||||
15000,
|
||||
50000000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ VALUES (
|
|||
6,
|
||||
'Kirubel',
|
||||
'Kibru',
|
||||
'modernkibru @gmail.com',
|
||||
'modernkibru@gmail.com',
|
||||
NULL,
|
||||
crypt('password@123', gen_salt('bf'))::bytea,
|
||||
'customer',
|
||||
|
|
@ -98,7 +98,7 @@ VALUES (
|
|||
),
|
||||
(
|
||||
7,
|
||||
10000,
|
||||
1000000,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
|||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_games (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
game_id VARCHAR(150) NOT NULL,
|
||||
|
|
@ -45,19 +44,16 @@ CREATE TABLE IF NOT EXISTS virtual_games (
|
|||
category VARCHAR(100),
|
||||
device_type VARCHAR(100),
|
||||
volatility VARCHAR(50),
|
||||
rtp NUMERIC(5,2),
|
||||
rtp NUMERIC(5, 2),
|
||||
has_demo BOOLEAN DEFAULT FALSE,
|
||||
has_free_bets BOOLEAN DEFAULT FALSE,
|
||||
bets NUMERIC[] DEFAULT '{}',
|
||||
bets NUMERIC [] DEFAULT '{}',
|
||||
thumbnail TEXT,
|
||||
status INT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_virtual_games_provider_game
|
||||
ON virtual_games (provider_id, game_id);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_virtual_games_provider_game ON virtual_games (provider_id, game_id);
|
||||
CREATE TABLE IF NOT EXISTS wallets (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
balance BIGINT NOT NULL DEFAULT 0,
|
||||
|
|
@ -325,7 +321,7 @@ CREATE TABLE events (
|
|||
),
|
||||
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
default_is_featured BOOLEAN NOT NULL DEFAULT false,
|
||||
default_winning_upper_limit INT NOT NULL,
|
||||
default_winning_upper_limit BIGINT NOT NULL,
|
||||
is_monitored BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
UNIQUE (id, source)
|
||||
);
|
||||
|
|
@ -621,7 +617,7 @@ SELECT l.*,
|
|||
COALESCE(cls.is_featured, l.default_is_featured) AS is_featured,
|
||||
cls.updated_at
|
||||
FROM leagues l
|
||||
JOIN company_league_settings cls ON l.id = cls.league_id;
|
||||
LEFT JOIN company_league_settings cls ON l.id = cls.league_id;
|
||||
CREATE VIEW event_with_settings AS
|
||||
SELECT e.*,
|
||||
ces.company_id,
|
||||
|
|
@ -634,7 +630,7 @@ SELECT e.*,
|
|||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
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;
|
||||
CREATE VIEW event_with_country AS
|
||||
SELECT events.*,
|
||||
|
|
@ -656,7 +652,7 @@ SELECT o.id,
|
|||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
JOIN company_odd_settings cos ON o.id = cos.odds_market_id;
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id;
|
||||
CREATE VIEW odds_market_with_event AS
|
||||
SELECT o.*,
|
||||
e.is_monitored,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ INSERT INTO events (
|
|||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source
|
||||
source,
|
||||
default_winning_upper_limit
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
|
|
@ -31,7 +32,8 @@ VALUES (
|
|||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15
|
||||
$15,
|
||||
$16
|
||||
) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET sport_id = EXCLUDED.sport_id,
|
||||
|
|
@ -44,7 +46,6 @@ SET sport_id = EXCLUDED.sport_id,
|
|||
away_kit_image = EXCLUDED.away_kit_image,
|
||||
league_id = EXCLUDED.league_id,
|
||||
league_name = EXCLUDED.league_name,
|
||||
league_cc = EXCLUDED.league_cc,
|
||||
start_time = EXCLUDED.start_time,
|
||||
score = EXCLUDED.score,
|
||||
match_minute = EXCLUDED.match_minute,
|
||||
|
|
@ -53,6 +54,7 @@ SET sport_id = EXCLUDED.sport_id,
|
|||
match_period = EXCLUDED.match_period,
|
||||
is_live = EXCLUDED.is_live,
|
||||
source = EXCLUDED.source,
|
||||
default_winning_upper_limit = EXCLUDED.default_winning_upper_limit,
|
||||
fetched_at = now();
|
||||
-- name: SaveEventSettings :exec
|
||||
INSERT INTO company_event_settings (
|
||||
|
|
@ -152,16 +154,18 @@ ORDER BY start_time ASC
|
|||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetTotalCompanyEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND is_live = false
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $1
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
league_id = sqlc.narg('league_id')
|
||||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
e.sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -178,14 +182,29 @@ WHERE company_id = $1
|
|||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = sqlc.narg('country_code')
|
||||
l.country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
AND (
|
||||
ces.is_featured = sqlc.narg('is_featured')
|
||||
OR sqlc.narg('is_featured') IS NULL
|
||||
);
|
||||
-- name: GetEventsWithSettings :many
|
||||
SELECT *
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND start_time > now()
|
||||
SELECT e.*,
|
||||
ces.company_id,
|
||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||
COALESCE(
|
||||
ces.winning_upper_limit,
|
||||
e.default_winning_upper_limit
|
||||
) AS winning_upper_limit,
|
||||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $1
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
|
|
@ -193,7 +212,7 @@ WHERE company_id = $1
|
|||
OR sqlc.narg('league_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = sqlc.narg('sport_id')
|
||||
e.sport_id = sqlc.narg('sport_id')
|
||||
OR sqlc.narg('sport_id') IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -210,9 +229,12 @@ WHERE company_id = $1
|
|||
OR sqlc.narg('first_start_time') IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = sqlc.narg('country_code')
|
||||
l.country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
) AND (
|
||||
ces.is_featured = sqlc.narg('is_featured')
|
||||
OR sqlc.narg('is_featured') IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetUpcomingByID :one
|
||||
|
|
@ -223,10 +245,21 @@ WHERE id = $1
|
|||
AND status = 'upcoming'
|
||||
LIMIT 1;
|
||||
-- name: GetEventWithSettingByID :one
|
||||
SELECT *
|
||||
FROM event_with_settings
|
||||
WHERE id = $1
|
||||
AND company_id = $2
|
||||
SELECT e.*,
|
||||
ces.company_id,
|
||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||
COALESCE(
|
||||
ces.winning_upper_limit,
|
||||
e.default_winning_upper_limit
|
||||
) AS winning_upper_limit,
|
||||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $2
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE e.id = $1
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
LIMIT 1;
|
||||
|
|
@ -243,7 +276,6 @@ WHERE id = $1;
|
|||
UPDATE events
|
||||
SET is_monitored = $1
|
||||
WHERE id = $2;
|
||||
|
||||
-- name: DeleteEvent :exec
|
||||
DELETE FROM events
|
||||
WHERE id = $1;
|
||||
|
|
@ -43,10 +43,14 @@ WHERE (
|
|||
ORDER BY name ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetAllLeaguesWithSettings :many
|
||||
SELECT *
|
||||
FROM league_with_settings
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
SELECT l.*,
|
||||
cls.company_id,
|
||||
COALESCE(cls.is_active, l.default_is_active) AS is_active,
|
||||
COALESCE(cls.is_featured, l.default_is_featured) AS is_featured,
|
||||
cls.updated_at
|
||||
FROM leagues l
|
||||
LEFT JOIN company_league_settings cls ON l.id = cls.league_id AND company_id = $1
|
||||
WHERE (
|
||||
country_code = sqlc.narg('country_code')
|
||||
OR sqlc.narg('country_code') IS NULL
|
||||
)
|
||||
|
|
@ -64,7 +68,6 @@ WHERE (company_id = $1)
|
|||
)
|
||||
AND (
|
||||
name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR league_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||
OR sqlc.narg('query') IS NULL
|
||||
)
|
||||
ORDER BY is_featured DESC,
|
||||
|
|
|
|||
|
|
@ -42,9 +42,22 @@ SELECT *
|
|||
FROM odds_market_with_event
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetAllOddsWithSettings :many
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE company_id = $1
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $1
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetOddByID :one
|
||||
SELECT *
|
||||
|
|
@ -56,16 +69,42 @@ FROM odds_market_with_event
|
|||
WHERE market_id = $1
|
||||
AND event_id = $2;
|
||||
-- name: GetOddsWithSettingsByMarketID :one
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $3
|
||||
WHERE market_id = $1
|
||||
AND event_id = $2
|
||||
AND company_id = $3;
|
||||
AND event_id = $2;
|
||||
-- name: GetOddsWithSettingsByID :one
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE id = $1
|
||||
AND company_id = $2;
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $2
|
||||
WHERE o.id = $1;
|
||||
-- name: GetOddsByEventID :many
|
||||
SELECT *
|
||||
FROM odds_market_with_event
|
||||
|
|
@ -84,10 +123,23 @@ WHERE event_id = $1
|
|||
)
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: GetOddsWithSettingsByEventID :many
|
||||
SELECT *
|
||||
FROM odds_market_with_settings
|
||||
WHERE event_id = $1
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $2
|
||||
WHERE event_id = $1
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
-- name: DeleteOddsForEvent :exec
|
||||
DELETE FROM odds_market
|
||||
|
|
|
|||
|
|
@ -78,10 +78,21 @@ func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]EventWithCountry,
|
|||
}
|
||||
|
||||
const GetEventWithSettingByID = `-- name: GetEventWithSettingByID :one
|
||||
SELECT 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, company_id, is_active, is_featured, winning_upper_limit, updated_at, league_cc
|
||||
FROM event_with_settings
|
||||
WHERE id = $1
|
||||
AND company_id = $2
|
||||
SELECT e.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,
|
||||
ces.company_id,
|
||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||
COALESCE(
|
||||
ces.winning_upper_limit,
|
||||
e.default_winning_upper_limit
|
||||
) AS winning_upper_limit,
|
||||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $2
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE e.id = $1
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
LIMIT 1
|
||||
|
|
@ -92,9 +103,43 @@ type GetEventWithSettingByIDParams struct {
|
|||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithSettingByIDParams) (EventWithSetting, error) {
|
||||
type GetEventWithSettingByIDRow struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeKitImage string `json:"home_kit_image"`
|
||||
AwayKitImage string `json:"away_kit_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
StartTime pgtype.Timestamp `json:"start_time"`
|
||||
Score pgtype.Text `json:"score"`
|
||||
MatchMinute pgtype.Int4 `json:"match_minute"`
|
||||
TimerStatus pgtype.Text `json:"timer_status"`
|
||||
AddedTime pgtype.Int4 `json:"added_time"`
|
||||
MatchPeriod pgtype.Int4 `json:"match_period"`
|
||||
IsLive bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithSettingByIDParams) (GetEventWithSettingByIDRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetEventWithSettingByID, arg.ID, arg.CompanyID)
|
||||
var i EventWithSetting
|
||||
var i GetEventWithSettingByIDRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.SportID,
|
||||
|
|
@ -132,10 +177,21 @@ func (q *Queries) GetEventWithSettingByID(ctx context.Context, arg GetEventWithS
|
|||
}
|
||||
|
||||
const GetEventsWithSettings = `-- name: GetEventsWithSettings :many
|
||||
SELECT 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, company_id, is_active, is_featured, winning_upper_limit, updated_at, league_cc
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND start_time > now()
|
||||
SELECT e.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,
|
||||
ces.company_id,
|
||||
COALESCE(ces.is_active, e.default_is_active) AS is_active,
|
||||
COALESCE(ces.is_featured, e.default_is_featured) AS is_featured,
|
||||
COALESCE(
|
||||
ces.winning_upper_limit,
|
||||
e.default_winning_upper_limit
|
||||
) AS winning_upper_limit,
|
||||
ces.updated_at,
|
||||
l.country_code as league_cc
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $1
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE start_time > now()
|
||||
AND is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
|
|
@ -143,7 +199,7 @@ WHERE company_id = $1
|
|||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $3
|
||||
e.sport_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -160,11 +216,14 @@ WHERE company_id = $1
|
|||
OR $6 IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = $7
|
||||
l.country_code = $7
|
||||
OR $7 IS NULL
|
||||
)
|
||||
) AND (
|
||||
ces.is_featured = $8
|
||||
OR $8 IS NULL
|
||||
)
|
||||
ORDER BY start_time ASC
|
||||
LIMIT $9 OFFSET $8
|
||||
LIMIT $10 OFFSET $9
|
||||
`
|
||||
|
||||
type GetEventsWithSettingsParams struct {
|
||||
|
|
@ -175,11 +234,46 @@ type GetEventsWithSettingsParams struct {
|
|||
LastStartTime pgtype.Timestamp `json:"last_start_time"`
|
||||
FirstStartTime pgtype.Timestamp `json:"first_start_time"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
Offset pgtype.Int4 `json:"offset"`
|
||||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSettingsParams) ([]EventWithSetting, error) {
|
||||
type GetEventsWithSettingsRow struct {
|
||||
ID string `json:"id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
MatchName string `json:"match_name"`
|
||||
HomeTeam string `json:"home_team"`
|
||||
AwayTeam string `json:"away_team"`
|
||||
HomeTeamID int64 `json:"home_team_id"`
|
||||
AwayTeamID int64 `json:"away_team_id"`
|
||||
HomeKitImage string `json:"home_kit_image"`
|
||||
AwayKitImage string `json:"away_kit_image"`
|
||||
LeagueID int64 `json:"league_id"`
|
||||
LeagueName string `json:"league_name"`
|
||||
StartTime pgtype.Timestamp `json:"start_time"`
|
||||
Score pgtype.Text `json:"score"`
|
||||
MatchMinute pgtype.Int4 `json:"match_minute"`
|
||||
TimerStatus pgtype.Text `json:"timer_status"`
|
||||
AddedTime pgtype.Int4 `json:"added_time"`
|
||||
MatchPeriod pgtype.Int4 `json:"match_period"`
|
||||
IsLive bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSettingsParams) ([]GetEventsWithSettingsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetEventsWithSettings,
|
||||
arg.CompanyID,
|
||||
arg.LeagueID,
|
||||
|
|
@ -188,6 +282,7 @@ func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSe
|
|||
arg.LastStartTime,
|
||||
arg.FirstStartTime,
|
||||
arg.CountryCode,
|
||||
arg.IsFeatured,
|
||||
arg.Offset,
|
||||
arg.Limit,
|
||||
)
|
||||
|
|
@ -195,9 +290,9 @@ func (q *Queries) GetEventsWithSettings(ctx context.Context, arg GetEventsWithSe
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []EventWithSetting
|
||||
var items []GetEventsWithSettingsRow
|
||||
for rows.Next() {
|
||||
var i EventWithSetting
|
||||
var i GetEventsWithSettingsRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.SportID,
|
||||
|
|
@ -403,16 +498,18 @@ func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginat
|
|||
|
||||
const GetTotalCompanyEvents = `-- name: GetTotalCompanyEvents :one
|
||||
SELECT COUNT(*)
|
||||
FROM event_with_settings
|
||||
WHERE company_id = $1
|
||||
AND is_live = false
|
||||
FROM events e
|
||||
LEFT JOIN company_event_settings ces ON e.id = ces.event_id
|
||||
AND ces.company_id = $1
|
||||
JOIN leagues l ON l.id = e.league_id
|
||||
WHERE is_live = false
|
||||
AND status = 'upcoming'
|
||||
AND (
|
||||
league_id = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
AND (
|
||||
sport_id = $3
|
||||
e.sport_id = $3
|
||||
OR $3 IS NULL
|
||||
)
|
||||
AND (
|
||||
|
|
@ -429,9 +526,13 @@ WHERE company_id = $1
|
|||
OR $6 IS NULL
|
||||
)
|
||||
AND (
|
||||
league_cc = $7
|
||||
l.country_code = $7
|
||||
OR $7 IS NULL
|
||||
)
|
||||
AND (
|
||||
ces.is_featured = $8
|
||||
OR $8 IS NULL
|
||||
)
|
||||
`
|
||||
|
||||
type GetTotalCompanyEventsParams struct {
|
||||
|
|
@ -442,6 +543,7 @@ type GetTotalCompanyEventsParams struct {
|
|||
LastStartTime pgtype.Timestamp `json:"last_start_time"`
|
||||
FirstStartTime pgtype.Timestamp `json:"first_start_time"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetTotalCompanyEvents(ctx context.Context, arg GetTotalCompanyEventsParams) (int64, error) {
|
||||
|
|
@ -453,6 +555,7 @@ func (q *Queries) GetTotalCompanyEvents(ctx context.Context, arg GetTotalCompany
|
|||
arg.LastStartTime,
|
||||
arg.FirstStartTime,
|
||||
arg.CountryCode,
|
||||
arg.IsFeatured,
|
||||
)
|
||||
var count int64
|
||||
err := row.Scan(&count)
|
||||
|
|
@ -573,7 +676,8 @@ INSERT INTO events (
|
|||
start_time,
|
||||
is_live,
|
||||
status,
|
||||
source
|
||||
source,
|
||||
default_winning_upper_limit
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
|
|
@ -590,7 +694,8 @@ VALUES (
|
|||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15
|
||||
$15,
|
||||
$16
|
||||
) ON CONFLICT (id) DO
|
||||
UPDATE
|
||||
SET sport_id = EXCLUDED.sport_id,
|
||||
|
|
@ -603,7 +708,6 @@ SET sport_id = EXCLUDED.sport_id,
|
|||
away_kit_image = EXCLUDED.away_kit_image,
|
||||
league_id = EXCLUDED.league_id,
|
||||
league_name = EXCLUDED.league_name,
|
||||
league_cc = EXCLUDED.league_cc,
|
||||
start_time = EXCLUDED.start_time,
|
||||
score = EXCLUDED.score,
|
||||
match_minute = EXCLUDED.match_minute,
|
||||
|
|
@ -612,6 +716,7 @@ SET sport_id = EXCLUDED.sport_id,
|
|||
match_period = EXCLUDED.match_period,
|
||||
is_live = EXCLUDED.is_live,
|
||||
source = EXCLUDED.source,
|
||||
default_winning_upper_limit = EXCLUDED.default_winning_upper_limit,
|
||||
fetched_at = now()
|
||||
`
|
||||
|
||||
|
|
@ -631,6 +736,7 @@ type InsertEventParams struct {
|
|||
IsLive bool `json:"is_live"`
|
||||
Status string `json:"status"`
|
||||
Source string `json:"source"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) error {
|
||||
|
|
@ -650,6 +756,7 @@ func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) error
|
|||
arg.IsLive,
|
||||
arg.Status,
|
||||
arg.Source,
|
||||
arg.DefaultWinningUpperLimit,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,10 +96,14 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
|||
}
|
||||
|
||||
const GetAllLeaguesWithSettings = `-- name: GetAllLeaguesWithSettings :many
|
||||
SELECT id, name, img_url, country_code, bet365_id, sport_id, default_is_active, default_is_featured, company_id, is_active, is_featured, updated_at
|
||||
FROM league_with_settings
|
||||
WHERE (company_id = $1)
|
||||
AND (
|
||||
SELECT l.id, l.name, l.img_url, l.country_code, l.bet365_id, l.sport_id, l.default_is_active, l.default_is_featured,
|
||||
cls.company_id,
|
||||
COALESCE(cls.is_active, l.default_is_active) AS is_active,
|
||||
COALESCE(cls.is_featured, l.default_is_featured) AS is_featured,
|
||||
cls.updated_at
|
||||
FROM leagues l
|
||||
LEFT JOIN company_league_settings cls ON l.id = cls.league_id AND company_id = $1
|
||||
WHERE (
|
||||
country_code = $2
|
||||
OR $2 IS NULL
|
||||
)
|
||||
|
|
@ -117,7 +121,6 @@ WHERE (company_id = $1)
|
|||
)
|
||||
AND (
|
||||
name ILIKE '%' || $6 || '%'
|
||||
OR league_name ILIKE '%' || $6 || '%'
|
||||
OR $6 IS NULL
|
||||
)
|
||||
ORDER BY is_featured DESC,
|
||||
|
|
@ -136,7 +139,22 @@ type GetAllLeaguesWithSettingsParams struct {
|
|||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeaguesWithSettingsParams) ([]LeagueWithSetting, error) {
|
||||
type GetAllLeaguesWithSettingsRow struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImgUrl pgtype.Text `json:"img_url"`
|
||||
CountryCode pgtype.Text `json:"country_code"`
|
||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||
SportID int32 `json:"sport_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeaguesWithSettingsParams) ([]GetAllLeaguesWithSettingsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllLeaguesWithSettings,
|
||||
arg.CompanyID,
|
||||
arg.CountryCode,
|
||||
|
|
@ -151,9 +169,9 @@ func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeagu
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []LeagueWithSetting
|
||||
var items []GetAllLeaguesWithSettingsRow
|
||||
for rows.Next() {
|
||||
var i LeagueWithSetting
|
||||
var i GetAllLeaguesWithSettingsRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ type Event struct {
|
|||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +356,7 @@ type EventWithCountry struct {
|
|||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
LeagueCc pgtype.Text `json:"league_cc"`
|
||||
}
|
||||
|
|
@ -385,9 +385,9 @@ type EventWithSetting struct {
|
|||
Source string `json:"source"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
IsMonitored bool `json:"is_monitored"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
|
|
@ -447,7 +447,7 @@ type LeagueWithSetting struct {
|
|||
SportID int32 `json:"sport_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
IsFeatured bool `json:"is_featured"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
|
|
@ -520,7 +520,7 @@ type OddsMarketWithSetting struct {
|
|||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID int64 `json:"company_id"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
|
|
|
|||
|
|
@ -68,9 +68,22 @@ func (q *Queries) GetAllOdds(ctx context.Context, arg GetAllOddsParams) ([]OddsM
|
|||
}
|
||||
|
||||
const GetAllOddsWithSettings = `-- name: GetAllOddsWithSettings :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE company_id = $1
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $1
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
|
|
@ -80,15 +93,31 @@ type GetAllOddsWithSettingsParams struct {
|
|||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]OddsMarketWithSetting, error) {
|
||||
type GetAllOddsWithSettingsRow struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]GetAllOddsWithSettingsRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetAllOddsWithSettings, arg.CompanyID, arg.Offset, arg.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddsMarketWithSetting
|
||||
var items []GetAllOddsWithSettingsRow
|
||||
for rows.Next() {
|
||||
var i OddsMarketWithSetting
|
||||
var i GetAllOddsWithSettingsRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
|
|
@ -247,10 +276,23 @@ func (q *Queries) GetOddsByMarketID(ctx context.Context, arg GetOddsByMarketIDPa
|
|||
}
|
||||
|
||||
const GetOddsWithSettingsByEventID = `-- name: GetOddsWithSettingsByEventID :many
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE event_id = $1
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $2
|
||||
WHERE event_id = $1
|
||||
LIMIT $4 OFFSET $3
|
||||
`
|
||||
|
||||
|
|
@ -261,7 +303,23 @@ type GetOddsWithSettingsByEventIDParams struct {
|
|||
Limit pgtype.Int4 `json:"limit"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]OddsMarketWithSetting, error) {
|
||||
type GetOddsWithSettingsByEventIDRow struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]GetOddsWithSettingsByEventIDRow, error) {
|
||||
rows, err := q.db.Query(ctx, GetOddsWithSettingsByEventID,
|
||||
arg.EventID,
|
||||
arg.CompanyID,
|
||||
|
|
@ -272,9 +330,9 @@ func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsW
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []OddsMarketWithSetting
|
||||
var items []GetOddsWithSettingsByEventIDRow
|
||||
for rows.Next() {
|
||||
var i OddsMarketWithSetting
|
||||
var i GetOddsWithSettingsByEventIDRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
|
|
@ -301,10 +359,23 @@ func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsW
|
|||
}
|
||||
|
||||
const GetOddsWithSettingsByID = `-- name: GetOddsWithSettingsByID :one
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
WHERE id = $1
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $2
|
||||
WHERE o.id = $1
|
||||
`
|
||||
|
||||
type GetOddsWithSettingsByIDParams struct {
|
||||
|
|
@ -312,9 +383,25 @@ type GetOddsWithSettingsByIDParams struct {
|
|||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSettingsByIDParams) (OddsMarketWithSetting, error) {
|
||||
type GetOddsWithSettingsByIDRow struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSettingsByIDParams) (GetOddsWithSettingsByIDRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetOddsWithSettingsByID, arg.ID, arg.CompanyID)
|
||||
var i OddsMarketWithSetting
|
||||
var i GetOddsWithSettingsByIDRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
|
|
@ -334,11 +421,24 @@ func (q *Queries) GetOddsWithSettingsByID(ctx context.Context, arg GetOddsWithSe
|
|||
}
|
||||
|
||||
const GetOddsWithSettingsByMarketID = `-- name: GetOddsWithSettingsByMarketID :one
|
||||
SELECT id, event_id, market_type, market_name, market_category, market_id, default_is_active, fetched_at, expires_at, company_id, is_active, raw_odds, updated_at
|
||||
FROM odds_market_with_settings
|
||||
SELECT o.id,
|
||||
o.event_id,
|
||||
o.market_type,
|
||||
o.market_name,
|
||||
o.market_category,
|
||||
o.market_id,
|
||||
o.default_is_active,
|
||||
o.fetched_at,
|
||||
o.expires_at,
|
||||
cos.company_id,
|
||||
COALESCE(cos.is_active, o.default_is_active) AS is_active,
|
||||
COALESCE(cos.custom_raw_odds, o.raw_odds) AS raw_odds,
|
||||
cos.updated_at
|
||||
FROM odds_market o
|
||||
LEFT JOIN company_odd_settings cos ON o.id = cos.odds_market_id
|
||||
AND company_id = $3
|
||||
WHERE market_id = $1
|
||||
AND event_id = $2
|
||||
AND company_id = $3
|
||||
`
|
||||
|
||||
type GetOddsWithSettingsByMarketIDParams struct {
|
||||
|
|
@ -347,9 +447,25 @@ type GetOddsWithSettingsByMarketIDParams struct {
|
|||
CompanyID int64 `json:"company_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (OddsMarketWithSetting, error) {
|
||||
type GetOddsWithSettingsByMarketIDRow struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
MarketType string `json:"market_type"`
|
||||
MarketName string `json:"market_name"`
|
||||
MarketCategory string `json:"market_category"`
|
||||
MarketID string `json:"market_id"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||
CompanyID pgtype.Int8 `json:"company_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
RawOdds []byte `json:"raw_odds"`
|
||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (GetOddsWithSettingsByMarketIDRow, error) {
|
||||
row := q.db.QueryRow(ctx, GetOddsWithSettingsByMarketID, arg.MarketID, arg.EventID, arg.CompanyID)
|
||||
var i OddsMarketWithSetting
|
||||
var i GetOddsWithSettingsByMarketIDRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.EventID,
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
|||
|
||||
return GetBet{
|
||||
ID: bet.ID,
|
||||
CompanyID: bet.CompanyID,
|
||||
Amount: Currency(bet.Amount),
|
||||
TotalOdds: bet.TotalOdds,
|
||||
Status: OutcomeStatus(bet.Status),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ type BaseEvent struct {
|
|||
IsMonitored bool
|
||||
DefaultIsFeatured bool
|
||||
DefaultIsActive bool
|
||||
DefaultWinningUpperLimit int32
|
||||
DefaultWinningUpperLimit int64
|
||||
Score ValidString
|
||||
MatchMinute ValidInt
|
||||
TimerStatus ValidString
|
||||
|
|
@ -97,7 +97,7 @@ type BaseEventRes struct {
|
|||
IsMonitored bool `json:"is_monitored"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
Score string `json:"score"`
|
||||
MatchMinute int `json:"match_minute"`
|
||||
TimerStatus string `json:"timer_status"`
|
||||
|
|
@ -128,7 +128,7 @@ type EventWithSettings struct {
|
|||
WinningUpperLimit int32
|
||||
DefaultIsFeatured bool
|
||||
DefaultIsActive bool
|
||||
DefaultWinningUpperLimit int32
|
||||
DefaultWinningUpperLimit int64
|
||||
Score ValidString
|
||||
MatchMinute ValidInt
|
||||
TimerStatus ValidString
|
||||
|
|
@ -155,6 +155,7 @@ type CreateEvent struct {
|
|||
IsLive bool
|
||||
Status EventStatus
|
||||
Source EventSource
|
||||
DefaultWinningUpperLimit int64
|
||||
}
|
||||
|
||||
type EventWithSettingsRes struct {
|
||||
|
|
@ -179,7 +180,7 @@ type EventWithSettingsRes struct {
|
|||
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||
DefaultIsActive bool `json:"default_is_active"`
|
||||
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||
DefaultWinningUpperLimit int64 `json:"default_winning_upper_limit"`
|
||||
Score string `json:"score,omitempty"`
|
||||
MatchMinute int `json:"match_minute,omitempty"`
|
||||
TimerStatus string `json:"timer_status,omitempty"`
|
||||
|
|
@ -294,6 +295,7 @@ func ConvertCreateEvent(e CreateEvent) dbgen.InsertEventParams {
|
|||
IsLive: e.IsLive,
|
||||
Status: string(e.Status),
|
||||
Source: string(e.Source),
|
||||
DefaultWinningUpperLimit: e.DefaultWinningUpperLimit,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ func ConvertDBLeagueWithSetting(lws dbgen.LeagueWithSetting) LeagueWithSettings
|
|||
return LeagueWithSettings{
|
||||
ID: lws.ID,
|
||||
Name: lws.Name,
|
||||
CompanyID: lws.CompanyID,
|
||||
CompanyID: lws.CompanyID.Int64,
|
||||
CountryCode: ValidString{
|
||||
Value: lws.CountryCode.String,
|
||||
Valid: lws.CountryCode.Valid,
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ type Notification struct {
|
|||
RecipientID int64 `json:"recipient_id"`
|
||||
Type NotificationType `json:"type"`
|
||||
Level NotificationLevel `json:"level"`
|
||||
ErrorSeverity *NotificationErrorSeverity `json:"error_severity"`
|
||||
ErrorSeverity NotificationErrorSeverity `json:"error_severity"`
|
||||
Reciever NotificationRecieverSide `json:"reciever"`
|
||||
IsRead bool `json:"is_read"`
|
||||
DeliveryStatus NotificationDeliveryStatus `json:"delivery_status,omitempty"`
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ type SettingList struct {
|
|||
TotalWinningLimit Currency `json:"total_winning_limit"`
|
||||
AmountForBetReferral Currency `json:"amount_for_bet_referral"`
|
||||
CashbackAmountCap Currency `json:"cashback_amount_cap"`
|
||||
DefaultWinningLimit int64 `json:"default_winning_limit"`
|
||||
}
|
||||
|
||||
type SettingListRes struct {
|
||||
|
|
@ -33,6 +34,7 @@ type SettingListRes struct {
|
|||
TotalWinningLimit float32 `json:"total_winning_limit"`
|
||||
AmountForBetReferral float32 `json:"amount_for_bet_referral"`
|
||||
CashbackAmountCap float32 `json:"cashback_amount_cap"`
|
||||
DefaultWinningLimit int64 `json:"default_winning_limit"`
|
||||
}
|
||||
|
||||
func ConvertSettingListRes(settings SettingList) SettingListRes {
|
||||
|
|
@ -44,6 +46,7 @@ func ConvertSettingListRes(settings SettingList) SettingListRes {
|
|||
TotalWinningLimit: settings.TotalWinningLimit.Float32(),
|
||||
AmountForBetReferral: settings.AmountForBetReferral.Float32(),
|
||||
CashbackAmountCap: settings.CashbackAmountCap.Float32(),
|
||||
DefaultWinningLimit: settings.DefaultWinningLimit,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +58,18 @@ type SaveSettingListReq struct {
|
|||
TotalWinningLimit *float32 `json:"total_winning_limit,omitempty"`
|
||||
AmountForBetReferral *float32 `json:"amount_for_bet_referral,omitempty"`
|
||||
CashbackAmountCap *float32 `json:"cashback_amount_cap,omitempty"`
|
||||
DefaultWinningLimit *int64 `json:"default_winning_limit,omitempty"`
|
||||
}
|
||||
|
||||
type ValidSettingList struct {
|
||||
SMSProvider ValidString
|
||||
MaxNumberOfOutcomes ValidInt64
|
||||
BetAmountLimit ValidCurrency
|
||||
DailyTicketPerIP ValidInt64
|
||||
TotalWinningLimit ValidCurrency
|
||||
AmountForBetReferral ValidCurrency
|
||||
CashbackAmountCap ValidCurrency
|
||||
DefaultWinningLimit ValidInt64
|
||||
}
|
||||
|
||||
func ConvertSaveSettingListReq(settings SaveSettingListReq) ValidSettingList {
|
||||
|
|
@ -66,19 +81,10 @@ func ConvertSaveSettingListReq(settings SaveSettingListReq) ValidSettingList {
|
|||
TotalWinningLimit: ConvertFloat32PtrToCurrency(settings.TotalWinningLimit),
|
||||
AmountForBetReferral: ConvertFloat32PtrToCurrency(settings.AmountForBetReferral),
|
||||
CashbackAmountCap: ConvertFloat32PtrToCurrency(settings.CashbackAmountCap),
|
||||
DefaultWinningLimit: ConvertInt64Ptr(settings.DefaultWinningLimit),
|
||||
}
|
||||
}
|
||||
|
||||
type ValidSettingList struct {
|
||||
SMSProvider ValidString
|
||||
MaxNumberOfOutcomes ValidInt64
|
||||
BetAmountLimit ValidCurrency
|
||||
DailyTicketPerIP ValidInt64
|
||||
TotalWinningLimit ValidCurrency
|
||||
AmountForBetReferral ValidCurrency
|
||||
CashbackAmountCap ValidCurrency
|
||||
}
|
||||
|
||||
// Always make sure to run the validation before converting this
|
||||
func (vsl *ValidSettingList) ToSettingList() SettingList {
|
||||
return SettingList{
|
||||
|
|
@ -89,6 +95,7 @@ func (vsl *ValidSettingList) ToSettingList() SettingList {
|
|||
TotalWinningLimit: Currency(vsl.TotalWinningLimit.Value),
|
||||
AmountForBetReferral: Currency(vsl.AmountForBetReferral.Value),
|
||||
CashbackAmountCap: Currency(vsl.CashbackAmountCap.Value),
|
||||
DefaultWinningLimit: vsl.DefaultWinningLimit.Value,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +111,7 @@ func (vsl *ValidSettingList) GetInt64SettingsMap() map[string]*ValidInt64 {
|
|||
return map[string]*ValidInt64{
|
||||
"max_number_of_outcomes": &vsl.MaxNumberOfOutcomes,
|
||||
"daily_ticket_limit": &vsl.DailyTicketPerIP,
|
||||
"default_winning_limit": &vsl.DefaultWinningLimit,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany)
|
|||
for {
|
||||
_, err := s.queries.GetCompanyIDUsingSlug(ctx, uniqueSlug)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
// slug is unique
|
||||
break
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ func (s *Store) SaveEvent(ctx context.Context, e domain.CreateEvent) error {
|
|||
return s.queries.InsertEvent(ctx, domain.ConvertCreateEvent(e))
|
||||
}
|
||||
|
||||
|
||||
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
||||
return s.queries.ListLiveEvents(ctx)
|
||||
}
|
||||
|
|
@ -86,6 +85,7 @@ func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filt
|
|||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
IsFeatured: filter.Featured.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -100,13 +100,69 @@ func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filt
|
|||
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||
LastStartTime: filter.LastStartTime.ToPG(),
|
||||
CountryCode: filter.CountryCode.ToPG(),
|
||||
IsFeatured: filter.Featured.ToPG(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
||||
return domain.ConvertDBEventWithSettings(events), int64(numberOfPages), nil
|
||||
|
||||
result := make([]domain.EventWithSettings, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
result[i] = domain.EventWithSettings{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeKitImage,
|
||||
AwayTeamImage: event.AwayKitImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: domain.ValidString{
|
||||
Value: event.LeagueCc.String,
|
||||
Valid: event.LeagueCc.Valid,
|
||||
},
|
||||
StartTime: event.StartTime.Time.UTC(),
|
||||
Source: domain.EventSource(event.Source),
|
||||
Status: domain.EventStatus(event.Status),
|
||||
IsFeatured: event.IsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
IsActive: event.IsActive,
|
||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||
DefaultIsActive: event.DefaultIsActive,
|
||||
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||
Score: domain.ValidString{
|
||||
Value: event.Score.String,
|
||||
Valid: event.Score.Valid,
|
||||
},
|
||||
MatchMinute: domain.ValidInt{
|
||||
Value: int(event.MatchMinute.Int32),
|
||||
Valid: event.MatchMinute.Valid,
|
||||
},
|
||||
TimerStatus: domain.ValidString{
|
||||
Value: event.TimerStatus.String,
|
||||
Valid: event.TimerStatus.Valid,
|
||||
},
|
||||
AddedTime: domain.ValidInt{
|
||||
Value: int(event.AddedTime.Int32),
|
||||
Valid: event.AddedTime.Valid,
|
||||
},
|
||||
MatchPeriod: domain.ValidInt{
|
||||
Value: int(event.MatchPeriod.Int32),
|
||||
Valid: event.MatchPeriod.Valid,
|
||||
},
|
||||
IsLive: event.IsLive,
|
||||
UpdatedAt: event.UpdatedAt.Time,
|
||||
FetchedAt: event.FetchedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
return result, int64(numberOfPages), nil
|
||||
}
|
||||
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error) {
|
||||
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
||||
|
|
@ -125,7 +181,56 @@ func (s *Store) GetEventWithSettingByID(ctx context.Context, ID string, companyI
|
|||
return domain.EventWithSettings{}, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBEventWithSetting(event), nil
|
||||
res := domain.EventWithSettings{
|
||||
ID: event.ID,
|
||||
SportID: event.SportID,
|
||||
MatchName: event.MatchName,
|
||||
HomeTeam: event.HomeTeam,
|
||||
AwayTeam: event.AwayTeam,
|
||||
HomeTeamID: event.HomeTeamID,
|
||||
AwayTeamID: event.AwayTeamID,
|
||||
HomeTeamImage: event.HomeKitImage,
|
||||
AwayTeamImage: event.AwayKitImage,
|
||||
LeagueID: event.LeagueID,
|
||||
LeagueName: event.LeagueName,
|
||||
LeagueCC: domain.ValidString{
|
||||
Value: event.LeagueCc.String,
|
||||
Valid: event.LeagueCc.Valid,
|
||||
},
|
||||
StartTime: event.StartTime.Time.UTC(),
|
||||
Source: domain.EventSource(event.Source),
|
||||
Status: domain.EventStatus(event.Status),
|
||||
IsFeatured: event.IsFeatured,
|
||||
IsMonitored: event.IsMonitored,
|
||||
IsActive: event.IsActive,
|
||||
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||
DefaultIsActive: event.DefaultIsActive,
|
||||
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||
Score: domain.ValidString{
|
||||
Value: event.Score.String,
|
||||
Valid: event.Score.Valid,
|
||||
},
|
||||
MatchMinute: domain.ValidInt{
|
||||
Value: int(event.MatchMinute.Int32),
|
||||
Valid: event.MatchMinute.Valid,
|
||||
},
|
||||
TimerStatus: domain.ValidString{
|
||||
Value: event.TimerStatus.String,
|
||||
Valid: event.TimerStatus.Valid,
|
||||
},
|
||||
AddedTime: domain.ValidInt{
|
||||
Value: int(event.AddedTime.Int32),
|
||||
Valid: event.AddedTime.Valid,
|
||||
},
|
||||
MatchPeriod: domain.ValidInt{
|
||||
Value: int(event.MatchPeriod.Int32),
|
||||
Valid: event.MatchPeriod.Valid,
|
||||
},
|
||||
IsLive: event.IsLive,
|
||||
UpdatedAt: event.UpdatedAt.Time,
|
||||
FetchedAt: event.FetchedAt.Time,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error {
|
||||
params := dbgen.UpdateMatchResultParams{
|
||||
|
|
@ -173,7 +278,7 @@ func (s *Store) UpdateEventMonitored(ctx context.Context, eventID string, IsMoni
|
|||
}
|
||||
|
||||
func (s *Store) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
||||
return s.queries.SaveEventSettings(ctx, domain.ConvertUpdateEventSettings(event));
|
||||
return s.queries.SaveEventSettings(ctx, domain.ConvertUpdateEventSettings(event))
|
||||
}
|
||||
|
||||
func (s *Store) DeleteEvent(ctx context.Context, eventID string) error {
|
||||
|
|
|
|||
|
|
@ -51,13 +51,39 @@ func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, fil
|
|||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||
Valid: filter.Offset.Valid,
|
||||
},
|
||||
IsFeatured: filter.IsFeatured.ToPG(),
|
||||
IsActive: filter.IsActive.ToPG(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return domain.ConvertDBLeagueWithSettings(l), nil
|
||||
result := make([]domain.LeagueWithSettings, len(l))
|
||||
for i, league := range l {
|
||||
result[i] = domain.LeagueWithSettings{
|
||||
ID: league.ID,
|
||||
Name: league.Name,
|
||||
CompanyID: league.CompanyID.Int64,
|
||||
CountryCode: domain.ValidString{
|
||||
Value: league.CountryCode.String,
|
||||
Valid: league.CountryCode.Valid,
|
||||
},
|
||||
Bet365ID: domain.ValidInt32{
|
||||
Value: league.Bet365ID.Int32,
|
||||
Valid: league.Bet365ID.Valid,
|
||||
},
|
||||
IsActive: league.IsActive,
|
||||
SportID: league.SportID,
|
||||
IsFeatured: league.IsFeatured,
|
||||
UpdatedAt: league.UpdatedAt.Time,
|
||||
|
||||
DefaultIsActive: league.DefaultIsActive,
|
||||
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ func (s *Store) DisconnectWebSocket(recipientID int64) {
|
|||
|
||||
func (r *Repository) CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error) {
|
||||
var errorSeverity pgtype.Text
|
||||
if notification.ErrorSeverity != nil {
|
||||
errorSeverity.String = string(*notification.ErrorSeverity)
|
||||
if notification.ErrorSeverity != "" {
|
||||
errorSeverity.String = string(notification.ErrorSeverity)
|
||||
errorSeverity.Valid = true
|
||||
}
|
||||
|
||||
|
|
@ -155,10 +155,12 @@ func (r *Repository) ListRecipientIDs(ctx context.Context, receiver domain.Notif
|
|||
}
|
||||
|
||||
func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
|
||||
var errorSeverity *domain.NotificationErrorSeverity
|
||||
var errorSeverity domain.NotificationErrorSeverity
|
||||
if dbNotif.ErrorSeverity.Valid {
|
||||
s := domain.NotificationErrorSeverity(dbNotif.ErrorSeverity.String)
|
||||
errorSeverity = &s
|
||||
errorSeverity = domain.NotificationErrorSeverity(dbNotif.ErrorSeverity.String)
|
||||
|
||||
} else {
|
||||
errorSeverity = ""
|
||||
}
|
||||
|
||||
var deliveryChannel domain.DeliveryChannel
|
||||
|
|
@ -317,8 +319,6 @@ func (s *Store) CountUnreadNotifications(ctx context.Context, userID int64) (int
|
|||
return count, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
// func (s *Store) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
|
||||
// dbNotifications, err := s.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
|
||||
// Limit: int32(limit),
|
||||
|
|
|
|||
|
|
@ -88,16 +88,39 @@ func (s *Store) GetAllOddsWithSettings(ctx context.Context, companyID int64, fil
|
|||
return nil, err
|
||||
}
|
||||
|
||||
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
// domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
if err != nil {
|
||||
result := make([]domain.OddMarketWithSettings, len(odds))
|
||||
for i, o := range odds {
|
||||
var rawOdds []json.RawMessage
|
||||
if len(o.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(o.RawOdds, &rawOdds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
result[i] = domain.OddMarketWithSettings{
|
||||
ID: o.ID,
|
||||
EventID: o.EventID,
|
||||
MarketType: o.MarketType,
|
||||
MarketName: o.MarketName,
|
||||
MarketCategory: o.MarketCategory,
|
||||
MarketID: o.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: o.FetchedAt.Time,
|
||||
ExpiresAt: o.ExpiresAt.Time,
|
||||
IsActive: o.IsActive,
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
func (s *Store) GetOddByID(ctx context.Context, id int64) (domain.OddMarket, error) {
|
||||
odd, err := s.queries.GetOddByID(ctx, id)
|
||||
if err != nil {
|
||||
|
|
@ -141,12 +164,34 @@ func (s *Store) GetOddsWithSettingsByMarketID(ctx context.Context, marketID stri
|
|||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
|
||||
convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||
// convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||
|
||||
if err != nil {
|
||||
// if err != nil {
|
||||
// return domain.OddMarketWithSettings{}, err
|
||||
// }
|
||||
|
||||
var rawOdds []json.RawMessage
|
||||
if len(odds.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil {
|
||||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
return convertedOdd, nil
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
|
||||
converted := domain.OddMarketWithSettings{
|
||||
ID: odds.ID,
|
||||
EventID: odds.EventID,
|
||||
MarketType: odds.MarketType,
|
||||
MarketName: odds.MarketName,
|
||||
MarketCategory: odds.MarketCategory,
|
||||
MarketID: odds.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: odds.FetchedAt.Time,
|
||||
ExpiresAt: odds.ExpiresAt.Time,
|
||||
IsActive: odds.IsActive,
|
||||
}
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID int64) (domain.OddMarketWithSettings, error) {
|
||||
|
|
@ -160,12 +205,35 @@ func (s *Store) GetOddsWithSettingsByID(ctx context.Context, ID int64, companyID
|
|||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
|
||||
convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||
// convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||
|
||||
if err != nil {
|
||||
// if err != nil {
|
||||
// return domain.OddMarketWithSettings{}, err
|
||||
// }
|
||||
|
||||
var rawOdds []json.RawMessage
|
||||
if len(odds.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil {
|
||||
return domain.OddMarketWithSettings{}, err
|
||||
}
|
||||
return convertedOdd, nil
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
|
||||
converted := domain.OddMarketWithSettings{
|
||||
ID: odds.ID,
|
||||
EventID: odds.EventID,
|
||||
MarketType: odds.MarketType,
|
||||
MarketName: odds.MarketName,
|
||||
MarketCategory: odds.MarketCategory,
|
||||
MarketID: odds.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: odds.FetchedAt.Time,
|
||||
ExpiresAt: odds.ExpiresAt.Time,
|
||||
IsActive: odds.IsActive,
|
||||
}
|
||||
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||
|
|
@ -208,12 +276,37 @@ func (s *Store) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID str
|
|||
}
|
||||
|
||||
// Map the results to domain.Odd
|
||||
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
if err != nil {
|
||||
// domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
result := make([]domain.OddMarketWithSettings, len(odds))
|
||||
for i, o := range odds {
|
||||
var rawOdds []json.RawMessage
|
||||
if len(o.RawOdds) > 0 {
|
||||
if err := json.Unmarshal(o.RawOdds, &rawOdds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||
}
|
||||
|
||||
return domainOdds, nil
|
||||
result[i] = domain.OddMarketWithSettings{
|
||||
ID: o.ID,
|
||||
EventID: o.EventID,
|
||||
MarketType: o.MarketType,
|
||||
MarketName: o.MarketName,
|
||||
MarketCategory: o.MarketCategory,
|
||||
MarketID: o.MarketID,
|
||||
RawOdds: rawOdds,
|
||||
FetchedAt: o.FetchedAt.Time,
|
||||
ExpiresAt: o.ExpiresAt.Time,
|
||||
IsActive: o.IsActive,
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package repository
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
|
|
@ -104,8 +105,10 @@ func (s *Store) GetAllShopBet(ctx context.Context, filter domain.ShopBetFilter)
|
|||
func (s *Store) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDetail, error) {
|
||||
bet, err := s.queries.GetShopBetByID(ctx, id)
|
||||
if err != nil {
|
||||
fmt.Printf("GetShopBetByID Repo BetID %d err %v \n", id, err.Error())
|
||||
return domain.ShopBetDetail{}, err
|
||||
}
|
||||
|
||||
return convertDBShopBetDetail(bet), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ func convertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) domain.GetTicket {
|
|||
}
|
||||
return domain.GetTicket{
|
||||
ID: ticket.ID,
|
||||
CompanyID: ticket.CompanyID,
|
||||
Amount: domain.Currency(ticket.Amount),
|
||||
TotalOdds: ticket.TotalOdds,
|
||||
Outcomes: outcomes,
|
||||
|
|
|
|||
|
|
@ -283,8 +283,10 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
)
|
||||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
if count >= 2 {
|
||||
return domain.CreateBetRes{}, fmt.Errorf("bet already placed twice")
|
||||
|
||||
// TODO: Make this a setting
|
||||
if role == domain.RoleCustomer && count >= 10 {
|
||||
return domain.CreateBetRes{}, fmt.Errorf("max user limit for single outcome")
|
||||
}
|
||||
|
||||
fastCode := helpers.GenerateFastCode()
|
||||
|
|
@ -340,6 +342,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
|
||||
if role == domain.RoleBranchManager {
|
||||
if branch.BranchManagerID != userID {
|
||||
s.mongoLogger.Warn("unauthorized branch for branch manager",
|
||||
zap.Int64("branch_id", *req.BranchID),
|
||||
|
|
@ -347,10 +350,12 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
|||
)
|
||||
return domain.CreateBetRes{}, err
|
||||
}
|
||||
|
||||
if branch.CompanyID == companyID {
|
||||
}
|
||||
if branch.CompanyID != companyID {
|
||||
s.mongoLogger.Warn("unauthorized company",
|
||||
zap.Int64("branch_id", *req.BranchID),
|
||||
zap.Int64("branch_company_id", branch.CompanyID),
|
||||
zap.Int64("company_id", companyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
|
@ -1073,8 +1078,6 @@ func (s *Service) SendErrorStatusNotification(ctx context.Context, status domain
|
|||
message = "We have encounter an error with your bet. We will fix it as soon as we can"
|
||||
}
|
||||
|
||||
errorSeverityLevel := domain.NotificationErrorSeverityFatal
|
||||
|
||||
betNotification := &domain.Notification{
|
||||
RecipientID: userID,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
|
|
@ -1088,7 +1091,7 @@ func (s *Service) SendErrorStatusNotification(ctx context.Context, status domain
|
|||
Message: message,
|
||||
},
|
||||
Priority: 1,
|
||||
ErrorSeverity: &errorSeverityLevel,
|
||||
ErrorSeverity: domain.NotificationErrorSeverityHigh,
|
||||
Metadata: fmt.Appendf(nil, `{
|
||||
"status":%v
|
||||
"more": %v
|
||||
|
|
@ -1117,9 +1120,8 @@ func (s *Service) SendAdminErrorAlertNotification(ctx context.Context, status do
|
|||
message = "We have encounter an error with bet. We will fix it as soon as we can"
|
||||
}
|
||||
|
||||
errorSeverity := domain.NotificationErrorSeverityHigh
|
||||
betNotification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
ErrorSeverity: domain.NotificationErrorSeverityHigh,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
|
|
@ -1322,7 +1324,6 @@ func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
|
||||
for _, bet := range bets {
|
||||
shouldProcess := true
|
||||
loseCount := 0
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import (
|
|||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"go.uber.org/zap"
|
||||
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||
)
|
||||
|
|
@ -21,13 +23,15 @@ import (
|
|||
type service struct {
|
||||
token string
|
||||
store *repository.Store
|
||||
settingSvc settings.Service
|
||||
mongoLogger *zap.Logger
|
||||
}
|
||||
|
||||
func New(token string, store *repository.Store, mongoLogger *zap.Logger) Service {
|
||||
func New(token string, store *repository.Store, settingSvc settings.Service, mongoLogger *zap.Logger) Service {
|
||||
return &service{
|
||||
token: token,
|
||||
store: store,
|
||||
settingSvc: settingSvc,
|
||||
mongoLogger: mongoLogger,
|
||||
}
|
||||
}
|
||||
|
|
@ -206,22 +210,31 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_url string, source domain.EventSource) {
|
||||
const pageLimit int = 200
|
||||
sportIDs := []int{1, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91}
|
||||
// sportIDs := []int{1}
|
||||
|
||||
settingsList, err := s.settingSvc.GetGlobalSettingList(ctx)
|
||||
|
||||
if err != nil {
|
||||
s.mongoLogger.Error("Failed to fetch event data for page", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
const pageLimit int = 1
|
||||
// sportIDs := []int{1, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91}
|
||||
sportIDs := []int{1}
|
||||
|
||||
var skippedLeague []string
|
||||
var totalEvents = 0
|
||||
nilAway := 0
|
||||
for sportIndex, sportID := range sportIDs {
|
||||
var totalPages int = 1
|
||||
var page int = 0
|
||||
var count int = 0
|
||||
var skippedLeague []string
|
||||
var totalEvents = 0
|
||||
var pageCount int = 0
|
||||
var sportEvents = 0
|
||||
logger := s.mongoLogger.With(
|
||||
zap.String("source", string(source)),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.String("sport_name", domain.Sport(sportID).String()),
|
||||
zap.Int("count", count),
|
||||
zap.Int("totalEvents", totalEvents),
|
||||
zap.Int("count", pageCount),
|
||||
zap.Int("Skipped leagues", len(skippedLeague)),
|
||||
)
|
||||
for page <= totalPages {
|
||||
|
|
@ -303,32 +316,31 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
event := domain.CreateEvent{
|
||||
ID: ev.ID,
|
||||
SportID: convertInt32(ev.SportID),
|
||||
MatchName: "",
|
||||
HomeTeam: ev.Home.Name,
|
||||
AwayTeam: "", // handle nil safely
|
||||
HomeTeamID: convertInt64(ev.Home.ID),
|
||||
AwayTeamID: 0,
|
||||
HomeTeamImage: "",
|
||||
AwayTeamImage: "",
|
||||
LeagueID: convertInt64(ev.League.ID),
|
||||
LeagueName: ev.League.Name,
|
||||
StartTime: time.Unix(startUnix, 0).UTC(),
|
||||
Source: source,
|
||||
IsLive: false,
|
||||
Status: domain.STATUS_PENDING,
|
||||
DefaultWinningUpperLimit: settingsList.DefaultWinningLimit,
|
||||
}
|
||||
|
||||
if ev.Away != nil {
|
||||
dataLogger.Info("event away is empty")
|
||||
event.AwayTeam = ev.Away.Name
|
||||
event.AwayTeamID = convertInt64(ev.Away.ID)
|
||||
event.MatchName = ev.Home.Name + " vs " + ev.Away.Name
|
||||
} else {
|
||||
nilAway += 1
|
||||
}
|
||||
ok, err := s.CheckAndInsertEventHistory(ctx, event)
|
||||
ok, _ := s.CheckAndInsertEventHistory(ctx, event)
|
||||
|
||||
if err != nil {
|
||||
dataLogger.Error("failed to check and insert event history", zap.Error(err))
|
||||
}
|
||||
// if err != nil {
|
||||
// dataLogger.Error("failed to check and insert event history", zap.Error(err))
|
||||
// }
|
||||
|
||||
if ok {
|
||||
dataLogger.Info("event history has been recorded")
|
||||
|
|
@ -338,7 +350,8 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
if err != nil {
|
||||
dataLogger.Error("failed to save upcoming event", zap.Error(err))
|
||||
}
|
||||
totalEvents += 1
|
||||
sportEvents += 1
|
||||
|
||||
}
|
||||
|
||||
// log.Printf("⚠️ Skipped leagues %v", len(skippedLeague))
|
||||
|
|
@ -346,26 +359,26 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
|||
|
||||
totalPages = data.Pager.Total / data.Pager.PerPage
|
||||
|
||||
if count >= pageLimit {
|
||||
if pageCount >= pageLimit {
|
||||
break
|
||||
}
|
||||
if page > totalPages {
|
||||
break
|
||||
}
|
||||
count++
|
||||
pageCount++
|
||||
}
|
||||
|
||||
logger.Info("Completed adding sport", zap.Int("number_of_events_in_sport", sportEvents))
|
||||
totalEvents += sportEvents
|
||||
}
|
||||
|
||||
s.mongoLogger.Info(
|
||||
"Successfully fetched upcoming events",
|
||||
zap.String("source", string(source)),
|
||||
zap.Int("totalEvents", totalEvents),
|
||||
zap.Int("sport_id", sportID),
|
||||
zap.String("sport_name", domain.Sport(sportID).String()),
|
||||
zap.Int("page", page),
|
||||
zap.Int("total_pages", totalPages),
|
||||
zap.Int("Skipped leagues", len(skippedLeague)),
|
||||
zap.Int("Events with empty away data", nilAway),
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) CheckAndInsertEventHistory(ctx context.Context, event domain.CreateEvent) (bool, error) {
|
||||
|
|
@ -379,7 +392,9 @@ func (s *service) CheckAndInsertEventHistory(ctx context.Context, event domain.C
|
|||
)
|
||||
|
||||
if err != nil {
|
||||
eventLogger.Error("failed to get event is_monitored", zap.Error(err))
|
||||
if err != pgx.ErrNoRows {
|
||||
eventLogger.Info("failed to get event is_monitored", zap.Error(err))
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -334,14 +334,22 @@ func (s *Service) SendNotificationSMS(ctx context.Context, recipientID int64, me
|
|||
}
|
||||
|
||||
if !user.PhoneVerified {
|
||||
return fmt.Errorf("Cannot send notification to unverified phone number")
|
||||
return fmt.Errorf("cannot send notification to unverified phone number")
|
||||
}
|
||||
|
||||
if user.PhoneNumber == "" {
|
||||
return fmt.Errorf("Phone Number is invalid")
|
||||
return fmt.Errorf("phone Number is invalid")
|
||||
}
|
||||
err = s.messengerSvc.SendSMS(ctx, user.PhoneNumber, message, user.CompanyID)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error("[NotificationSvc.HandleNotification] Failed to send notification SMS",
|
||||
zap.Int64("recipient_id", recipientID),
|
||||
zap.String("user_phone_number", user.PhoneNumber),
|
||||
zap.String("message", message),
|
||||
zap.Int64("company_id", user.CompanyID.Value),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -357,14 +365,22 @@ func (s *Service) SendNotificationEmail(ctx context.Context, recipientID int64,
|
|||
}
|
||||
|
||||
if !user.EmailVerified {
|
||||
return fmt.Errorf("Cannot send notification to unverified email")
|
||||
return fmt.Errorf("cannot send notification to unverified email")
|
||||
}
|
||||
|
||||
if user.PhoneNumber == "" {
|
||||
return fmt.Errorf("Email is invalid")
|
||||
if user.Email == "" {
|
||||
return fmt.Errorf("email is invalid")
|
||||
}
|
||||
err = s.messengerSvc.SendEmail(ctx, user.PhoneNumber, message, subject)
|
||||
err = s.messengerSvc.SendEmail(ctx, user.Email, message, subject)
|
||||
if err != nil {
|
||||
s.mongoLogger.Error("[NotificationSvc.HandleNotification] Failed to send notification SMS",
|
||||
zap.Int64("recipient_id", recipientID),
|
||||
zap.String("user_email", user.Email),
|
||||
zap.String("message", message),
|
||||
zap.Int64("company_id", user.CompanyID.Value),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -541,9 +541,8 @@ func (s *Service) SendAdminResultStatusErrorNotification(
|
|||
}
|
||||
|
||||
headline, message := buildHeadlineAndMessage(counts)
|
||||
errorSeverity := domain.NotificationErrorSeverityLow
|
||||
notification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
ErrorSeverity: domain.NotificationErrorSeverityHigh,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
IsRead: false,
|
||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ func (s *Service) CreateShopBet(ctx context.Context, userID int64, role domain.R
|
|||
newBet, err := s.betSvc.PlaceBet(ctx, domain.CreateBetReq{
|
||||
Outcomes: req.Outcomes,
|
||||
Amount: req.Amount,
|
||||
BranchID: branchID,
|
||||
}, userID, role, *companyID)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -94,6 +95,10 @@ func (s *Service) CreateShopBet(ctx context.Context, userID int64, role domain.R
|
|||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return domain.ShopBet{}, err
|
||||
}
|
||||
|
||||
return s.transactionStore.CreateShopBet(ctx, domain.CreateShopBet{
|
||||
ShopTransactionID: newTransaction.ID,
|
||||
CashoutID: cashoutID,
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ func (s *Service) notifyCashiersForVerification(ctx context.Context, depositID,
|
|||
Metadata: metadataJSON,
|
||||
}
|
||||
|
||||
if err := s.notificationStore.SendNotification(ctx, notification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, notification); err != nil {
|
||||
s.logger.Error("failed to send verification notification",
|
||||
"cashier_id", cashier.ID,
|
||||
"error", err)
|
||||
|
|
@ -199,7 +199,7 @@ func (s *Service) notifyCustomerVerificationResult(ctx context.Context, deposit
|
|||
Metadata: metadataJSON,
|
||||
}
|
||||
|
||||
if err := s.notificationStore.SendNotification(ctx, notification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, notification); err != nil {
|
||||
s.logger.Error("failed to send deposit result notification",
|
||||
"customer_id", deposit.CustomerID,
|
||||
"error", err)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ type Service struct {
|
|||
walletStore WalletStore
|
||||
transferStore TransferStore
|
||||
directDepositStore DirectDepositStore
|
||||
notificationStore notificationservice.NotificationStore
|
||||
notificationSvc *notificationservice.Service
|
||||
userSvc *user.Service
|
||||
mongoLogger *zap.Logger
|
||||
|
|
@ -26,7 +25,6 @@ func NewService(
|
|||
walletStore WalletStore,
|
||||
transferStore TransferStore,
|
||||
directDepositStore DirectDepositStore,
|
||||
notificationStore notificationservice.NotificationStore,
|
||||
notificationSvc *notificationservice.Service,
|
||||
userSvc *user.Service,
|
||||
mongoLogger *zap.Logger,
|
||||
|
|
@ -38,7 +36,6 @@ func NewService(
|
|||
transferStore: transferStore,
|
||||
directDepositStore: directDepositStore,
|
||||
// approvalStore: approvalStore,
|
||||
notificationStore: notificationStore,
|
||||
notificationSvc: notificationSvc,
|
||||
userSvc: userSvc,
|
||||
mongoLogger: mongoLogger,
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ func (s *Service) SendTransferNotification(ctx context.Context, senderWallet dom
|
|||
}
|
||||
|
||||
// Sender notifications
|
||||
if err := s.notificationStore.SendNotification(ctx, senderNotify); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, senderNotify); err != nil {
|
||||
s.logger.Error("failed to send sender notification",
|
||||
"user_id", "",
|
||||
"error", err)
|
||||
|
|
@ -163,7 +163,7 @@ func (s *Service) SendTransferNotification(ctx context.Context, senderWallet dom
|
|||
}`, amount, receiverWallet.Balance, receiverWallet.ID)),
|
||||
}
|
||||
// Sender notifications
|
||||
if err := s.notificationStore.SendNotification(ctx, receiverNotify); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, receiverNotify); err != nil {
|
||||
s.logger.Error("failed to send sender notification",
|
||||
"user_id", "",
|
||||
"error", err)
|
||||
|
|
|
|||
|
|
@ -304,10 +304,10 @@ func (s *Service) GetAdminNotificationRecipients(ctx context.Context, walletID i
|
|||
}
|
||||
|
||||
func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWallet domain.Wallet) error {
|
||||
errorSeverity := domain.NotificationErrorSeverityLow
|
||||
|
||||
// Send notification to admin team
|
||||
adminNotification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
ErrorSeverity: "low",
|
||||
IsRead: false,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
RecipientID: adminWallet.UserID,
|
||||
|
|
@ -343,7 +343,7 @@ func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWalle
|
|||
|
||||
for _, adminID := range adminRecipients {
|
||||
adminNotification.RecipientID = adminID
|
||||
if err := s.notificationStore.SendNotification(ctx, adminNotification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
||||
s.mongoLogger.Error("failed to send admin notification",
|
||||
zap.Int64("admin_id", adminID),
|
||||
zap.Error(err),
|
||||
|
|
@ -353,7 +353,7 @@ func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWalle
|
|||
|
||||
adminNotification.DeliveryChannel = domain.DeliveryChannelEmail
|
||||
|
||||
if err := s.notificationStore.SendNotification(ctx, adminNotification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
||||
s.mongoLogger.Error("failed to send email admin notification",
|
||||
zap.Int64("admin_id", adminID),
|
||||
zap.Error(err),
|
||||
|
|
@ -366,11 +366,9 @@ func (s *Service) SendAdminWalletLowNotification(ctx context.Context, adminWalle
|
|||
}
|
||||
|
||||
func (s *Service) SendAdminWalletInsufficientNotification(ctx context.Context, adminWallet domain.Wallet, amount domain.Currency) error {
|
||||
|
||||
errorSeverity := domain.NotificationErrorSeverityLow
|
||||
// Send notification to admin team
|
||||
adminNotification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
ErrorSeverity: domain.NotificationErrorSeverityLow,
|
||||
IsRead: false,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
RecipientID: adminWallet.UserID,
|
||||
|
|
@ -408,7 +406,7 @@ func (s *Service) SendAdminWalletInsufficientNotification(ctx context.Context, a
|
|||
}
|
||||
for _, adminID := range recipients {
|
||||
adminNotification.RecipientID = adminID
|
||||
if err := s.notificationStore.SendNotification(ctx, adminNotification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
||||
s.mongoLogger.Error("failed to send admin notification",
|
||||
zap.Int64("admin_id", adminID),
|
||||
zap.Error(err),
|
||||
|
|
@ -417,7 +415,7 @@ func (s *Service) SendAdminWalletInsufficientNotification(ctx context.Context, a
|
|||
}
|
||||
adminNotification.DeliveryChannel = domain.DeliveryChannelEmail
|
||||
|
||||
if err := s.notificationStore.SendNotification(ctx, adminNotification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, adminNotification); err != nil {
|
||||
s.mongoLogger.Error("failed to send email admin notification",
|
||||
zap.Int64("admin_id", adminID),
|
||||
zap.Error(err),
|
||||
|
|
@ -431,10 +429,9 @@ func (s *Service) SendAdminWalletInsufficientNotification(ctx context.Context, a
|
|||
}
|
||||
|
||||
func (s *Service) SendCustomerWalletInsufficientNotification(ctx context.Context, customerWallet domain.Wallet, amount domain.Currency) error {
|
||||
errorSeverity := domain.NotificationErrorSeverityLow
|
||||
// Send notification to admin team
|
||||
customerNotification := &domain.Notification{
|
||||
ErrorSeverity: &errorSeverity,
|
||||
ErrorSeverity: domain.NotificationErrorSeverityLow,
|
||||
IsRead: false,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
RecipientID: customerWallet.UserID,
|
||||
|
|
@ -460,7 +457,7 @@ func (s *Service) SendCustomerWalletInsufficientNotification(ctx context.Context
|
|||
}`, customerWallet.ID, customerWallet.Balance, amount.Float32()),
|
||||
}
|
||||
|
||||
if err := s.notificationStore.SendNotification(ctx, customerNotification); err != nil {
|
||||
if err := s.notificationSvc.SendNotification(ctx, customerNotification); err != nil {
|
||||
s.mongoLogger.Error("failed to create customer notification",
|
||||
zap.Int64("customer_id", customerWallet.UserID),
|
||||
zap.Error(err),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
|
|
@ -46,6 +45,19 @@ func (h *Handler) CreateBet(c *fiber.Ctx) error {
|
|||
|
||||
res, err := h.CreateBetInternal(c, req, userID, role, companyID.Value)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case bet.ErrEventHasBeenRemoved, bet.ErrEventHasNotEnded, bet.ErrRawOddInvalid, bet.ErrTotalBalanceNotEnough:
|
||||
h.mongoLoggerSvc.Info("PlaceBet failed",
|
||||
zap.Int("status_code", fiber.StatusBadRequest),
|
||||
zap.Int64("userID", userID),
|
||||
zap.Int64("companyID", companyID.Value),
|
||||
zap.String("role", string(role)),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
h.mongoLoggerSvc.Error("Failed to create bet",
|
||||
zap.Int("status_code", fiber.StatusInternalServerError),
|
||||
zap.Int64("user_id", userID),
|
||||
|
|
@ -200,7 +212,7 @@ func (h *Handler) CreateBetInternal(c *fiber.Ctx, req domain.CreateBetReq, userI
|
|||
res, err := h.betSvc.PlaceBet(c.Context(), req, userID, role, companyID)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case bet.ErrEventHasBeenRemoved, bet.ErrEventHasNotEnded, bet.ErrRawOddInvalid, wallet.ErrBalanceInsufficient:
|
||||
case bet.ErrEventHasBeenRemoved, bet.ErrEventHasNotEnded, bet.ErrRawOddInvalid, bet.ErrTotalBalanceNotEnough:
|
||||
h.mongoLoggerSvc.Info("PlaceBet failed",
|
||||
zap.Int("status_code", fiber.StatusBadRequest),
|
||||
zap.Int64("userID", userID),
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ func (h *Handler) GetTopLeagues(c *fiber.Ctx) error {
|
|||
Value: true,
|
||||
Valid: true,
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -208,12 +208,17 @@ func (h *Handler) CreateAndSendNotification(c *fiber.Ctx) error {
|
|||
// return fiber.NewError(fiber.StatusForbidden, "Unauthorized to send notification to this recipient")
|
||||
// }
|
||||
|
||||
errorSeverity := domain.NotificationErrorSeverityMedium
|
||||
if req.ErrorSeverity != nil {
|
||||
errorSeverity = *req.ErrorSeverity
|
||||
}
|
||||
|
||||
notification := &domain.Notification{
|
||||
ID: "",
|
||||
RecipientID: req.RecipientID,
|
||||
Type: req.Type,
|
||||
Level: req.Level,
|
||||
ErrorSeverity: req.ErrorSeverity,
|
||||
ErrorSeverity: errorSeverity,
|
||||
Reciever: req.Reciever,
|
||||
IsRead: false,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
|
|
@ -257,12 +262,17 @@ func (h *Handler) CreateAndSendNotification(c *fiber.Ctx) error {
|
|||
|
||||
notificationIDs := make([]string, 0, len(recipients))
|
||||
for _, user := range recipients {
|
||||
errorSeverity := domain.NotificationErrorSeverityMedium
|
||||
if req.ErrorSeverity != nil {
|
||||
errorSeverity = *req.ErrorSeverity
|
||||
}
|
||||
|
||||
notification := &domain.Notification{
|
||||
ID: "",
|
||||
RecipientID: user.ID,
|
||||
Type: req.Type,
|
||||
Level: req.Level,
|
||||
ErrorSeverity: req.ErrorSeverity,
|
||||
ErrorSeverity: errorSeverity,
|
||||
Reciever: req.Reciever,
|
||||
IsRead: false,
|
||||
DeliveryStatus: domain.DeliveryStatusPending,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (h *Handler) CreateShopBet(c *fiber.Ctx) error {
|
|||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
)
|
||||
return fiber.NewError(statusCode, "failed to create shop bet"+err.Error())
|
||||
return fiber.NewError(statusCode, err.Error())
|
||||
}
|
||||
res := domain.ConvertShopBet(shopBet)
|
||||
|
||||
|
|
@ -464,6 +464,7 @@ func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
|
|||
// role := c.Locals("role").(domain.Role)
|
||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||
branchID := c.Locals("branch_id").(domain.ValidInt64)
|
||||
role := c.Locals("role").(domain.Role)
|
||||
|
||||
searchQuery := c.Query("query")
|
||||
searchString := domain.ValidString{
|
||||
|
|
@ -509,6 +510,14 @@ func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
|
|||
}
|
||||
}
|
||||
|
||||
companyFilter := int64(c.QueryInt("company_id"))
|
||||
if role == domain.RoleSuperAdmin {
|
||||
companyID = domain.ValidInt64{
|
||||
Value: companyFilter,
|
||||
Valid: companyFilter != 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Check user role and fetch transactions accordingly
|
||||
transactions, err := h.transactionSvc.GetAllShopTransactions(c.Context(), domain.ShopTransactionFilter{
|
||||
CompanyID: companyID,
|
||||
|
|
|
|||
|
|
@ -123,6 +123,10 @@ func (h *Handler) GetTicketByID(c *fiber.Ctx) error {
|
|||
if ticket.CompanyID != companyID.Value {
|
||||
h.mongoLoggerSvc.Warn("User attempt to access another company ticket",
|
||||
zap.Int64("ticketID", id),
|
||||
zap.Int64("ticket CompanyID", ticket.CompanyID),
|
||||
zap.Int64("companyID", companyID.Value),
|
||||
zap.Bool("companyID Valid", companyID.Valid),
|
||||
|
||||
zap.Int("status_code", fiber.StatusNotFound),
|
||||
zap.Error(err),
|
||||
zap.Time("timestamp", time.Now()),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user