data type and enable/disable provider fixes
This commit is contained in:
commit
3624acbacb
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,3 +9,4 @@ logs/
|
||||||
app_logs/
|
app_logs/
|
||||||
backup/
|
backup/
|
||||||
reports/
|
reports/
|
||||||
|
exports/
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,8 +1,11 @@
|
||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Cashout",
|
"Cashout",
|
||||||
|
"dbgen",
|
||||||
|
"jackc",
|
||||||
"narg",
|
"narg",
|
||||||
"notificationservice",
|
"notificationservice",
|
||||||
|
"pgtype",
|
||||||
"sqlc"
|
"sqlc"
|
||||||
],
|
],
|
||||||
"cSpell.enabledFileTypes": {
|
"cSpell.enabledFileTypes": {
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ func main() {
|
||||||
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
||||||
userSvc := user.NewService(store, store, messengerSvc, cfg)
|
userSvc := user.NewService(store, store, messengerSvc, cfg)
|
||||||
eventSvc := event.New(cfg.Bet365Token, store, domain.MongoDBLogger)
|
eventSvc := event.New(cfg.Bet365Token, store, domain.MongoDBLogger)
|
||||||
oddsSvc := odds.New(store, cfg, logger, domain.MongoDBLogger)
|
oddsSvc := odds.New(store, cfg, eventSvc, logger, domain.MongoDBLogger)
|
||||||
notificationRepo := repository.NewNotificationRepository(store)
|
notificationRepo := repository.NewNotificationRepository(store)
|
||||||
virtuaGamesRepo := repository.NewVirtualGameRepository(store)
|
virtuaGamesRepo := repository.NewVirtualGameRepository(store)
|
||||||
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
|
notificationSvc := notificationservice.New(notificationRepo, domain.MongoDBLogger, logger, cfg, messengerSvc, userSvc)
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,222 @@
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
|
|
||||||
-- Users
|
-- Users
|
||||||
INSERT INTO users (
|
INSERT INTO users (
|
||||||
id, first_name, last_name, email, phone_number, password, role,
|
id,
|
||||||
email_verified, phone_verified, created_at, updated_at, suspended, company_id
|
first_name,
|
||||||
) VALUES
|
last_name,
|
||||||
(1, 'John', 'Doe', 'john.doe@example.com', NULL,
|
email,
|
||||||
crypt('password123', gen_salt('bf'))::bytea, 'customer',
|
phone_number,
|
||||||
TRUE, FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
password,
|
||||||
|
role,
|
||||||
(2, 'Test', 'Admin', 'test.admin@gmail.com', '0988554466',
|
email_verified,
|
||||||
crypt('password123', gen_salt('bf'))::bytea, 'admin',
|
phone_verified,
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, 1),
|
created_at,
|
||||||
|
updated_at,
|
||||||
(3, 'Samuel', 'Tariku', 'cybersamt@gmail.com', '0911111111',
|
suspended,
|
||||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
company_id
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
)
|
||||||
|
VALUES (
|
||||||
(4, 'Kirubel', 'Kibru', 'kirubel.jkl679@gmail.com', '0911554486',
|
1,
|
||||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
'John',
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL);
|
'Doe',
|
||||||
|
'john.doe@example.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'customer',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
'Test',
|
||||||
|
'Admin',
|
||||||
|
'test.admin@gmail.com',
|
||||||
|
'0988554466',
|
||||||
|
crypt('password123', gen_salt('bf'))::bytea,
|
||||||
|
'admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
'Samuel',
|
||||||
|
'Tariku',
|
||||||
|
'cybersamt@gmail.com',
|
||||||
|
'0911111111',
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'super_admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
4,
|
||||||
|
'Kirubel',
|
||||||
|
'Kibru',
|
||||||
|
'kirubel.jkl679@gmail.com',
|
||||||
|
'0911554486',
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'super_admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
5,
|
||||||
|
'Test',
|
||||||
|
'Veli',
|
||||||
|
'test.veli@example.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'customer',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
-- Supported Operations
|
-- Supported Operations
|
||||||
INSERT INTO supported_operations (id, name, description) VALUES
|
INSERT INTO supported_operations (id, name, description)
|
||||||
(1, 'SportBook', 'Sportbook operations'),
|
VALUES (1, 'SportBook', 'Sportbook operations'),
|
||||||
(2, 'Virtual', 'Virtual operations');
|
(2, 'Virtual', 'Virtual operations');
|
||||||
|
|
||||||
-- Wallets
|
-- Wallets
|
||||||
INSERT INTO wallets (
|
INSERT INTO wallets (
|
||||||
id, balance, is_withdraw, is_bettable, is_transferable, user_id,
|
id,
|
||||||
type, currency, is_active, created_at, updated_at
|
balance,
|
||||||
) VALUES
|
is_withdraw,
|
||||||
(1, 10000, TRUE, TRUE, TRUE, 1, 'regular', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
is_bettable,
|
||||||
(2, 5000, FALSE, TRUE, TRUE, 1, 'static', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
is_transferable,
|
||||||
(3, 20000, TRUE, TRUE, TRUE, 2, 'company_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
user_id,
|
||||||
(4, 15000, TRUE, TRUE, TRUE, 2, 'branch_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
type,
|
||||||
|
currency,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
10000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1,
|
||||||
|
'regular',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
5000,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1,
|
||||||
|
'static',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
20000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
'company_main',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
4,
|
||||||
|
15000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
'branch_main',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
-- Customer Wallets
|
-- Customer Wallets
|
||||||
INSERT INTO customer_wallets (id, customer_id, regular_wallet_id, static_wallet_id)
|
INSERT INTO customer_wallets (
|
||||||
|
id,
|
||||||
|
customer_id,
|
||||||
|
regular_wallet_id,
|
||||||
|
static_wallet_id
|
||||||
|
)
|
||||||
VALUES (1, 1, 1, 2);
|
VALUES (1, 1, 1, 2);
|
||||||
|
|
||||||
-- Company
|
-- Company
|
||||||
INSERT INTO companies (
|
INSERT INTO companies (
|
||||||
id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
id,
|
||||||
) VALUES
|
name,
|
||||||
(1, 'Test Company', 2, 3, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
slug,
|
||||||
|
admin_id,
|
||||||
|
wallet_id,
|
||||||
|
deducted_percentage,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
'FortuneBets',
|
||||||
|
'fortunebets',
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
0.10,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
-- Branch
|
-- Branch
|
||||||
INSERT INTO branches (
|
INSERT INTO branches (
|
||||||
id, name, location, wallet_id, branch_manager_id, company_id,
|
id,
|
||||||
is_self_owned, profit_percent, is_active, created_at, updated_at
|
name,
|
||||||
) VALUES
|
location,
|
||||||
(1, 'Test Branch', 'addis_ababa', 4, 2, 1, TRUE, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
wallet_id,
|
||||||
|
branch_manager_id,
|
||||||
COMMIT;
|
company_id,
|
||||||
|
is_self_owned,
|
||||||
|
profit_percent,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
'Test Branch',
|
||||||
|
'addis_ababa',
|
||||||
|
4,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
TRUE,
|
||||||
|
0.10,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
COMMIT;
|
||||||
|
|
@ -17,7 +17,9 @@ CREATE TABLE IF NOT EXISTS users (
|
||||||
CHECK (
|
CHECK (
|
||||||
email IS NOT NULL
|
email IS NOT NULL
|
||||||
OR phone_number IS NOT NULL
|
OR phone_number IS NOT NULL
|
||||||
)
|
),
|
||||||
|
UNIQUE(email, company_id),
|
||||||
|
UNIQUE (phone_number, company_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
||||||
|
|
@ -30,10 +32,10 @@ CREATE TABLE IF NOT EXISTS virtual_game_providers (
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMPTZ
|
updated_at TIMESTAMPTZ
|
||||||
);
|
);
|
||||||
|
|
||||||
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,
|
||||||
|
currency VARCHAR(3) NOT NULL DEFAULT 'ETB',
|
||||||
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,
|
||||||
|
|
@ -43,7 +45,6 @@ CREATE TABLE IF NOT EXISTS wallets (
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -53,26 +54,6 @@ CREATE TABLE refresh_tokens (
|
||||||
revoked BOOLEAN DEFAULT FALSE NOT NULL,
|
revoked BOOLEAN DEFAULT FALSE NOT NULL,
|
||||||
CONSTRAINT unique_token UNIQUE (token)
|
CONSTRAINT unique_token UNIQUE (token)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE direct_deposits (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
customer_id BIGINT NOT NULL REFERENCES users(id),
|
|
||||||
wallet_id BIGINT NOT NULL REFERENCES wallets(id),
|
|
||||||
amount NUMERIC(15, 2) NOT NULL,
|
|
||||||
bank_reference TEXT NOT NULL,
|
|
||||||
sender_account TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'rejected')),
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
verified_by BIGINT REFERENCES users(id),
|
|
||||||
verification_notes TEXT,
|
|
||||||
verified_at TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX idx_direct_deposits_status ON direct_deposits(status);
|
|
||||||
CREATE INDEX idx_direct_deposits_customer ON direct_deposits(customer_id);
|
|
||||||
CREATE INDEX idx_direct_deposits_reference ON direct_deposits(bank_reference);
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
CREATE TABLE otps (
|
CREATE TABLE otps (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
|
@ -87,6 +68,7 @@ CREATE TABLE otps (
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS bets (
|
CREATE TABLE IF NOT EXISTS bets (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
amount BIGINT NOT NULL,
|
amount BIGINT NOT NULL,
|
||||||
total_odds REAL NOT NULL,
|
total_odds REAL NOT NULL,
|
||||||
status INT NOT NULL,
|
status INT NOT NULL,
|
||||||
|
|
@ -101,6 +83,7 @@ CREATE TABLE IF NOT EXISTS bets (
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
amount BIGINT NOT NULL,
|
amount BIGINT NOT NULL,
|
||||||
total_odds REAL NOT NULL,
|
total_odds REAL NOT NULL,
|
||||||
IP VARCHAR(255) NOT NULL,
|
IP VARCHAR(255) NOT NULL,
|
||||||
|
|
@ -122,14 +105,14 @@ CREATE TABLE IF NOT EXISTS bet_outcomes (
|
||||||
sport_id BIGINT NOT NULL,
|
sport_id BIGINT NOT NULL,
|
||||||
event_id BIGINT NOT null,
|
event_id BIGINT NOT null,
|
||||||
odd_id BIGINT NOT NULL,
|
odd_id BIGINT NOT NULL,
|
||||||
home_team_name VARCHAR(255) NOT NULL,
|
home_team_name TEXT NOT NULL,
|
||||||
away_team_name VARCHAR(255) NOT NULL,
|
away_team_name TEXT NOT NULL,
|
||||||
market_id BIGINT NOT NULL,
|
market_id BIGINT NOT NULL,
|
||||||
market_name VARCHAR(255) NOT NULL,
|
market_name TEXT NOT NULL,
|
||||||
odd REAL NOT NULL,
|
odd REAL NOT NULL,
|
||||||
odd_name VARCHAR(255) NOT NULL,
|
odd_name TEXT NOT NULL,
|
||||||
odd_header VARCHAR(255) NOT NULL,
|
odd_header TEXT NOT NULL,
|
||||||
odd_handicap VARCHAR(255) NOT NULL,
|
odd_handicap TEXT NOT NULL,
|
||||||
status INT NOT NULL DEFAULT 0,
|
status INT NOT NULL DEFAULT 0,
|
||||||
expires TIMESTAMP NOT NULL
|
expires TIMESTAMP NOT NULL
|
||||||
);
|
);
|
||||||
|
|
@ -138,14 +121,14 @@ CREATE TABLE IF NOT EXISTS ticket_outcomes (
|
||||||
ticket_id BIGINT NOT NULL,
|
ticket_id BIGINT NOT NULL,
|
||||||
event_id BIGINT NOT null,
|
event_id BIGINT NOT null,
|
||||||
odd_id BIGINT NOT NULL,
|
odd_id BIGINT NOT NULL,
|
||||||
home_team_name VARCHAR(255) NOT NULL,
|
home_team_name TEXT NOT NULL,
|
||||||
away_team_name VARCHAR(255) NOT NULL,
|
away_team_name TEXT NOT NULL,
|
||||||
market_id BIGINT NOT NULL,
|
market_id BIGINT NOT NULL,
|
||||||
market_name VARCHAR(255) NOT NULL,
|
market_name TEXT NOT NULL,
|
||||||
odd REAL NOT NULL,
|
odd REAL NOT NULL,
|
||||||
odd_name VARCHAR(255) NOT NULL,
|
odd_name TEXT NOT NULL,
|
||||||
odd_header VARCHAR(255) NOT NULL,
|
odd_header TEXT NOT NULL,
|
||||||
odd_handicap VARCHAR(255) NOT NULL,
|
odd_handicap TEXT NOT NULL,
|
||||||
status INT NOT NULL DEFAULT 0,
|
status INT NOT NULL DEFAULT 0,
|
||||||
expires TIMESTAMP NOT NULL
|
expires TIMESTAMP NOT NULL
|
||||||
);
|
);
|
||||||
|
|
@ -194,7 +177,7 @@ CREATE TABLE IF NOT EXISTS customer_wallets (
|
||||||
CREATE TABLE IF NOT EXISTS wallet_transfer (
|
CREATE TABLE IF NOT EXISTS wallet_transfer (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
amount BIGINT,
|
amount BIGINT,
|
||||||
message VARCHAR(255) NOT NULL,
|
message TEXT NOT NULL,
|
||||||
type VARCHAR(255),
|
type VARCHAR(255),
|
||||||
receiver_wallet_id BIGINT,
|
receiver_wallet_id BIGINT,
|
||||||
sender_wallet_id BIGINT,
|
sender_wallet_id BIGINT,
|
||||||
|
|
@ -288,54 +271,115 @@ CREATE TABLE IF NOT EXISTS branch_locations (
|
||||||
);
|
);
|
||||||
CREATE TABLE events (
|
CREATE TABLE events (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
sport_id INT,
|
sport_id INT NOT NULL,
|
||||||
match_name TEXT,
|
match_name TEXT NOT NULL,
|
||||||
home_team TEXT,
|
home_team TEXT NOT NULL,
|
||||||
away_team TEXT,
|
away_team TEXT NOT NULL,
|
||||||
home_team_id INT,
|
home_team_id BIGINT NOT NULL,
|
||||||
away_team_id INT,
|
away_team_id BIGINT NOT NULL,
|
||||||
home_kit_image TEXT,
|
home_kit_image TEXT NOT NULL,
|
||||||
away_kit_image TEXT,
|
away_kit_image TEXT NOT NULL,
|
||||||
league_id INT,
|
league_id BIGINT NOT NULL,
|
||||||
league_name TEXT,
|
league_name TEXT NOT NULL,
|
||||||
league_cc TEXT,
|
start_time TIMESTAMP NOT NULL,
|
||||||
start_time TIMESTAMP,
|
|
||||||
score TEXT,
|
score TEXT,
|
||||||
match_minute INT,
|
match_minute INT,
|
||||||
timer_status TEXT,
|
timer_status TEXT,
|
||||||
added_time INT,
|
added_time INT,
|
||||||
match_period INT,
|
match_period INT,
|
||||||
is_live BOOLEAN,
|
is_live BOOLEAN NOT NULL DEFAULT false,
|
||||||
status TEXT,
|
status TEXT NOT NULL,
|
||||||
fetched_at TIMESTAMP DEFAULT now(),
|
fetched_at TIMESTAMP DEFAULT now(),
|
||||||
source TEXT DEFAULT 'b365api',
|
source TEXT NOT NULL DEFAULT 'b365api' CHECK (
|
||||||
is_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
source IN (
|
||||||
is_active BOOLEAN NOT NULL DEFAULT TRUE
|
'b365api',
|
||||||
|
'bfair',
|
||||||
|
'1xbet',
|
||||||
|
'bwin',
|
||||||
|
'enetpulse'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
default_is_featured BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
default_winning_upper_limit INT NOT NULL,
|
||||||
|
is_monitored BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
UNIQUE(id, source)
|
||||||
);
|
);
|
||||||
CREATE TABLE odds (
|
CREATE TABLE event_history (
|
||||||
id SERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
event_id TEXT,
|
event_id TEXT NOT NULL,
|
||||||
fi TEXT,
|
status TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE TABLE company_event_settings (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
|
event_id TEXT NOT NULL,
|
||||||
|
is_active BOOLEAN,
|
||||||
|
is_featured BOOLEAN,
|
||||||
|
winning_upper_limit INT,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(company_id, event_id)
|
||||||
|
);
|
||||||
|
CREATE TABLE odds_market (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
event_id TEXT NOT NULL,
|
||||||
market_type TEXT NOT NULL,
|
market_type TEXT NOT NULL,
|
||||||
market_name TEXT,
|
market_name TEXT NOT NULL,
|
||||||
market_category TEXT,
|
market_category TEXT NOT NULL,
|
||||||
market_id TEXT,
|
market_id TEXT NOT NULL,
|
||||||
name TEXT,
|
raw_odds JSONB NOT NULL,
|
||||||
handicap TEXT,
|
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
odds_value DOUBLE PRECISION,
|
|
||||||
section TEXT NOT NULL,
|
|
||||||
category TEXT,
|
|
||||||
raw_odds JSONB,
|
|
||||||
fetched_at TIMESTAMP DEFAULT now(),
|
fetched_at TIMESTAMP DEFAULT now(),
|
||||||
source TEXT DEFAULT 'b365api',
|
expires_at TIMESTAMP NOT NULL,
|
||||||
is_active BOOLEAN DEFAULT true,
|
|
||||||
UNIQUE (market_id, name, handicap),
|
|
||||||
UNIQUE (event_id, market_id, name, handicap),
|
|
||||||
UNIQUE (event_id, market_id)
|
UNIQUE (event_id, market_id)
|
||||||
);
|
);
|
||||||
|
CREATE TABLE odd_history (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
odds_market_id BIGINT NOT NULL REFERENCES odds_market(id),
|
||||||
|
raw_odd_id BIGINT NOT NULL,
|
||||||
|
market_id TEXT NOT NULL,
|
||||||
|
event_id TEXT NOT NULL,
|
||||||
|
odd_value DOUBLE PRECISION NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE TABLE disabled_odd (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
|
odds_market_id BIGINT NOT NULL,
|
||||||
|
raw_odd_id BIGINT NOT NULL,
|
||||||
|
event_id TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE TABLE company_odd_settings (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
|
odds_market_id BIGINT NOT NULL,
|
||||||
|
is_active BOOLEAN,
|
||||||
|
custom_raw_odds JSONB,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(company_id, odds_market_id)
|
||||||
|
);
|
||||||
|
CREATE TABLE result_log (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
status_not_finished_count INT NOT NULL,
|
||||||
|
status_not_finished_bets INT NOT NULL,
|
||||||
|
status_to_be_fixed_count INT NOT NULL,
|
||||||
|
status_to_be_fixed_bets INT NOT NULL,
|
||||||
|
status_postponed_count INT NOT NULL,
|
||||||
|
status_postponed_bets INT NOT NULL,
|
||||||
|
status_ended_count INT NOT NULL,
|
||||||
|
status_ended_bets INT NOT NULL,
|
||||||
|
status_removed_count INT NOT NULL,
|
||||||
|
status_removed_bets INT NOT NULL,
|
||||||
|
removed_count INT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
CREATE TABLE companies (
|
CREATE TABLE companies (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
slug TEXT UNIQUE NOT NULL,
|
||||||
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,
|
||||||
|
|
@ -350,35 +394,53 @@ CREATE TABLE companies (
|
||||||
CREATE TABLE leagues (
|
CREATE TABLE leagues (
|
||||||
id BIGINT PRIMARY KEY,
|
id BIGINT PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
img TEXT,
|
img_url TEXT,
|
||||||
country_code TEXT,
|
country_code TEXT,
|
||||||
bet365_id INT,
|
bet365_id INT,
|
||||||
sport_id INT NOT NULL,
|
sport_id INT NOT NULL,
|
||||||
is_active BOOLEAN DEFAULT true,
|
default_is_active BOOLEAN NOT NULL DEFAULT true,
|
||||||
is_featured BOOLEAN DEFAULT false
|
default_is_featured BOOLEAN NOT NULL DEFAULT false
|
||||||
|
);
|
||||||
|
CREATE TABLE company_league_settings (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
|
league_id BIGINT NOT NULL,
|
||||||
|
is_active BOOLEAN,
|
||||||
|
is_featured BOOLEAN,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(league_id, company_id)
|
||||||
);
|
);
|
||||||
CREATE TABLE teams (
|
CREATE TABLE teams (
|
||||||
id TEXT PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
team_name TEXT NOT NULL,
|
team_name TEXT NOT NULL,
|
||||||
country TEXT,
|
country_code TEXT NOT NULL,
|
||||||
bet365_id INT,
|
bet365_id BIGINT,
|
||||||
logo_url TEXT
|
img_url TEXT
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS settings (
|
CREATE TABLE IF NOT EXISTS global_settings (
|
||||||
key TEXT PRIMARY KEY,
|
key TEXT PRIMARY KEY,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
-- Tenant/Company-specific overrides
|
||||||
|
CREATE TABLE IF NOT EXISTS company_settings (
|
||||||
|
company_id BIGINT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||||
|
key TEXT NOT NULL,
|
||||||
|
value TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (company_id, key)
|
||||||
|
);
|
||||||
CREATE TABLE bonus (
|
CREATE TABLE bonus (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
multiplier REAL NOT NULL,
|
multiplier REAL NOT NULL,
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
balance_cap BIGINT NOT NULL DEFAULT 0
|
balance_cap BIGINT NOT NULL DEFAULT 0
|
||||||
);
|
);
|
||||||
CREATE TABLE flags (
|
CREATE TABLE flags (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
bet_id BIGINT REFERENCES bets(id) ON DELETE CASCADE,
|
bet_id BIGINT REFERENCES bets(id) ON DELETE CASCADE,
|
||||||
odd_id BIGINT REFERENCES odds(id),
|
odds_market_id BIGINT REFERENCES odds_market(id),
|
||||||
reason TEXT,
|
reason TEXT,
|
||||||
flagged_at TIMESTAMP DEFAULT NOW(),
|
flagged_at TIMESTAMP DEFAULT NOW(),
|
||||||
resolved BOOLEAN DEFAULT FALSE,
|
resolved BOOLEAN DEFAULT FALSE,
|
||||||
|
|
@ -386,14 +448,30 @@ CREATE TABLE flags (
|
||||||
CHECK (
|
CHECK (
|
||||||
(
|
(
|
||||||
bet_id IS NOT NULL
|
bet_id IS NOT NULL
|
||||||
AND odd_id IS NULL
|
AND odds_market_id IS NULL
|
||||||
)
|
)
|
||||||
OR (
|
OR (
|
||||||
bet_id IS NULL
|
bet_id IS NULL
|
||||||
AND odd_id IS NOT NULL
|
AND odds_market_id IS NOT NULL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
CREATE TABLE direct_deposits (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
customer_id BIGINT NOT NULL REFERENCES users(id),
|
||||||
|
wallet_id BIGINT NOT NULL REFERENCES wallets(id),
|
||||||
|
amount NUMERIC(15, 2) NOT NULL,
|
||||||
|
bank_reference TEXT NOT NULL,
|
||||||
|
sender_account TEXT NOT NULL,
|
||||||
|
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'rejected')),
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
|
verified_by BIGINT REFERENCES users(id),
|
||||||
|
verification_notes TEXT,
|
||||||
|
verified_at TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_direct_deposits_status ON direct_deposits(status);
|
||||||
|
CREATE INDEX idx_direct_deposits_customer ON direct_deposits(customer_id);
|
||||||
|
CREATE INDEX idx_direct_deposits_reference ON direct_deposits(bank_reference);
|
||||||
-- Views
|
-- Views
|
||||||
CREATE VIEW companies_details AS
|
CREATE VIEW companies_details AS
|
||||||
SELECT companies.*,
|
SELECT companies.*,
|
||||||
|
|
@ -512,17 +590,64 @@ SELECT sd.*,
|
||||||
st.verified AS transaction_verified
|
st.verified AS transaction_verified
|
||||||
FROM shop_deposits AS sd
|
FROM shop_deposits AS sd
|
||||||
JOIN shop_transactions st ON st.id = sd.shop_transaction_id;
|
JOIN shop_transactions st ON st.id = sd.shop_transaction_id;
|
||||||
|
CREATE VIEW league_with_settings AS
|
||||||
|
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
|
||||||
|
JOIN company_league_settings cls ON l.id = cls.league_id;
|
||||||
|
CREATE VIEW event_with_settings AS
|
||||||
|
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
|
||||||
|
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.*,
|
||||||
|
leagues.country_code as league_cc
|
||||||
|
FROM events
|
||||||
|
LEFT JOIN leagues ON leagues.id = events.league_id;
|
||||||
|
CREATE VIEW odds_market_with_settings AS
|
||||||
|
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
|
||||||
|
JOIN company_odd_settings cos ON o.id = cos.odds_market_id;
|
||||||
|
CREATE VIEW odds_market_with_event AS
|
||||||
|
SELECT o.*,
|
||||||
|
e.is_monitored,
|
||||||
|
e.is_live,
|
||||||
|
e.status,
|
||||||
|
e.source
|
||||||
|
FROM odds_market o
|
||||||
|
JOIN events e ON o.event_id = e.id;
|
||||||
-- Foreign Keys
|
-- Foreign Keys
|
||||||
ALTER TABLE users
|
|
||||||
ADD CONSTRAINT unique_email UNIQUE (email),
|
|
||||||
ADD CONSTRAINT unique_phone_number UNIQUE (phone_number);
|
|
||||||
ALTER TABLE refresh_tokens
|
ALTER TABLE refresh_tokens
|
||||||
ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id);
|
ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id);
|
||||||
ALTER TABLE bets
|
ALTER TABLE bets
|
||||||
ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id);
|
ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id);
|
||||||
ALTER TABLE wallets
|
ALTER TABLE wallets
|
||||||
ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id),
|
ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id);
|
||||||
ADD COLUMN currency VARCHAR(3) NOT NULL DEFAULT 'ETB';
|
|
||||||
ALTER TABLE customer_wallets
|
ALTER TABLE customer_wallets
|
||||||
ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id),
|
ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id),
|
||||||
ADD CONSTRAINT fk_customer_wallets_regular_wallet FOREIGN KEY (regular_wallet_id) REFERENCES wallets(id),
|
ADD CONSTRAINT fk_customer_wallets_regular_wallet FOREIGN KEY (regular_wallet_id) REFERENCES wallets(id),
|
||||||
|
|
@ -552,4 +677,13 @@ ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(i
|
||||||
ADD CONSTRAINT fk_branch_cashiers_branches FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE;
|
ADD CONSTRAINT fk_branch_cashiers_branches FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE;
|
||||||
ALTER TABLE companies
|
ALTER TABLE companies
|
||||||
ADD CONSTRAINT fk_companies_admin FOREIGN KEY (admin_id) REFERENCES users(id),
|
ADD CONSTRAINT fk_companies_admin FOREIGN KEY (admin_id) REFERENCES users(id),
|
||||||
ADD CONSTRAINT fk_companies_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE;
|
ADD CONSTRAINT fk_companies_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE company_league_settings
|
||||||
|
ADD CONSTRAINT fk_league_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||||
|
ADD CONSTRAINT fk_league_settings_league FOREIGN KEY (league_id) REFERENCES leagues(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE company_event_settings
|
||||||
|
ADD CONSTRAINT fk_event_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||||
|
ADD CONSTRAINT fk_event_settings_event FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE company_odd_settings
|
||||||
|
ADD CONSTRAINT fk_odds_settings_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||||
|
ADD CONSTRAINT fk_odds_settings_odds_market FOREIGN KEY (odds_market_id) REFERENCES odds_market(id) ON DELETE CASCADE;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
-- Settings Initial Data
|
-- Settings Initial Data
|
||||||
INSERT INTO settings (key, value)
|
INSERT INTO global_settings (key, value)
|
||||||
VALUES ('sms_provider', '30'),
|
VALUES ('sms_provider', 'afro_message'),
|
||||||
('max_number_of_outcomes', '30'),
|
('max_number_of_outcomes', '30'),
|
||||||
('bet_amount_limit', '10000000'),
|
('bet_amount_limit', '10000000'),
|
||||||
('daily_ticket_limit', '50'),
|
('daily_ticket_limit', '50'),
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,218 @@
|
||||||
|
|
||||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
|
|
||||||
-- Users
|
-- Users
|
||||||
INSERT INTO users (
|
INSERT INTO users (
|
||||||
id, first_name, last_name, email, phone_number, password, role,
|
id,
|
||||||
email_verified, phone_verified, created_at, updated_at, suspended, company_id
|
first_name,
|
||||||
) VALUES
|
last_name,
|
||||||
(1, 'John', 'Doe', 'john.doe@example.com', NULL,
|
email,
|
||||||
crypt('password123', gen_salt('bf'))::bytea, 'customer',
|
phone_number,
|
||||||
TRUE, FALSE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
password,
|
||||||
|
role,
|
||||||
(2, 'Test', 'Admin', 'test.admin@gmail.com', '0988554466',
|
email_verified,
|
||||||
crypt('password123', gen_salt('bf'))::bytea, 'admin',
|
phone_verified,
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, 1),
|
created_at,
|
||||||
|
updated_at,
|
||||||
(3, 'Samuel', 'Tariku', 'cybersamt@gmail.com', '0911111111',
|
suspended,
|
||||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
company_id
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL),
|
)
|
||||||
|
VALUES (
|
||||||
(4, 'Kirubel', 'Kibru', 'kirubel.jkl679@gmail.com', '0911554486',
|
1,
|
||||||
crypt('password@123', gen_salt('bf'))::bytea, 'super_admin',
|
'John',
|
||||||
TRUE, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, FALSE, NULL);
|
'Doe',
|
||||||
|
'john.doe@example.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password123', gen_salt('bf'))::bytea,
|
||||||
|
'customer',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
'Test',
|
||||||
|
'Admin',
|
||||||
|
'test.admin@gmail.com',
|
||||||
|
'0988554466',
|
||||||
|
crypt('password123', gen_salt('bf'))::bytea,
|
||||||
|
'admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
'Samuel',
|
||||||
|
'Tariku',
|
||||||
|
'cybersamt@gmail.com',
|
||||||
|
'0911111111',
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'super_admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
4,
|
||||||
|
'Kirubel',
|
||||||
|
'Kibru',
|
||||||
|
'kirubel.jkl679@gmail.com',
|
||||||
|
'0911554486',
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'super_admin',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
),
|
||||||
|
(
|
||||||
|
5,
|
||||||
|
'Test',
|
||||||
|
'Veli',
|
||||||
|
'test.veli@example.com',
|
||||||
|
NULL,
|
||||||
|
crypt('password@123', gen_salt('bf'))::bytea,
|
||||||
|
'customer',
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
-- Supported Operations
|
-- Supported Operations
|
||||||
INSERT INTO supported_operations (id, name, description) VALUES
|
INSERT INTO supported_operations (id, name, description)
|
||||||
(1, 'SportBook', 'Sportbook operations'),
|
VALUES (1, 'SportBook', 'Sportbook operations'),
|
||||||
(2, 'Virtual', 'Virtual operations');
|
(2, 'Virtual', 'Virtual operations');
|
||||||
|
|
||||||
-- Wallets
|
-- Wallets
|
||||||
INSERT INTO wallets (
|
INSERT INTO wallets (
|
||||||
id, balance, is_withdraw, is_bettable, is_transferable, user_id,
|
id,
|
||||||
type, currency, is_active, created_at, updated_at
|
balance,
|
||||||
) VALUES
|
is_withdraw,
|
||||||
(1, 10000, TRUE, TRUE, TRUE, 1, 'regular', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
is_bettable,
|
||||||
(2, 5000, FALSE, TRUE, TRUE, 1, 'static', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
is_transferable,
|
||||||
(3, 20000, TRUE, TRUE, TRUE, 2, 'company_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
user_id,
|
||||||
(4, 15000, TRUE, TRUE, TRUE, 2, 'branch_main', 'ETB', TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
type,
|
||||||
|
currency,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
10000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1,
|
||||||
|
'regular',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
5000,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1,
|
||||||
|
'static',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
20000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
'company_main',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
),
|
||||||
|
(
|
||||||
|
4,
|
||||||
|
15000,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
'branch_main',
|
||||||
|
'ETB',
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
-- Customer Wallets
|
-- Customer Wallets
|
||||||
INSERT INTO customer_wallets (id, customer_id, regular_wallet_id, static_wallet_id)
|
INSERT INTO customer_wallets (
|
||||||
|
id,
|
||||||
|
customer_id,
|
||||||
|
regular_wallet_id,
|
||||||
|
static_wallet_id
|
||||||
|
)
|
||||||
VALUES (1, 1, 1, 2);
|
VALUES (1, 1, 1, 2);
|
||||||
|
|
||||||
-- Company
|
-- Company
|
||||||
INSERT INTO companies (
|
INSERT INTO companies (
|
||||||
id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at
|
id,
|
||||||
) VALUES
|
name,
|
||||||
(1, 'Test Company', 2, 3, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
admin_id,
|
||||||
|
wallet_id,
|
||||||
|
deducted_percentage,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
'Test Company',
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
0.10,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
-- Branch
|
-- Branch
|
||||||
INSERT INTO branches (
|
INSERT INTO branches (
|
||||||
id, name, location, wallet_id, branch_manager_id, company_id,
|
id,
|
||||||
is_self_owned, profit_percent, is_active, created_at, updated_at
|
name,
|
||||||
) VALUES
|
location,
|
||||||
(1, 'Test Branch', 'addis_ababa', 4, 2, 1, TRUE, 0.10, TRUE, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
wallet_id,
|
||||||
|
branch_manager_id,
|
||||||
|
company_id,
|
||||||
|
is_self_owned,
|
||||||
|
profit_percent,
|
||||||
|
is_active,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
1,
|
||||||
|
'Test Branch',
|
||||||
|
'addis_ababa',
|
||||||
|
4,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
TRUE,
|
||||||
|
0.10,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
-- name: GetUserByEmailPhone :one
|
-- name: GetUserByEmailPhone :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM users
|
FROM users
|
||||||
WHERE email = $1
|
WHERE (
|
||||||
OR phone_number = $2;
|
email = $1
|
||||||
|
OR phone_number = $2
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
);
|
||||||
-- name: CreateRefreshToken :exec
|
-- name: CreateRefreshToken :exec
|
||||||
INSERT INTO refresh_tokens (user_id, token, expires_at, created_at, revoked)
|
INSERT INTO refresh_tokens (user_id, token, expires_at, created_at, revoked)
|
||||||
VALUES ($1, $2, $3, $4, $5);
|
VALUES ($1, $2, $3, $4, $5);
|
||||||
|
|
||||||
-- name: GetRefreshToken :one
|
-- name: GetRefreshToken :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM refresh_tokens
|
FROM refresh_tokens
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,10 @@ INSERT INTO bets (
|
||||||
user_id,
|
user_id,
|
||||||
is_shop_bet,
|
is_shop_bet,
|
||||||
outcomes_hash,
|
outcomes_hash,
|
||||||
fast_code
|
fast_code,
|
||||||
|
company_id
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: CreateBetOutcome :copyfrom
|
-- name: CreateBetOutcome :copyfrom
|
||||||
INSERT INTO bet_outcomes (
|
INSERT INTO bet_outcomes (
|
||||||
|
|
@ -52,6 +53,10 @@ wHERE (
|
||||||
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
|
||||||
)
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
AND (
|
AND (
|
||||||
cashed_out = sqlc.narg('cashed_out')
|
cashed_out = sqlc.narg('cashed_out')
|
||||||
OR sqlc.narg('cashed_out') IS NULL
|
OR sqlc.narg('cashed_out') IS NULL
|
||||||
|
|
@ -148,4 +153,4 @@ DELETE FROM bets
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
-- name: DeleteBetOutcome :exec
|
-- name: DeleteBetOutcome :exec
|
||||||
DELETE FROM bet_outcomes
|
DELETE FROM bet_outcomes
|
||||||
WHERE bet_id = $1;
|
WHERE bet_id = $1;
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
-- name: CreateCompany :one
|
-- name: CreateCompany :one
|
||||||
INSERT INTO companies (
|
INSERT INTO companies (
|
||||||
name,
|
name,
|
||||||
|
slug,
|
||||||
admin_id,
|
admin_id,
|
||||||
wallet_id,
|
wallet_id,
|
||||||
deducted_percentage
|
deducted_percentage
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: GetAllCompanies :many
|
-- name: GetAllCompanies :many
|
||||||
SELECT *
|
SELECT *
|
||||||
|
|
@ -29,6 +30,10 @@ WHERE (
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
-- name: GetCompanyIDUsingSlug :one
|
||||||
|
SELECT id
|
||||||
|
FROM companies
|
||||||
|
WHERE slug = $1;
|
||||||
-- name: SearchCompanyByName :many
|
-- name: SearchCompanyByName :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
|
|
|
||||||
35
db/query/custom_odds.sql
Normal file
35
db/query/custom_odds.sql
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
-- -- name: InsertCustomOddsMarket :one
|
||||||
|
-- INSERT INTO custom_odds_market (
|
||||||
|
-- odds_market_id,
|
||||||
|
-- company_id,
|
||||||
|
-- event_id,
|
||||||
|
-- raw_odds
|
||||||
|
-- )
|
||||||
|
-- VALUES ($1, $2, $3, $4)
|
||||||
|
-- RETURNING *;
|
||||||
|
-- -- name: GetAllCustomOdds :many
|
||||||
|
-- SELECT *
|
||||||
|
-- FROM custom_odds_market
|
||||||
|
-- WHERE (
|
||||||
|
-- company_id = sqlc.narg('company_id')
|
||||||
|
-- OR sqlc.narg('company_id') IS NULL
|
||||||
|
-- );
|
||||||
|
-- -- name: GetCustomOddByID :one
|
||||||
|
-- SELECT *
|
||||||
|
-- FROM custom_odds_market
|
||||||
|
-- WHERE id = $1;
|
||||||
|
-- -- name: GetCustomOddByOddID :one
|
||||||
|
-- SELECT *
|
||||||
|
-- FROM custom_odds_market
|
||||||
|
-- WHERE odds_market_id = $1
|
||||||
|
-- AND company_id = $2;
|
||||||
|
-- -- name: DeleteCustomOddsByID :exec
|
||||||
|
-- DELETE FROM custom_odds_market
|
||||||
|
-- WHERE id = $1;
|
||||||
|
-- -- name: DeleteCustomOddsByOddID :exec
|
||||||
|
-- DELETE FROM custom_odds_market
|
||||||
|
-- WHERE odds_market_id = $1
|
||||||
|
-- AND company_id = $2;
|
||||||
|
-- -- name: DeleteCustomOddByEventID :exec
|
||||||
|
-- DELETE FROM custom_odds_market
|
||||||
|
-- WHERE event_id = $1;
|
||||||
26
db/query/disabled_odds.sql
Normal file
26
db/query/disabled_odds.sql
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
-- name: InsertDisabledOdds :one
|
||||||
|
INSERT INTO disabled_odd (
|
||||||
|
odds_market_id,
|
||||||
|
company_id,
|
||||||
|
event_id,
|
||||||
|
raw_odd_id
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllDisabledOdds :many
|
||||||
|
SELECT *
|
||||||
|
FROM disabled_odd;
|
||||||
|
-- name: GetDisabledOddByRawOddID :one
|
||||||
|
SELECT *
|
||||||
|
FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1;
|
||||||
|
-- name: GetDisabledOddByID :one
|
||||||
|
SELECT *
|
||||||
|
FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1;
|
||||||
|
-- name: DeleteDisabledOddsByID :exec
|
||||||
|
DELETE FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1;
|
||||||
|
-- name: DeleteDisabledOddsByRawOddID :exec
|
||||||
|
DELETE FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1;
|
||||||
36
db/query/event_history.sql
Normal file
36
db/query/event_history.sql
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
-- name: InsertEventHistory :one
|
||||||
|
INSERT INTO event_history (event_id, status)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllEventHistory :many
|
||||||
|
SELECT *
|
||||||
|
FROM event_history
|
||||||
|
WHERE (
|
||||||
|
event_id = sqlc.narg('event_id')
|
||||||
|
OR sqlc.narg('event_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetInitialEventPerDay :many
|
||||||
|
SELECT DISTINCT ON (DATE_TRUNC('day', created_at)) *
|
||||||
|
FROM event_history
|
||||||
|
WHERE (
|
||||||
|
event_id = sqlc.narg('event_id')
|
||||||
|
OR sqlc.narg('event_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY DATE_TRUNC('day', created_at),
|
||||||
|
created_at ASC;
|
||||||
|
|
@ -11,13 +11,7 @@ INSERT INTO events (
|
||||||
away_kit_image,
|
away_kit_image,
|
||||||
league_id,
|
league_id,
|
||||||
league_name,
|
league_name,
|
||||||
league_cc,
|
|
||||||
start_time,
|
start_time,
|
||||||
score,
|
|
||||||
match_minute,
|
|
||||||
timer_status,
|
|
||||||
added_time,
|
|
||||||
match_period,
|
|
||||||
is_live,
|
is_live,
|
||||||
status,
|
status,
|
||||||
source
|
source
|
||||||
|
|
@ -37,13 +31,7 @@ VALUES (
|
||||||
$12,
|
$12,
|
||||||
$13,
|
$13,
|
||||||
$14,
|
$14,
|
||||||
$15,
|
$15
|
||||||
$16,
|
|
||||||
$17,
|
|
||||||
$18,
|
|
||||||
$19,
|
|
||||||
$20,
|
|
||||||
$21
|
|
||||||
) ON CONFLICT (id) DO
|
) ON CONFLICT (id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET sport_id = EXCLUDED.sport_id,
|
SET sport_id = EXCLUDED.sport_id,
|
||||||
|
|
@ -64,79 +52,35 @@ SET sport_id = EXCLUDED.sport_id,
|
||||||
added_time = EXCLUDED.added_time,
|
added_time = EXCLUDED.added_time,
|
||||||
match_period = EXCLUDED.match_period,
|
match_period = EXCLUDED.match_period,
|
||||||
is_live = EXCLUDED.is_live,
|
is_live = EXCLUDED.is_live,
|
||||||
status = EXCLUDED.status,
|
|
||||||
source = EXCLUDED.source,
|
source = EXCLUDED.source,
|
||||||
fetched_at = now();
|
fetched_at = now();
|
||||||
-- name: InsertUpcomingEvent :exec
|
-- name: InsertEventSettings :exec
|
||||||
INSERT INTO events (
|
INSERT INTO company_event_settings (
|
||||||
id,
|
company_id,
|
||||||
sport_id,
|
event_id,
|
||||||
match_name,
|
is_active,
|
||||||
home_team,
|
is_featured,
|
||||||
away_team,
|
winning_upper_limit
|
||||||
home_team_id,
|
|
||||||
away_team_id,
|
|
||||||
home_kit_image,
|
|
||||||
away_kit_image,
|
|
||||||
league_id,
|
|
||||||
league_name,
|
|
||||||
league_cc,
|
|
||||||
start_time,
|
|
||||||
is_live,
|
|
||||||
status,
|
|
||||||
source
|
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES ($1, $2, $3, $4, $5) ON CONFLICT(company_id, event_id) DO
|
||||||
$1,
|
|
||||||
$2,
|
|
||||||
$3,
|
|
||||||
$4,
|
|
||||||
$5,
|
|
||||||
$6,
|
|
||||||
$7,
|
|
||||||
$8,
|
|
||||||
$9,
|
|
||||||
$10,
|
|
||||||
$11,
|
|
||||||
$12,
|
|
||||||
$13,
|
|
||||||
false,
|
|
||||||
'upcoming',
|
|
||||||
$14
|
|
||||||
) ON CONFLICT (id) DO
|
|
||||||
UPDATE
|
UPDATE
|
||||||
SET sport_id = EXCLUDED.sport_id,
|
SET is_active = EXCLUDED.is_active,
|
||||||
match_name = EXCLUDED.match_name,
|
is_featured = EXCLUDED.is_featured,
|
||||||
home_team = EXCLUDED.home_team,
|
winning_upper_limit = EXCLUDED.winning_upper_limit;
|
||||||
away_team = EXCLUDED.away_team,
|
|
||||||
home_team_id = EXCLUDED.home_team_id,
|
|
||||||
away_team_id = EXCLUDED.away_team_id,
|
|
||||||
home_kit_image = EXCLUDED.home_kit_image,
|
|
||||||
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,
|
|
||||||
is_live = false,
|
|
||||||
status = 'upcoming',
|
|
||||||
source = EXCLUDED.source,
|
|
||||||
fetched_at = now();
|
|
||||||
-- name: ListLiveEvents :many
|
-- name: ListLiveEvents :many
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM events
|
FROM event_with_country
|
||||||
WHERE is_live = true;
|
WHERE is_live = true;
|
||||||
-- name: GetAllUpcomingEvents :many
|
-- name: GetAllUpcomingEvents :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM events
|
FROM event_with_country
|
||||||
WHERE start_time > now()
|
WHERE start_time > now()
|
||||||
AND is_live = false
|
AND is_live = false
|
||||||
AND status = 'upcoming'
|
AND status = 'upcoming'
|
||||||
ORDER BY start_time ASC;
|
ORDER BY start_time ASC;
|
||||||
-- name: GetExpiredUpcomingEvents :many
|
-- name: GetExpiredEvents :many
|
||||||
SELECT events.*,
|
SELECT *
|
||||||
leagues.country_code as league_cc
|
FROM event_with_country
|
||||||
FROM events
|
|
||||||
LEFT JOIN leagues ON leagues.id = league_id
|
|
||||||
WHERE start_time < now()
|
WHERE start_time < now()
|
||||||
and (
|
and (
|
||||||
status = sqlc.narg('status')
|
status = sqlc.narg('status')
|
||||||
|
|
@ -145,8 +89,7 @@ WHERE start_time < now()
|
||||||
ORDER BY start_time ASC;
|
ORDER BY start_time ASC;
|
||||||
-- name: GetTotalEvents :one
|
-- name: GetTotalEvents :one
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM events
|
FROM event_with_country
|
||||||
LEFT JOIN leagues ON leagues.id = league_id
|
|
||||||
WHERE is_live = false
|
WHERE is_live = false
|
||||||
AND status = 'upcoming'
|
AND status = 'upcoming'
|
||||||
AND (
|
AND (
|
||||||
|
|
@ -154,7 +97,7 @@ WHERE is_live = false
|
||||||
OR sqlc.narg('league_id') IS NULL
|
OR sqlc.narg('league_id') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
events.sport_id = sqlc.narg('sport_id')
|
sport_id = sqlc.narg('sport_id')
|
||||||
OR sqlc.narg('sport_id') IS NULL
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
|
|
@ -171,18 +114,12 @@ WHERE is_live = false
|
||||||
OR sqlc.narg('first_start_time') IS NULL
|
OR sqlc.narg('first_start_time') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
leagues.country_code = sqlc.narg('country_code')
|
league_cc = sqlc.narg('country_code')
|
||||||
OR sqlc.narg('country_code') IS NULL
|
OR sqlc.narg('country_code') IS NULL
|
||||||
)
|
|
||||||
AND (
|
|
||||||
events.is_featured = sqlc.narg('is_featured')
|
|
||||||
OR sqlc.narg('is_featured') IS NULL
|
|
||||||
);
|
);
|
||||||
-- name: GetPaginatedUpcomingEvents :many
|
-- name: GetPaginatedUpcomingEvents :many
|
||||||
SELECT events.*,
|
SELECT *
|
||||||
leagues.country_code as league_cc
|
FROM event_with_country
|
||||||
FROM events
|
|
||||||
LEFT JOIN leagues ON leagues.id = league_id
|
|
||||||
WHERE start_time > now()
|
WHERE start_time > now()
|
||||||
AND is_live = false
|
AND is_live = false
|
||||||
AND status = 'upcoming'
|
AND status = 'upcoming'
|
||||||
|
|
@ -191,7 +128,7 @@ WHERE start_time > now()
|
||||||
OR sqlc.narg('league_id') IS NULL
|
OR sqlc.narg('league_id') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
events.sport_id = sqlc.narg('sport_id')
|
sport_id = sqlc.narg('sport_id')
|
||||||
OR sqlc.narg('sport_id') IS NULL
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
|
|
@ -208,31 +145,117 @@ WHERE start_time > now()
|
||||||
OR sqlc.narg('first_start_time') IS NULL
|
OR sqlc.narg('first_start_time') IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
leagues.country_code = sqlc.narg('country_code')
|
league_cc = sqlc.narg('country_code')
|
||||||
OR sqlc.narg('country_code') IS NULL
|
OR sqlc.narg('country_code') IS NULL
|
||||||
)
|
)
|
||||||
|
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
|
||||||
|
AND status = 'upcoming'
|
||||||
AND (
|
AND (
|
||||||
events.is_featured = sqlc.narg('is_featured')
|
league_id = sqlc.narg('league_id')
|
||||||
OR sqlc.narg('is_featured') IS NULL
|
OR sqlc.narg('league_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
sport_id = sqlc.narg('sport_id')
|
||||||
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
match_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR league_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
start_time < sqlc.narg('last_start_time')
|
||||||
|
OR sqlc.narg('last_start_time') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
start_time > sqlc.narg('first_start_time')
|
||||||
|
OR sqlc.narg('first_start_time') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
league_cc = sqlc.narg('country_code')
|
||||||
|
OR sqlc.narg('country_code') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetEventsWithSettings :many
|
||||||
|
SELECT *
|
||||||
|
FROM event_with_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
AND start_time > now()
|
||||||
|
AND 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')
|
||||||
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
match_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR league_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
start_time < sqlc.narg('last_start_time')
|
||||||
|
OR sqlc.narg('last_start_time') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
start_time > sqlc.narg('first_start_time')
|
||||||
|
OR sqlc.narg('first_start_time') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
league_cc = sqlc.narg('country_code')
|
||||||
|
OR sqlc.narg('country_code') IS NULL
|
||||||
)
|
)
|
||||||
ORDER BY start_time ASC
|
ORDER BY start_time ASC
|
||||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
-- name: GetUpcomingByID :one
|
-- name: GetUpcomingByID :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM events
|
FROM event_with_country
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
AND is_live = false
|
AND is_live = false
|
||||||
AND status = 'upcoming'
|
AND status = 'upcoming'
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
-- name: GetEventWithSettingByID :one
|
||||||
|
SELECT *
|
||||||
|
FROM event_with_settings
|
||||||
|
WHERE id = $1
|
||||||
|
AND company_id = $2
|
||||||
|
AND is_live = false
|
||||||
|
AND status = 'upcoming'
|
||||||
|
LIMIT 1;
|
||||||
-- name: UpdateMatchResult :exec
|
-- name: UpdateMatchResult :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
SET score = $1,
|
SET score = $1,
|
||||||
status = $2
|
status = $2
|
||||||
WHERE id = $3;
|
WHERE id = $3;
|
||||||
-- name: UpdateFeatured :exec
|
-- name: IsEventMonitored :one
|
||||||
|
SELECT is_monitored
|
||||||
|
FROM events
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: UpdateEventMonitored :exec
|
||||||
UPDATE events
|
UPDATE events
|
||||||
SET is_featured = $1
|
SET is_monitored = $1
|
||||||
WHERE id = $2;
|
WHERE id = $2;
|
||||||
|
-- name: UpdateEventSettings :exec
|
||||||
|
UPDATE company_event_settings
|
||||||
|
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||||
|
is_featured = COALESCE(
|
||||||
|
sqlc.narg('is_featured'),
|
||||||
|
is_featured
|
||||||
|
),
|
||||||
|
winning_upper_limit = COALESCE(
|
||||||
|
sqlc.narg('winning_upper_limit'),
|
||||||
|
winning_upper_limit
|
||||||
|
)
|
||||||
|
WHERE event_id = $1
|
||||||
|
AND company_id = $2;
|
||||||
-- name: DeleteEvent :exec
|
-- name: DeleteEvent :exec
|
||||||
DELETE FROM events
|
DELETE FROM events
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
@ -4,16 +4,55 @@ SELECT DATE_TRUNC('month', start_time) AS month,
|
||||||
FROM events
|
FROM events
|
||||||
JOIN leagues ON leagues.id = events.league_id
|
JOIN leagues ON leagues.id = events.league_id
|
||||||
WHERE (
|
WHERE (
|
||||||
events.is_featured = sqlc.narg('is_event_featured')
|
|
||||||
OR sqlc.narg('is_event_featured') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
leagues.is_featured = sqlc.narg('is_league_featured')
|
|
||||||
OR sqlc.narg('is_league_featured') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
events.league_id = sqlc.narg('league_id')
|
events.league_id = sqlc.narg('league_id')
|
||||||
OR sqlc.narg('league_id') IS NULL
|
OR sqlc.narg('league_id') IS NULL
|
||||||
)
|
)
|
||||||
GROUP BY month
|
GROUP BY month
|
||||||
ORDER BY month;
|
ORDER BY month;
|
||||||
|
-- name: GetLeagueEventStat :many
|
||||||
|
SELECT leagues.id,
|
||||||
|
leagues.name,
|
||||||
|
COUNT(*) AS total_events,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'pending'
|
||||||
|
) AS pending,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'in_play'
|
||||||
|
) AS in_play,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'to_be_fixed'
|
||||||
|
) AS to_be_fixed,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'ended'
|
||||||
|
) AS ended,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'postponed'
|
||||||
|
) AS postponed,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'cancelled'
|
||||||
|
) AS cancelled,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'walkover'
|
||||||
|
) AS walkover,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'interrupted'
|
||||||
|
) AS interrupted,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'abandoned'
|
||||||
|
) AS abandoned,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'retired'
|
||||||
|
) AS retired,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'suspended'
|
||||||
|
) AS suspended,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'decided_by_fa'
|
||||||
|
) AS decided_by_fa,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'removed'
|
||||||
|
) AS removed
|
||||||
|
FROM leagues
|
||||||
|
JOIN events ON leagues.id = events.league_id
|
||||||
|
GROUP BY leagues.id,
|
||||||
|
leagues.name;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
-- name: CreateFlag :one
|
-- name: CreateFlag :one
|
||||||
INSERT INTO flags (
|
INSERT INTO flags (
|
||||||
bet_id,
|
bet_id,
|
||||||
odd_id,
|
odds_market_id,
|
||||||
reason
|
reason
|
||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3
|
$1, $2, $3
|
||||||
|
|
|
||||||
|
|
@ -5,25 +5,28 @@ INSERT INTO leagues (
|
||||||
country_code,
|
country_code,
|
||||||
bet365_id,
|
bet365_id,
|
||||||
sport_id,
|
sport_id,
|
||||||
is_active,
|
default_is_active,
|
||||||
is_featured
|
default_is_featured
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET name = EXCLUDED.name,
|
SET name = EXCLUDED.name,
|
||||||
country_code = EXCLUDED.country_code,
|
country_code = EXCLUDED.country_code,
|
||||||
bet365_id = EXCLUDED.bet365_id,
|
bet365_id = EXCLUDED.bet365_id,
|
||||||
is_active = EXCLUDED.is_active,
|
|
||||||
is_featured = EXCLUDED.is_featured,
|
|
||||||
sport_id = EXCLUDED.sport_id;
|
sport_id = EXCLUDED.sport_id;
|
||||||
|
-- name: InsertLeagueSettings :exec
|
||||||
|
INSERT INTO company_league_settings (
|
||||||
|
company_id,
|
||||||
|
league_id,
|
||||||
|
is_active,
|
||||||
|
is_featured
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4) ON CONFLICT(company_id, league_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET is_active = EXCLUDED.is_active,
|
||||||
|
is_featured = EXCLUDED.is_featured;
|
||||||
-- name: GetAllLeagues :many
|
-- name: GetAllLeagues :many
|
||||||
SELECT id,
|
SELECT *
|
||||||
name,
|
|
||||||
country_code,
|
|
||||||
bet365_id,
|
|
||||||
is_active,
|
|
||||||
is_featured,
|
|
||||||
sport_id
|
|
||||||
FROM leagues
|
FROM leagues
|
||||||
WHERE (
|
WHERE (
|
||||||
country_code = sqlc.narg('country_code')
|
country_code = sqlc.narg('country_code')
|
||||||
|
|
@ -33,6 +36,20 @@ WHERE (
|
||||||
sport_id = sqlc.narg('sport_id')
|
sport_id = sqlc.narg('sport_id')
|
||||||
OR sqlc.narg('sport_id') IS NULL
|
OR sqlc.narg('sport_id') IS NULL
|
||||||
)
|
)
|
||||||
|
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 (
|
||||||
|
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 (
|
AND (
|
||||||
is_active = sqlc.narg('is_active')
|
is_active = sqlc.narg('is_active')
|
||||||
OR sqlc.narg('is_active') IS NULL
|
OR sqlc.narg('is_active') IS NULL
|
||||||
|
|
@ -44,21 +61,12 @@ WHERE (
|
||||||
ORDER BY is_featured DESC,
|
ORDER BY is_featured DESC,
|
||||||
name ASC
|
name ASC
|
||||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
-- name: GetFeaturedLeagues :many
|
|
||||||
SELECT id,
|
|
||||||
name,
|
|
||||||
country_code,
|
|
||||||
bet365_id,
|
|
||||||
is_active,
|
|
||||||
is_featured,
|
|
||||||
sport_id
|
|
||||||
FROM leagues
|
|
||||||
WHERE is_featured = true;
|
|
||||||
-- name: CheckLeagueSupport :one
|
-- name: CheckLeagueSupport :one
|
||||||
SELECT EXISTS(
|
SELECT EXISTS(
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM leagues
|
FROM company_league_settings
|
||||||
WHERE id = $1
|
WHERE league_id = $1
|
||||||
|
AND company_id = $2
|
||||||
AND is_active = true
|
AND is_active = true
|
||||||
);
|
);
|
||||||
-- name: UpdateLeague :exec
|
-- name: UpdateLeague :exec
|
||||||
|
|
@ -66,20 +74,14 @@ UPDATE leagues
|
||||||
SET name = COALESCE(sqlc.narg('name'), name),
|
SET name = COALESCE(sqlc.narg('name'), name),
|
||||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
||||||
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
bet365_id = COALESCE(sqlc.narg('bet365_id'), bet365_id),
|
||||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
|
||||||
is_featured = COALESCE(sqlc.narg('is_featured'), is_featured),
|
|
||||||
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: UpdateLeagueByBet365ID :exec
|
-- name: UpdateLeagueSettings :exec
|
||||||
UPDATE leagues
|
UPDATE company_league_settings
|
||||||
SET name = COALESCE(sqlc.narg('name'), name),
|
SET is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
||||||
id = COALESCE(sqlc.narg('id'), id),
|
is_featured = COALESCE(
|
||||||
country_code = COALESCE(sqlc.narg('country_code'), country_code),
|
sqlc.narg('is_featured'),
|
||||||
is_active = COALESCE(sqlc.narg('is_active'), is_active),
|
is_featured
|
||||||
is_featured = COALESCE(sqlc.narg('is_featured'), is_featured),
|
)
|
||||||
sport_id = COALESCE(sqlc.narg('sport_id'), sport_id)
|
WHERE league_id = $1
|
||||||
WHERE bet365_id = $1;
|
AND company_id = $2;
|
||||||
-- name: SetLeagueActive :exec
|
|
||||||
UPDATE leagues
|
|
||||||
SET is_active = $2
|
|
||||||
WHERE id = $1;
|
|
||||||
66
db/query/odd_history.sql
Normal file
66
db/query/odd_history.sql
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
-- name: InsertOddHistory :one
|
||||||
|
INSERT INTO odd_history (
|
||||||
|
odds_market_id,
|
||||||
|
market_id,
|
||||||
|
raw_odd_id,
|
||||||
|
event_id,
|
||||||
|
odd_value
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllOddHistory :many
|
||||||
|
SELECT *
|
||||||
|
FROM odd_history
|
||||||
|
WHERE (
|
||||||
|
odds_market_id = sqlc.narg('odd_id')
|
||||||
|
OR sqlc.narg('odd_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
market_id = sqlc.narg('market_id')
|
||||||
|
OR sqlc.narg('market_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
raw_odd_id = sqlc.narg('raw_odd_id')
|
||||||
|
OR sqlc.narg('raw_odd_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
event_id = sqlc.narg('event_id')
|
||||||
|
OR sqlc.narg('event_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetInitialOddPerDay :many
|
||||||
|
SELECT DISTINCT ON (DATE_TRUNC($1, created_at)) *
|
||||||
|
FROM odd_history
|
||||||
|
WHERE (
|
||||||
|
odds_market_id = sqlc.narg('odd_id')
|
||||||
|
OR sqlc.narg('odd_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
market_id = sqlc.narg('market_id')
|
||||||
|
OR sqlc.narg('market_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
raw_odd_id = sqlc.narg('raw_odd_id')
|
||||||
|
OR sqlc.narg('raw_odd_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
event_id = sqlc.narg('event_id')
|
||||||
|
OR sqlc.narg('event_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY DATE_TRUNC($1, created_at),
|
||||||
|
created_at ASC;
|
||||||
|
|
@ -1,20 +1,13 @@
|
||||||
-- name: InsertNonLiveOdd :exec
|
-- name: InsertOddsMarket :exec
|
||||||
INSERT INTO odds (
|
INSERT INTO odds_market (
|
||||||
event_id,
|
event_id,
|
||||||
fi,
|
|
||||||
market_type,
|
market_type,
|
||||||
market_name,
|
market_name,
|
||||||
market_category,
|
market_category,
|
||||||
market_id,
|
market_id,
|
||||||
name,
|
|
||||||
handicap,
|
|
||||||
odds_value,
|
|
||||||
section,
|
|
||||||
category,
|
|
||||||
raw_odds,
|
raw_odds,
|
||||||
is_active,
|
fetched_at,
|
||||||
source,
|
expires_at
|
||||||
fetched_at
|
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
$1,
|
$1,
|
||||||
|
|
@ -24,95 +17,69 @@ VALUES (
|
||||||
$5,
|
$5,
|
||||||
$6,
|
$6,
|
||||||
$7,
|
$7,
|
||||||
$8,
|
$8
|
||||||
$9,
|
|
||||||
$10,
|
|
||||||
$11,
|
|
||||||
$12,
|
|
||||||
$13,
|
|
||||||
$14,
|
|
||||||
$15
|
|
||||||
) ON CONFLICT (event_id, market_id) DO
|
) ON CONFLICT (event_id, market_id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET odds_value = EXCLUDED.odds_value,
|
SET market_type = EXCLUDED.market_type,
|
||||||
raw_odds = EXCLUDED.raw_odds,
|
|
||||||
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,
|
||||||
name = EXCLUDED.name,
|
raw_odds = EXCLUDED.raw_odds,
|
||||||
handicap = EXCLUDED.handicap,
|
|
||||||
fetched_at = EXCLUDED.fetched_at,
|
fetched_at = EXCLUDED.fetched_at,
|
||||||
is_active = EXCLUDED.is_active,
|
expires_at = EXCLUDED.expires_at;
|
||||||
source = EXCLUDED.source,
|
-- name: InsertOddSettings :exec
|
||||||
fi = EXCLUDED.fi;
|
INSERT INTO company_odd_settings (
|
||||||
-- name: GetPrematchOdds :many
|
company_id,
|
||||||
SELECT event_id,
|
odds_market_id,
|
||||||
fi,
|
is_active,
|
||||||
market_type,
|
custom_raw_odds
|
||||||
market_name,
|
)
|
||||||
market_category,
|
VALUES ($1, $2, $3, $4) ON CONFLICT (company_id, odds_market_id) DO
|
||||||
market_id,
|
UPDATE
|
||||||
name,
|
SET is_active = EXCLUDED.is_active,
|
||||||
handicap,
|
custom_raw_odds = EXCLUDED.custom_raw_odds;
|
||||||
odds_value,
|
-- name: GetAllOdds :many
|
||||||
section,
|
SELECT *
|
||||||
category,
|
FROM odds_market_with_event
|
||||||
raw_odds,
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
fetched_at,
|
-- name: GetAllOddsWithSettings :many
|
||||||
source,
|
SELECT *
|
||||||
is_active
|
FROM odds_market_with_settings
|
||||||
FROM odds
|
WHERE company_id = $1
|
||||||
WHERE is_active = true
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
AND source = 'bet365';
|
-- name: GetOddsByMarketID :one
|
||||||
-- name: GetALLPrematchOdds :many
|
SELECT *
|
||||||
SELECT event_id,
|
FROM odds_market_with_event
|
||||||
fi,
|
|
||||||
market_type,
|
|
||||||
market_name,
|
|
||||||
market_category,
|
|
||||||
market_id,
|
|
||||||
name,
|
|
||||||
handicap,
|
|
||||||
odds_value,
|
|
||||||
section,
|
|
||||||
category,
|
|
||||||
raw_odds,
|
|
||||||
fetched_at,
|
|
||||||
source,
|
|
||||||
is_active
|
|
||||||
FROM odds
|
|
||||||
WHERE is_active = true
|
|
||||||
AND source = 'bet365';
|
|
||||||
-- name: GetRawOddsByMarketID :one
|
|
||||||
SELECT id,
|
|
||||||
market_name,
|
|
||||||
handicap,
|
|
||||||
raw_odds,
|
|
||||||
fetched_at
|
|
||||||
FROM odds
|
|
||||||
WHERE market_id = $1
|
WHERE market_id = $1
|
||||||
AND fi = $2
|
AND event_id = $2;
|
||||||
AND is_active = true
|
-- name: GetOddsWithSettingsByMarketID :one
|
||||||
AND source = 'bet365';
|
SELECT *
|
||||||
-- name: GetPrematchOddsByUpcomingID :many
|
FROM odds_market_with_settings
|
||||||
SELECT o.*
|
WHERE market_id = $1
|
||||||
FROM odds o
|
AND event_id = $2
|
||||||
JOIN events e ON o.fi = e.id
|
AND company_id = $3;
|
||||||
WHERE e.id = $1
|
-- name: GetOddsByEventID :many
|
||||||
AND e.is_live = false
|
SELECT *
|
||||||
AND e.status = 'upcoming'
|
FROM odds_market_with_event
|
||||||
AND o.is_active = true
|
WHERE event_id = $1
|
||||||
AND o.source = 'bet365';
|
AND (
|
||||||
-- name: GetPaginatedPrematchOddsByUpcomingID :many
|
is_live = sqlc.narg('is_live')
|
||||||
SELECT o.*
|
OR sqlc.narg('is_live') IS NULL
|
||||||
FROM odds o
|
)
|
||||||
JOIN events e ON o.fi = e.id
|
AND (
|
||||||
WHERE e.id = $1
|
status = sqlc.narg('status')
|
||||||
AND e.is_live = false
|
OR sqlc.narg('status') IS NULL
|
||||||
AND e.status = 'upcoming'
|
)
|
||||||
AND o.is_active = true
|
AND (
|
||||||
AND o.source = 'bet365'
|
source = sqlc.narg('source')
|
||||||
|
OR sqlc.narg('source') IS NULL
|
||||||
|
)
|
||||||
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
|
-- name: GetOddsWithSettingsByEventID :many
|
||||||
|
SELECT *
|
||||||
|
FROM odds_market_with_settings
|
||||||
|
WHERE event_id = $1
|
||||||
|
AND company_id = $2
|
||||||
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
|
DELETE FROM odds_market
|
||||||
Where fi = $1;
|
Where event_id = $1;
|
||||||
28
db/query/result_log.sql
Normal file
28
db/query/result_log.sql
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- name: CreateResultLog :one
|
||||||
|
INSERT INTO result_log (
|
||||||
|
status_not_finished_count,
|
||||||
|
status_not_finished_bets,
|
||||||
|
status_to_be_fixed_count,
|
||||||
|
status_to_be_fixed_bets,
|
||||||
|
status_postponed_count,
|
||||||
|
status_postponed_bets,
|
||||||
|
status_ended_count,
|
||||||
|
status_ended_bets,
|
||||||
|
status_removed_count,
|
||||||
|
status_removed_bets,
|
||||||
|
removed_count
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllResultLog :many
|
||||||
|
SELECT *
|
||||||
|
FROM result_log
|
||||||
|
WHERE (
|
||||||
|
created_at < sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY created_at DESC;
|
||||||
|
|
@ -1,13 +1,41 @@
|
||||||
-- name: GetSettings :many
|
-- name: GetGlobalSettings :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM settings;
|
FROM global_settings;
|
||||||
-- name: GetSetting :one
|
-- name: GetGlobalSetting :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM settings
|
FROM global_settings
|
||||||
WHERE key = $1;
|
WHERE key = $1;
|
||||||
-- name: SaveSetting :one
|
-- name: UpdateGlobalSetting :exec
|
||||||
INSERT INTO settings (key, value, updated_at)
|
UPDATE global_settings
|
||||||
VALUES ($1, $2, CURRENT_TIMESTAMP) ON CONFLICT (key) DO
|
SET value = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE key = $1;
|
||||||
|
-- name: InsertCompanySetting :exec
|
||||||
|
INSERT INTO company_settings (company_id, key, value)
|
||||||
|
VALUES ($1, $2, $3) ON CONFLICT (company_id, key) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET value = EXCLUDED.value
|
SET value = EXCLUDED.value;
|
||||||
RETURNING *;
|
-- name: GetAllCompanySettings :many
|
||||||
|
SELECT *
|
||||||
|
FROM company_settings;
|
||||||
|
-- name: GetCompanySetting :many
|
||||||
|
SELECT *
|
||||||
|
FROM company_settings
|
||||||
|
WHERE company_id = $1;
|
||||||
|
-- name: GetCompanySettingsByKey :many
|
||||||
|
SELECT *
|
||||||
|
FROM company_settings
|
||||||
|
WHERE key = $1;
|
||||||
|
-- name: GetOverrideSettings :many
|
||||||
|
SELECT gs.*,
|
||||||
|
COALESCE(cs.value, gs.value) AS value
|
||||||
|
FROM global_settings gs
|
||||||
|
LEFT JOIN company_settings cs ON cs.key = gs.key
|
||||||
|
AND cs.company_id = $1;
|
||||||
|
-- name: DeleteCompanySetting :exec
|
||||||
|
DELETE FROM company_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
AND key = $2;
|
||||||
|
-- name: DeleteAllCompanySetting :exec
|
||||||
|
DELETE FROM company_settings
|
||||||
|
WHERE company_id = $1;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
-- name: CreateTicket :one
|
-- name: CreateTicket :one
|
||||||
INSERT INTO tickets (amount, total_odds, ip)
|
INSERT INTO tickets (amount, total_odds, ip, company_id)
|
||||||
VALUES ($1, $2, $3)
|
VALUES ($1, $2, $3, $4)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
-- name: CreateTicketOutcome :copyfrom
|
-- name: CreateTicketOutcome :copyfrom
|
||||||
INSERT INTO ticket_outcomes (
|
INSERT INTO ticket_outcomes (
|
||||||
|
|
@ -33,7 +33,11 @@ VALUES (
|
||||||
);
|
);
|
||||||
-- name: GetAllTickets :many
|
-- name: GetAllTickets :many
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM ticket_with_outcomes;
|
FROM ticket_with_outcomes
|
||||||
|
WHERE (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
);
|
||||||
-- name: GetTicketByID :one
|
-- name: GetTicketByID :one
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM ticket_with_outcomes
|
FROM ticket_with_outcomes
|
||||||
|
|
@ -60,6 +64,7 @@ where created_at < now() - interval '1 day';
|
||||||
Delete from ticket_outcomes
|
Delete from ticket_outcomes
|
||||||
where ticket_id = $1;
|
where ticket_id = $1;
|
||||||
-- name: GetAllTicketsInRange :one
|
-- name: GetAllTicketsInRange :one
|
||||||
SELECT COUNT(*) as total_tickets, COALESCE(SUM(amount), 0) as total_amount
|
SELECT COUNT(*) as total_tickets,
|
||||||
|
COALESCE(SUM(amount), 0) as total_amount
|
||||||
FROM tickets
|
FROM tickets
|
||||||
WHERE created_at BETWEEN $1 AND $2;
|
WHERE created_at BETWEEN $1 AND $2;
|
||||||
|
|
@ -107,18 +107,15 @@ SELECT id,
|
||||||
suspended_at,
|
suspended_at,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE (
|
WHERE (company_id = $1)
|
||||||
first_name ILIKE '%' || $1 || '%'
|
AND (
|
||||||
OR last_name ILIKE '%' || $1 || '%'
|
first_name ILIKE '%' || $2 || '%'
|
||||||
OR phone_number LIKE '%' || $1 || '%'
|
OR last_name ILIKE '%' || $2 || '%'
|
||||||
|
OR phone_number LIKE '%' || $2 || '%'
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
role = sqlc.narg('role')
|
role = sqlc.narg('role')
|
||||||
OR sqlc.narg('role') IS NULL
|
OR sqlc.narg('role') IS NULL
|
||||||
)
|
|
||||||
AND (
|
|
||||||
company_id = sqlc.narg('company_id')
|
|
||||||
OR sqlc.narg('company_id') IS NULL
|
|
||||||
);
|
);
|
||||||
-- name: UpdateUser :exec
|
-- name: UpdateUser :exec
|
||||||
UPDATE users
|
UPDATE users
|
||||||
|
|
@ -146,12 +143,14 @@ SELECT EXISTS (
|
||||||
FROM users
|
FROM users
|
||||||
WHERE users.phone_number = $1
|
WHERE users.phone_number = $1
|
||||||
AND users.phone_number IS NOT NULL
|
AND users.phone_number IS NOT NULL
|
||||||
|
AND users.company_id = $2
|
||||||
) AS phone_exists,
|
) AS phone_exists,
|
||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM users
|
FROM users
|
||||||
WHERE users.email = $2
|
WHERE users.email = $3
|
||||||
AND users.email IS NOT NULL
|
AND users.email IS NOT NULL
|
||||||
|
AND users.company_id = $2
|
||||||
) AS email_exists;
|
) AS email_exists;
|
||||||
-- name: GetUserByEmail :one
|
-- name: GetUserByEmail :one
|
||||||
SELECT id,
|
SELECT id,
|
||||||
|
|
@ -168,7 +167,8 @@ SELECT id,
|
||||||
suspended_at,
|
suspended_at,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE email = $1;
|
WHERE email = $1
|
||||||
|
AND company_id = $2;
|
||||||
-- name: GetUserByPhone :one
|
-- name: GetUserByPhone :one
|
||||||
SELECT id,
|
SELECT id,
|
||||||
first_name,
|
first_name,
|
||||||
|
|
@ -184,7 +184,8 @@ SELECT id,
|
||||||
suspended_at,
|
suspended_at,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE phone_number = $1;
|
WHERE phone_number = $1
|
||||||
|
AND company_id = $2;
|
||||||
-- name: UpdatePassword :exec
|
-- name: UpdatePassword :exec
|
||||||
UPDATE users
|
UPDATE users
|
||||||
SET password = $1,
|
SET password = $1,
|
||||||
|
|
@ -192,6 +193,7 @@ SET password = $1,
|
||||||
WHERE (
|
WHERE (
|
||||||
email = $2
|
email = $2
|
||||||
OR phone_number = $3
|
OR phone_number = $3
|
||||||
|
AND company_id = $4
|
||||||
);
|
);
|
||||||
-- name: GetAdminByCompanyID :one
|
-- name: GetAdminByCompanyID :one
|
||||||
SELECT users.*
|
SELECT users.*
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ services:
|
||||||
retries: 5
|
retries: 5
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
- ./exports:/exports
|
||||||
|
|
||||||
mongo:
|
mongo:
|
||||||
container_name: fortunebet-mongo
|
container_name: fortunebet-mongo
|
||||||
|
|
|
||||||
|
|
@ -78,17 +78,24 @@ func (q *Queries) GetRefreshTokenByUserID(ctx context.Context, userID int64) (Re
|
||||||
const GetUserByEmailPhone = `-- name: GetUserByEmailPhone :one
|
const GetUserByEmailPhone = `-- name: GetUserByEmailPhone :one
|
||||||
SELECT id, first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at, company_id, suspended_at, suspended, referral_code, referred_by
|
SELECT id, first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at, company_id, suspended_at, suspended, referral_code, referred_by
|
||||||
FROM users
|
FROM users
|
||||||
WHERE email = $1
|
WHERE (
|
||||||
OR phone_number = $2
|
email = $1
|
||||||
|
OR phone_number = $2
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserByEmailPhoneParams struct {
|
type GetUserByEmailPhoneParams struct {
|
||||||
Email pgtype.Text `json:"email"`
|
Email pgtype.Text `json:"email"`
|
||||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPhoneParams) (User, error) {
|
func (q *Queries) GetUserByEmailPhone(ctx context.Context, arg GetUserByEmailPhoneParams) (User, error) {
|
||||||
row := q.db.QueryRow(ctx, GetUserByEmailPhone, arg.Email, arg.PhoneNumber)
|
row := q.db.QueryRow(ctx, GetUserByEmailPhone, arg.Email, arg.PhoneNumber, arg.CompanyID)
|
||||||
var i User
|
var i User
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@ INSERT INTO bets (
|
||||||
user_id,
|
user_id,
|
||||||
is_shop_bet,
|
is_shop_bet,
|
||||||
outcomes_hash,
|
outcomes_hash,
|
||||||
fast_code
|
fast_code,
|
||||||
|
company_id
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
RETURNING id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at
|
RETURNING id, company_id, amount, total_odds, status, user_id, is_shop_bet, cashed_out, outcomes_hash, fast_code, processed, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateBetParams struct {
|
type CreateBetParams struct {
|
||||||
|
|
@ -33,6 +34,7 @@ type CreateBetParams struct {
|
||||||
IsShopBet bool `json:"is_shop_bet"`
|
IsShopBet bool `json:"is_shop_bet"`
|
||||||
OutcomesHash string `json:"outcomes_hash"`
|
OutcomesHash string `json:"outcomes_hash"`
|
||||||
FastCode string `json:"fast_code"`
|
FastCode string `json:"fast_code"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) {
|
func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) {
|
||||||
|
|
@ -44,10 +46,12 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro
|
||||||
arg.IsShopBet,
|
arg.IsShopBet,
|
||||||
arg.OutcomesHash,
|
arg.OutcomesHash,
|
||||||
arg.FastCode,
|
arg.FastCode,
|
||||||
|
arg.CompanyID,
|
||||||
)
|
)
|
||||||
var i Bet
|
var i Bet
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
@ -100,7 +104,7 @@ func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllBets = `-- name: GetAllBets :many
|
const GetAllBets = `-- name: GetAllBets :many
|
||||||
SELECT 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
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
wHERE (
|
wHERE (
|
||||||
user_id = $1
|
user_id = $1
|
||||||
|
|
@ -111,27 +115,32 @@ wHERE (
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
cashed_out = $3
|
company_id = $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
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetAllBetsParams struct {
|
type GetAllBetsParams struct {
|
||||||
UserID pgtype.Int8 `json:"user_id"`
|
UserID pgtype.Int8 `json:"user_id"`
|
||||||
IsShopBet pgtype.Bool `json:"is_shop_bet"`
|
IsShopBet pgtype.Bool `json:"is_shop_bet"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
CashedOut pgtype.Bool `json:"cashed_out"`
|
CashedOut pgtype.Bool `json:"cashed_out"`
|
||||||
Query pgtype.Text `json:"query"`
|
Query pgtype.Text `json:"query"`
|
||||||
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
|
@ -142,6 +151,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
||||||
rows, err := q.db.Query(ctx, GetAllBets,
|
rows, err := q.db.Query(ctx, GetAllBets,
|
||||||
arg.UserID,
|
arg.UserID,
|
||||||
arg.IsShopBet,
|
arg.IsShopBet,
|
||||||
|
arg.CompanyID,
|
||||||
arg.CashedOut,
|
arg.CashedOut,
|
||||||
arg.Query,
|
arg.Query,
|
||||||
arg.CreatedBefore,
|
arg.CreatedBefore,
|
||||||
|
|
@ -156,6 +166,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
||||||
var i BetWithOutcome
|
var i BetWithOutcome
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
@ -182,7 +193,7 @@ func (q *Queries) GetAllBets(ctx context.Context, arg GetAllBetsParams) ([]BetWi
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByFastCode = `-- name: GetBetByFastCode :one
|
const GetBetByFastCode = `-- name: GetBetByFastCode :one
|
||||||
SELECT 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
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE fast_code = $1
|
WHERE fast_code = $1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -193,6 +204,7 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit
|
||||||
var i BetWithOutcome
|
var i BetWithOutcome
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
@ -212,7 +224,7 @@ func (q *Queries) GetBetByFastCode(ctx context.Context, fastCode string) (BetWit
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByID = `-- name: GetBetByID :one
|
const GetBetByID = `-- name: GetBetByID :one
|
||||||
SELECT 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
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -222,6 +234,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
|
||||||
var i BetWithOutcome
|
var i BetWithOutcome
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
@ -241,7 +254,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByUserID = `-- name: GetBetByUserID :many
|
const GetBetByUserID = `-- name: GetBetByUserID :many
|
||||||
SELECT 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
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -257,6 +270,7 @@ func (q *Queries) GetBetByUserID(ctx context.Context, userID int64) ([]BetWithOu
|
||||||
var i BetWithOutcome
|
var i BetWithOutcome
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
@ -424,7 +438,7 @@ func (q *Queries) GetBetOutcomeCountByOddID(ctx context.Context, oddID int64) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetsForCashback = `-- name: GetBetsForCashback :many
|
const GetBetsForCashback = `-- name: GetBetsForCashback :many
|
||||||
SELECT 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
|
||||||
FROM bet_with_outcomes
|
FROM bet_with_outcomes
|
||||||
WHERE status = 2
|
WHERE status = 2
|
||||||
AND processed = false
|
AND processed = false
|
||||||
|
|
@ -441,6 +455,7 @@ func (q *Queries) GetBetsForCashback(ctx context.Context) ([]BetWithOutcome, err
|
||||||
var i BetWithOutcome
|
var i BetWithOutcome
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Status,
|
&i.Status,
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,18 @@ import (
|
||||||
const CreateCompany = `-- name: CreateCompany :one
|
const CreateCompany = `-- name: CreateCompany :one
|
||||||
INSERT INTO companies (
|
INSERT INTO companies (
|
||||||
name,
|
name,
|
||||||
|
slug,
|
||||||
admin_id,
|
admin_id,
|
||||||
wallet_id,
|
wallet_id,
|
||||||
deducted_percentage
|
deducted_percentage
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING id, name, 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
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateCompanyParams struct {
|
type CreateCompanyParams struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
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"`
|
||||||
|
|
@ -32,6 +34,7 @@ type CreateCompanyParams struct {
|
||||||
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
|
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
|
||||||
row := q.db.QueryRow(ctx, CreateCompany,
|
row := q.db.QueryRow(ctx, CreateCompany,
|
||||||
arg.Name,
|
arg.Name,
|
||||||
|
arg.Slug,
|
||||||
arg.AdminID,
|
arg.AdminID,
|
||||||
arg.WalletID,
|
arg.WalletID,
|
||||||
arg.DeductedPercentage,
|
arg.DeductedPercentage,
|
||||||
|
|
@ -40,6 +43,7 @@ func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (C
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
&i.DeductedPercentage,
|
&i.DeductedPercentage,
|
||||||
|
|
@ -61,7 +65,7 @@ func (q *Queries) DeleteCompany(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllCompanies = `-- name: GetAllCompanies :many
|
const GetAllCompanies = `-- name: GetAllCompanies :many
|
||||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE (
|
WHERE (
|
||||||
name ILIKE '%' || $1 || '%'
|
name ILIKE '%' || $1 || '%'
|
||||||
|
|
@ -98,6 +102,7 @@ func (q *Queries) GetAllCompanies(ctx context.Context, arg GetAllCompaniesParams
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
&i.DeductedPercentage,
|
&i.DeductedPercentage,
|
||||||
|
|
@ -121,7 +126,7 @@ func (q *Queries) GetAllCompanies(ctx context.Context, arg GetAllCompaniesParams
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetCompanyByID = `-- name: GetCompanyByID :one
|
const GetCompanyByID = `-- name: GetCompanyByID :one
|
||||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -132,6 +137,7 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
&i.DeductedPercentage,
|
&i.DeductedPercentage,
|
||||||
|
|
@ -147,8 +153,21 @@ func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (CompaniesDetail
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GetCompanyIDUsingSlug = `-- name: GetCompanyIDUsingSlug :one
|
||||||
|
SELECT id
|
||||||
|
FROM companies
|
||||||
|
WHERE slug = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetCompanyIDUsingSlug(ctx context.Context, slug string) (int64, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetCompanyIDUsingSlug, slug)
|
||||||
|
var id int64
|
||||||
|
err := row.Scan(&id)
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
const SearchCompanyByName = `-- name: SearchCompanyByName :many
|
||||||
SELECT id, name, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
SELECT id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at, balance, wallet_is_active, admin_first_name, admin_last_name, admin_phone_number
|
||||||
FROM companies_details
|
FROM companies_details
|
||||||
WHERE name ILIKE '%' || $1 || '%'
|
WHERE name ILIKE '%' || $1 || '%'
|
||||||
`
|
`
|
||||||
|
|
@ -165,6 +184,7 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
&i.DeductedPercentage,
|
&i.DeductedPercentage,
|
||||||
|
|
@ -198,7 +218,7 @@ SET name = COALESCE($2, name),
|
||||||
),
|
),
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, name, 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
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateCompanyParams struct {
|
type UpdateCompanyParams struct {
|
||||||
|
|
@ -221,6 +241,7 @@ func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (C
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.Slug,
|
||||||
&i.AdminID,
|
&i.AdminID,
|
||||||
&i.WalletID,
|
&i.WalletID,
|
||||||
&i.DeductedPercentage,
|
&i.DeductedPercentage,
|
||||||
|
|
|
||||||
139
gen/db/disabled_odds.sql.go
Normal file
139
gen/db/disabled_odds.sql.go
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.29.0
|
||||||
|
// source: disabled_odds.sql
|
||||||
|
|
||||||
|
package dbgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const DeleteDisabledOddsByID = `-- name: DeleteDisabledOddsByID :exec
|
||||||
|
DELETE FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteDisabledOddsByID(ctx context.Context, rawOddID int64) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteDisabledOddsByID, rawOddID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteDisabledOddsByRawOddID = `-- name: DeleteDisabledOddsByRawOddID :exec
|
||||||
|
DELETE FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteDisabledOddsByRawOddID(ctx context.Context, rawOddID int64) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteDisabledOddsByRawOddID, rawOddID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllDisabledOdds = `-- name: GetAllDisabledOdds :many
|
||||||
|
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
|
||||||
|
FROM disabled_odd
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetAllDisabledOdds(ctx context.Context) ([]DisabledOdd, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllDisabledOdds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []DisabledOdd
|
||||||
|
for rows.Next() {
|
||||||
|
var i DisabledOdd
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetDisabledOddByID = `-- name: GetDisabledOddByID :one
|
||||||
|
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
|
||||||
|
FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetDisabledOddByID(ctx context.Context, rawOddID int64) (DisabledOdd, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetDisabledOddByID, rawOddID)
|
||||||
|
var i DisabledOdd
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetDisabledOddByRawOddID = `-- name: GetDisabledOddByRawOddID :one
|
||||||
|
SELECT id, company_id, odds_market_id, raw_odd_id, event_id, created_at
|
||||||
|
FROM disabled_odd
|
||||||
|
WHERE raw_odd_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (DisabledOdd, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetDisabledOddByRawOddID, rawOddID)
|
||||||
|
var i DisabledOdd
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertDisabledOdds = `-- name: InsertDisabledOdds :one
|
||||||
|
INSERT INTO disabled_odd (
|
||||||
|
odds_market_id,
|
||||||
|
company_id,
|
||||||
|
event_id,
|
||||||
|
raw_odd_id
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING id, company_id, odds_market_id, raw_odd_id, event_id, created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertDisabledOddsParams struct {
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
RawOddID int64 `json:"raw_odd_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) InsertDisabledOdds(ctx context.Context, arg InsertDisabledOddsParams) (DisabledOdd, error) {
|
||||||
|
row := q.db.QueryRow(ctx, InsertDisabledOdds,
|
||||||
|
arg.OddsMarketID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.RawOddID,
|
||||||
|
)
|
||||||
|
var i DisabledOdd
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
133
gen/db/event_history.sql.go
Normal file
133
gen/db/event_history.sql.go
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.29.0
|
||||||
|
// source: event_history.sql
|
||||||
|
|
||||||
|
package dbgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const GetAllEventHistory = `-- name: GetAllEventHistory :many
|
||||||
|
SELECT id, event_id, status, created_at
|
||||||
|
FROM event_history
|
||||||
|
WHERE (
|
||||||
|
event_id = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllEventHistoryParams struct {
|
||||||
|
EventID pgtype.Text `json:"event_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllEventHistory(ctx context.Context, arg GetAllEventHistoryParams) ([]EventHistory, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllEventHistory, arg.EventID, arg.CreatedBefore, arg.CreatedAfter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []EventHistory
|
||||||
|
for rows.Next() {
|
||||||
|
var i EventHistory
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.Status,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetInitialEventPerDay = `-- name: GetInitialEventPerDay :many
|
||||||
|
SELECT DISTINCT ON (DATE_TRUNC('day', created_at)) id, event_id, status, created_at
|
||||||
|
FROM event_history
|
||||||
|
WHERE (
|
||||||
|
event_id = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY DATE_TRUNC('day', created_at),
|
||||||
|
created_at ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetInitialEventPerDayParams struct {
|
||||||
|
EventID pgtype.Text `json:"event_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetInitialEventPerDay(ctx context.Context, arg GetInitialEventPerDayParams) ([]EventHistory, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetInitialEventPerDay, arg.EventID, arg.CreatedBefore, arg.CreatedAfter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []EventHistory
|
||||||
|
for rows.Next() {
|
||||||
|
var i EventHistory
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.Status,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertEventHistory = `-- name: InsertEventHistory :one
|
||||||
|
INSERT INTO event_history (event_id, status)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING id, event_id, status, created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertEventHistoryParams struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) InsertEventHistory(ctx context.Context, arg InsertEventHistoryParams) (EventHistory, error) {
|
||||||
|
row := q.db.QueryRow(ctx, InsertEventHistory, arg.EventID, arg.Status)
|
||||||
|
var i EventHistory
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.Status,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,40 +11,131 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const GetLeagueEventStat = `-- name: GetLeagueEventStat :many
|
||||||
|
SELECT leagues.id,
|
||||||
|
leagues.name,
|
||||||
|
COUNT(*) AS total_events,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'pending'
|
||||||
|
) AS pending,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'in_play'
|
||||||
|
) AS in_play,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'to_be_fixed'
|
||||||
|
) AS to_be_fixed,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'ended'
|
||||||
|
) AS ended,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'postponed'
|
||||||
|
) AS postponed,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'cancelled'
|
||||||
|
) AS cancelled,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'walkover'
|
||||||
|
) AS walkover,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'interrupted'
|
||||||
|
) AS interrupted,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'abandoned'
|
||||||
|
) AS abandoned,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'retired'
|
||||||
|
) AS retired,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'suspended'
|
||||||
|
) AS suspended,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'decided_by_fa'
|
||||||
|
) AS decided_by_fa,
|
||||||
|
COUNT(*) FILTER (
|
||||||
|
WHERE events.status = 'removed'
|
||||||
|
) AS removed
|
||||||
|
FROM leagues
|
||||||
|
JOIN events ON leagues.id = events.league_id
|
||||||
|
GROUP BY leagues.id,
|
||||||
|
leagues.name
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetLeagueEventStatRow struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
TotalEvents int64 `json:"total_events"`
|
||||||
|
Pending int64 `json:"pending"`
|
||||||
|
InPlay int64 `json:"in_play"`
|
||||||
|
ToBeFixed int64 `json:"to_be_fixed"`
|
||||||
|
Ended int64 `json:"ended"`
|
||||||
|
Postponed int64 `json:"postponed"`
|
||||||
|
Cancelled int64 `json:"cancelled"`
|
||||||
|
Walkover int64 `json:"walkover"`
|
||||||
|
Interrupted int64 `json:"interrupted"`
|
||||||
|
Abandoned int64 `json:"abandoned"`
|
||||||
|
Retired int64 `json:"retired"`
|
||||||
|
Suspended int64 `json:"suspended"`
|
||||||
|
DecidedByFa int64 `json:"decided_by_fa"`
|
||||||
|
Removed int64 `json:"removed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetLeagueEventStat(ctx context.Context) ([]GetLeagueEventStatRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetLeagueEventStat)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetLeagueEventStatRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetLeagueEventStatRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Name,
|
||||||
|
&i.TotalEvents,
|
||||||
|
&i.Pending,
|
||||||
|
&i.InPlay,
|
||||||
|
&i.ToBeFixed,
|
||||||
|
&i.Ended,
|
||||||
|
&i.Postponed,
|
||||||
|
&i.Cancelled,
|
||||||
|
&i.Walkover,
|
||||||
|
&i.Interrupted,
|
||||||
|
&i.Abandoned,
|
||||||
|
&i.Retired,
|
||||||
|
&i.Suspended,
|
||||||
|
&i.DecidedByFa,
|
||||||
|
&i.Removed,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const GetTotalMontlyEventStat = `-- name: GetTotalMontlyEventStat :many
|
const GetTotalMontlyEventStat = `-- name: GetTotalMontlyEventStat :many
|
||||||
SELECT DATE_TRUNC('month', start_time) AS month,
|
SELECT DATE_TRUNC('month', start_time) AS month,
|
||||||
COUNT(*) AS event_count
|
COUNT(*) AS event_count
|
||||||
FROM events
|
FROM events
|
||||||
JOIN leagues ON leagues.id = events.league_id
|
JOIN leagues ON leagues.id = events.league_id
|
||||||
WHERE (
|
WHERE (
|
||||||
events.is_featured = $1
|
events.league_id = $1
|
||||||
OR $1 IS NULL
|
OR $1 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
|
||||||
leagues.is_featured = $2
|
|
||||||
OR $2 IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
events.league_id = $3
|
|
||||||
OR $3 IS NULL
|
|
||||||
)
|
|
||||||
GROUP BY month
|
GROUP BY month
|
||||||
ORDER BY month
|
ORDER BY month
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetTotalMontlyEventStatParams struct {
|
|
||||||
IsEventFeatured pgtype.Bool `json:"is_event_featured"`
|
|
||||||
IsLeagueFeatured pgtype.Bool `json:"is_league_featured"`
|
|
||||||
LeagueID pgtype.Int4 `json:"league_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetTotalMontlyEventStatRow struct {
|
type GetTotalMontlyEventStatRow struct {
|
||||||
Month pgtype.Interval `json:"month"`
|
Month pgtype.Interval `json:"month"`
|
||||||
EventCount int64 `json:"event_count"`
|
EventCount int64 `json:"event_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetTotalMontlyEventStat(ctx context.Context, arg GetTotalMontlyEventStatParams) ([]GetTotalMontlyEventStatRow, error) {
|
func (q *Queries) GetTotalMontlyEventStat(ctx context.Context, leagueID pgtype.Int8) ([]GetTotalMontlyEventStatRow, error) {
|
||||||
rows, err := q.db.Query(ctx, GetTotalMontlyEventStat, arg.IsEventFeatured, arg.IsLeagueFeatured, arg.LeagueID)
|
rows, err := q.db.Query(ctx, GetTotalMontlyEventStat, leagueID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,26 +14,26 @@ import (
|
||||||
const CreateFlag = `-- name: CreateFlag :one
|
const CreateFlag = `-- name: CreateFlag :one
|
||||||
INSERT INTO flags (
|
INSERT INTO flags (
|
||||||
bet_id,
|
bet_id,
|
||||||
odd_id,
|
odds_market_id,
|
||||||
reason
|
reason
|
||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3
|
$1, $2, $3
|
||||||
) RETURNING id, bet_id, odd_id, reason, flagged_at, resolved
|
) RETURNING id, bet_id, odds_market_id, reason, flagged_at, resolved
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateFlagParams struct {
|
type CreateFlagParams struct {
|
||||||
BetID pgtype.Int8 `json:"bet_id"`
|
BetID pgtype.Int8 `json:"bet_id"`
|
||||||
OddID pgtype.Int8 `json:"odd_id"`
|
OddsMarketID pgtype.Int8 `json:"odds_market_id"`
|
||||||
Reason pgtype.Text `json:"reason"`
|
Reason pgtype.Text `json:"reason"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateFlag(ctx context.Context, arg CreateFlagParams) (Flag, error) {
|
func (q *Queries) CreateFlag(ctx context.Context, arg CreateFlagParams) (Flag, error) {
|
||||||
row := q.db.QueryRow(ctx, CreateFlag, arg.BetID, arg.OddID, arg.Reason)
|
row := q.db.QueryRow(ctx, CreateFlag, arg.BetID, arg.OddsMarketID, arg.Reason)
|
||||||
var i Flag
|
var i Flag
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.BetID,
|
&i.BetID,
|
||||||
&i.OddID,
|
&i.OddsMarketID,
|
||||||
&i.Reason,
|
&i.Reason,
|
||||||
&i.FlaggedAt,
|
&i.FlaggedAt,
|
||||||
&i.Resolved,
|
&i.Resolved,
|
||||||
|
|
|
||||||
|
|
@ -14,27 +14,27 @@ import (
|
||||||
const CheckLeagueSupport = `-- name: CheckLeagueSupport :one
|
const CheckLeagueSupport = `-- name: CheckLeagueSupport :one
|
||||||
SELECT EXISTS(
|
SELECT EXISTS(
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM leagues
|
FROM company_league_settings
|
||||||
WHERE id = $1
|
WHERE league_id = $1
|
||||||
|
AND company_id = $2
|
||||||
AND is_active = true
|
AND is_active = true
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) CheckLeagueSupport(ctx context.Context, id int64) (bool, error) {
|
type CheckLeagueSupportParams struct {
|
||||||
row := q.db.QueryRow(ctx, CheckLeagueSupport, id)
|
LeagueID int64 `json:"league_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CheckLeagueSupport(ctx context.Context, arg CheckLeagueSupportParams) (bool, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CheckLeagueSupport, arg.LeagueID, arg.CompanyID)
|
||||||
var exists bool
|
var exists bool
|
||||||
err := row.Scan(&exists)
|
err := row.Scan(&exists)
|
||||||
return exists, err
|
return exists, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllLeagues = `-- name: GetAllLeagues :many
|
const GetAllLeagues = `-- name: GetAllLeagues :many
|
||||||
SELECT id,
|
SELECT id, name, img_url, country_code, bet365_id, sport_id, default_is_active, default_is_featured
|
||||||
name,
|
|
||||||
country_code,
|
|
||||||
bet365_id,
|
|
||||||
is_active,
|
|
||||||
is_featured,
|
|
||||||
sport_id
|
|
||||||
FROM leagues
|
FROM leagues
|
||||||
WHERE (
|
WHERE (
|
||||||
country_code = $1
|
country_code = $1
|
||||||
|
|
@ -44,44 +44,21 @@ WHERE (
|
||||||
sport_id = $2
|
sport_id = $2
|
||||||
OR $2 IS NULL
|
OR $2 IS NULL
|
||||||
)
|
)
|
||||||
AND (
|
ORDER BY name ASC
|
||||||
is_active = $3
|
LIMIT $4 OFFSET $3
|
||||||
OR $3 IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
is_featured = $4
|
|
||||||
OR $4 IS NULL
|
|
||||||
)
|
|
||||||
ORDER BY is_featured DESC,
|
|
||||||
name ASC
|
|
||||||
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"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
|
||||||
Offset pgtype.Int4 `json:"offset"`
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
Limit pgtype.Int4 `json:"limit"`
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetAllLeaguesRow struct {
|
func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([]League, error) {
|
||||||
ID int64 `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
|
||||||
SportID int32 `json:"sport_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([]GetAllLeaguesRow, error) {
|
|
||||||
rows, err := q.db.Query(ctx, GetAllLeagues,
|
rows, err := q.db.Query(ctx, GetAllLeagues,
|
||||||
arg.CountryCode,
|
arg.CountryCode,
|
||||||
arg.SportID,
|
arg.SportID,
|
||||||
arg.IsActive,
|
|
||||||
arg.IsFeatured,
|
|
||||||
arg.Offset,
|
arg.Offset,
|
||||||
arg.Limit,
|
arg.Limit,
|
||||||
)
|
)
|
||||||
|
|
@ -89,17 +66,18 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []GetAllLeaguesRow
|
var items []League
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i GetAllLeaguesRow
|
var i League
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.ImgUrl,
|
||||||
&i.CountryCode,
|
&i.CountryCode,
|
||||||
&i.Bet365ID,
|
&i.Bet365ID,
|
||||||
&i.IsActive,
|
|
||||||
&i.IsFeatured,
|
|
||||||
&i.SportID,
|
&i.SportID,
|
||||||
|
&i.DefaultIsActive,
|
||||||
|
&i.DefaultIsFeatured,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -111,45 +89,71 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetFeaturedLeagues = `-- name: GetFeaturedLeagues :many
|
const GetAllLeaguesWithSettings = `-- name: GetAllLeaguesWithSettings :many
|
||||||
SELECT id,
|
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
|
||||||
name,
|
FROM league_with_settings
|
||||||
country_code,
|
WHERE (company_id = $1)
|
||||||
bet365_id,
|
AND (
|
||||||
is_active,
|
country_code = $2
|
||||||
is_featured,
|
OR $2 IS NULL
|
||||||
sport_id
|
)
|
||||||
FROM leagues
|
AND (
|
||||||
WHERE is_featured = true
|
sport_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
is_active = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
is_featured = $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY is_featured DESC,
|
||||||
|
name ASC
|
||||||
|
LIMIT $7 OFFSET $6
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetFeaturedLeaguesRow struct {
|
type GetAllLeaguesWithSettingsParams struct {
|
||||||
ID int64 `json:"id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
Name string `json:"name"`
|
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
SportID pgtype.Int4 `json:"sport_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"`
|
||||||
SportID int32 `json:"sport_id"`
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetFeaturedLeagues(ctx context.Context) ([]GetFeaturedLeaguesRow, error) {
|
func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeaguesWithSettingsParams) ([]LeagueWithSetting, error) {
|
||||||
rows, err := q.db.Query(ctx, GetFeaturedLeagues)
|
rows, err := q.db.Query(ctx, GetAllLeaguesWithSettings,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.CountryCode,
|
||||||
|
arg.SportID,
|
||||||
|
arg.IsActive,
|
||||||
|
arg.IsFeatured,
|
||||||
|
arg.Offset,
|
||||||
|
arg.Limit,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []GetFeaturedLeaguesRow
|
var items []LeagueWithSetting
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i GetFeaturedLeaguesRow
|
var i LeagueWithSetting
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
|
&i.ImgUrl,
|
||||||
&i.CountryCode,
|
&i.CountryCode,
|
||||||
&i.Bet365ID,
|
&i.Bet365ID,
|
||||||
|
&i.SportID,
|
||||||
|
&i.DefaultIsActive,
|
||||||
|
&i.DefaultIsFeatured,
|
||||||
|
&i.CompanyID,
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.IsFeatured,
|
&i.IsFeatured,
|
||||||
&i.SportID,
|
&i.UpdatedAt,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -168,27 +172,25 @@ INSERT INTO leagues (
|
||||||
country_code,
|
country_code,
|
||||||
bet365_id,
|
bet365_id,
|
||||||
sport_id,
|
sport_id,
|
||||||
is_active,
|
default_is_active,
|
||||||
is_featured
|
default_is_featured
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET name = EXCLUDED.name,
|
SET name = EXCLUDED.name,
|
||||||
country_code = EXCLUDED.country_code,
|
country_code = EXCLUDED.country_code,
|
||||||
bet365_id = EXCLUDED.bet365_id,
|
bet365_id = EXCLUDED.bet365_id,
|
||||||
is_active = EXCLUDED.is_active,
|
|
||||||
is_featured = EXCLUDED.is_featured,
|
|
||||||
sport_id = EXCLUDED.sport_id
|
sport_id = EXCLUDED.sport_id
|
||||||
`
|
`
|
||||||
|
|
||||||
type InsertLeagueParams struct {
|
type InsertLeagueParams struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||||
SportID int32 `json:"sport_id"`
|
SportID int32 `json:"sport_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) error {
|
func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) error {
|
||||||
|
|
@ -198,25 +200,39 @@ func (q *Queries) InsertLeague(ctx context.Context, arg InsertLeagueParams) erro
|
||||||
arg.CountryCode,
|
arg.CountryCode,
|
||||||
arg.Bet365ID,
|
arg.Bet365ID,
|
||||||
arg.SportID,
|
arg.SportID,
|
||||||
arg.IsActive,
|
arg.DefaultIsActive,
|
||||||
arg.IsFeatured,
|
arg.DefaultIsFeatured,
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const SetLeagueActive = `-- name: SetLeagueActive :exec
|
const InsertLeagueSettings = `-- name: InsertLeagueSettings :exec
|
||||||
UPDATE leagues
|
INSERT INTO company_league_settings (
|
||||||
SET is_active = $2
|
company_id,
|
||||||
WHERE id = $1
|
league_id,
|
||||||
|
is_active,
|
||||||
|
is_featured
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4) ON CONFLICT(company_id, league_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET is_active = EXCLUDED.is_active,
|
||||||
|
is_featured = EXCLUDED.is_featured
|
||||||
`
|
`
|
||||||
|
|
||||||
type SetLeagueActiveParams struct {
|
type InsertLeagueSettingsParams struct {
|
||||||
ID int64 `json:"id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
LeagueID int64 `json:"league_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SetLeagueActive(ctx context.Context, arg SetLeagueActiveParams) error {
|
func (q *Queries) InsertLeagueSettings(ctx context.Context, arg InsertLeagueSettingsParams) error {
|
||||||
_, err := q.db.Exec(ctx, SetLeagueActive, arg.ID, arg.IsActive)
|
_, err := q.db.Exec(ctx, InsertLeagueSettings,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.LeagueID,
|
||||||
|
arg.IsActive,
|
||||||
|
arg.IsFeatured,
|
||||||
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,9 +241,7 @@ UPDATE leagues
|
||||||
SET name = COALESCE($2, name),
|
SET name = COALESCE($2, name),
|
||||||
country_code = COALESCE($3, country_code),
|
country_code = COALESCE($3, country_code),
|
||||||
bet365_id = COALESCE($4, bet365_id),
|
bet365_id = COALESCE($4, bet365_id),
|
||||||
is_active = COALESCE($5, is_active),
|
sport_id = COALESCE($5, sport_id)
|
||||||
is_featured = COALESCE($6, is_featured),
|
|
||||||
sport_id = COALESCE($7, sport_id)
|
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -236,8 +250,6 @@ type UpdateLeagueParams struct {
|
||||||
Name pgtype.Text `json:"name"`
|
Name pgtype.Text `json:"name"`
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
|
||||||
SportID pgtype.Int4 `json:"sport_id"`
|
SportID pgtype.Int4 `json:"sport_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,43 +259,35 @@ func (q *Queries) UpdateLeague(ctx context.Context, arg UpdateLeagueParams) erro
|
||||||
arg.Name,
|
arg.Name,
|
||||||
arg.CountryCode,
|
arg.CountryCode,
|
||||||
arg.Bet365ID,
|
arg.Bet365ID,
|
||||||
arg.IsActive,
|
|
||||||
arg.IsFeatured,
|
|
||||||
arg.SportID,
|
arg.SportID,
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const UpdateLeagueByBet365ID = `-- name: UpdateLeagueByBet365ID :exec
|
const UpdateLeagueSettings = `-- name: UpdateLeagueSettings :exec
|
||||||
UPDATE leagues
|
UPDATE company_league_settings
|
||||||
SET name = COALESCE($2, name),
|
SET is_active = COALESCE($3, is_active),
|
||||||
id = COALESCE($3, id),
|
is_featured = COALESCE(
|
||||||
country_code = COALESCE($4, country_code),
|
$4,
|
||||||
is_active = COALESCE($5, is_active),
|
is_featured
|
||||||
is_featured = COALESCE($6, is_featured),
|
)
|
||||||
sport_id = COALESCE($7, sport_id)
|
WHERE league_id = $1
|
||||||
WHERE bet365_id = $1
|
AND company_id = $2
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateLeagueByBet365IDParams struct {
|
type UpdateLeagueSettingsParams struct {
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
LeagueID int64 `json:"league_id"`
|
||||||
Name pgtype.Text `json:"name"`
|
CompanyID int64 `json:"company_id"`
|
||||||
ID pgtype.Int8 `json:"id"`
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
|
||||||
SportID pgtype.Int4 `json:"sport_id"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) UpdateLeagueByBet365ID(ctx context.Context, arg UpdateLeagueByBet365IDParams) error {
|
func (q *Queries) UpdateLeagueSettings(ctx context.Context, arg UpdateLeagueSettingsParams) error {
|
||||||
_, err := q.db.Exec(ctx, UpdateLeagueByBet365ID,
|
_, err := q.db.Exec(ctx, UpdateLeagueSettings,
|
||||||
arg.Bet365ID,
|
arg.LeagueID,
|
||||||
arg.Name,
|
arg.CompanyID,
|
||||||
arg.ID,
|
|
||||||
arg.CountryCode,
|
|
||||||
arg.IsActive,
|
arg.IsActive,
|
||||||
arg.IsFeatured,
|
arg.IsFeatured,
|
||||||
arg.SportID,
|
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
325
gen/db/models.go
325
gen/db/models.go
|
|
@ -75,6 +75,7 @@ type Bank struct {
|
||||||
|
|
||||||
type Bet struct {
|
type Bet struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
|
|
@ -108,6 +109,7 @@ type BetOutcome struct {
|
||||||
|
|
||||||
type BetWithOutcome struct {
|
type BetWithOutcome struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
|
|
@ -125,8 +127,8 @@ type BetWithOutcome struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bonu struct {
|
type Bonu struct {
|
||||||
ID int64 `json:"id"`
|
|
||||||
Multiplier float32 `json:"multiplier"`
|
Multiplier float32 `json:"multiplier"`
|
||||||
|
ID int64 `json:"id"`
|
||||||
BalanceCap int64 `json:"balance_cap"`
|
BalanceCap int64 `json:"balance_cap"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,6 +186,7 @@ type BranchOperation struct {
|
||||||
type CompaniesDetail struct {
|
type CompaniesDetail struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
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"`
|
||||||
|
|
@ -200,6 +203,7 @@ type CompaniesDetail struct {
|
||||||
type Company struct {
|
type Company struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
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"`
|
||||||
|
|
@ -208,6 +212,42 @@ type Company struct {
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CompanyEventSetting struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
|
WinningUpperLimit pgtype.Int4 `json:"winning_upper_limit"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompanyLeagueSetting struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
LeagueID int64 `json:"league_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
IsFeatured pgtype.Bool `json:"is_featured"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompanyOddSetting struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
CustomRawOdds []byte `json:"custom_raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompanySetting struct {
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type CustomerWallet struct {
|
type CustomerWallet struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
CustomerID int64 `json:"customer_id"`
|
CustomerID int64 `json:"customer_id"`
|
||||||
|
|
@ -248,31 +288,111 @@ type DirectDeposit struct {
|
||||||
VerifiedAt pgtype.Timestamp `json:"verified_at"`
|
VerifiedAt pgtype.Timestamp `json:"verified_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DisabledOdd struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
RawOddID int64 `json:"raw_odd_id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
SportID pgtype.Int4 `json:"sport_id"`
|
SportID int32 `json:"sport_id"`
|
||||||
MatchName pgtype.Text `json:"match_name"`
|
MatchName string `json:"match_name"`
|
||||||
HomeTeam pgtype.Text `json:"home_team"`
|
HomeTeam string `json:"home_team"`
|
||||||
AwayTeam pgtype.Text `json:"away_team"`
|
AwayTeam string `json:"away_team"`
|
||||||
HomeTeamID pgtype.Int4 `json:"home_team_id"`
|
HomeTeamID int64 `json:"home_team_id"`
|
||||||
AwayTeamID pgtype.Int4 `json:"away_team_id"`
|
AwayTeamID int64 `json:"away_team_id"`
|
||||||
HomeKitImage pgtype.Text `json:"home_kit_image"`
|
HomeKitImage string `json:"home_kit_image"`
|
||||||
AwayKitImage pgtype.Text `json:"away_kit_image"`
|
AwayKitImage string `json:"away_kit_image"`
|
||||||
LeagueID pgtype.Int4 `json:"league_id"`
|
LeagueID int64 `json:"league_id"`
|
||||||
LeagueName pgtype.Text `json:"league_name"`
|
LeagueName string `json:"league_name"`
|
||||||
LeagueCc pgtype.Text `json:"league_cc"`
|
StartTime pgtype.Timestamp `json:"start_time"`
|
||||||
StartTime pgtype.Timestamp `json:"start_time"`
|
Score pgtype.Text `json:"score"`
|
||||||
Score pgtype.Text `json:"score"`
|
MatchMinute pgtype.Int4 `json:"match_minute"`
|
||||||
MatchMinute pgtype.Int4 `json:"match_minute"`
|
TimerStatus pgtype.Text `json:"timer_status"`
|
||||||
TimerStatus pgtype.Text `json:"timer_status"`
|
AddedTime pgtype.Int4 `json:"added_time"`
|
||||||
AddedTime pgtype.Int4 `json:"added_time"`
|
MatchPeriod pgtype.Int4 `json:"match_period"`
|
||||||
MatchPeriod pgtype.Int4 `json:"match_period"`
|
IsLive bool `json:"is_live"`
|
||||||
IsLive pgtype.Bool `json:"is_live"`
|
Status string `json:"status"`
|
||||||
Status pgtype.Text `json:"status"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
Source string `json:"source"`
|
||||||
Source pgtype.Text `json:"source"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
IsActive bool `json:"is_active"`
|
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||||
|
IsMonitored bool `json:"is_monitored"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventHistory struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventWithCountry 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 int32 `json:"default_winning_upper_limit"`
|
||||||
|
IsMonitored bool `json:"is_monitored"`
|
||||||
|
LeagueCc pgtype.Text `json:"league_cc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventWithSetting 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 int32 `json:"default_winning_upper_limit"`
|
||||||
|
IsMonitored bool `json:"is_monitored"`
|
||||||
|
CompanyID int64 `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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExchangeRate struct {
|
type ExchangeRate struct {
|
||||||
|
|
@ -292,23 +412,45 @@ type FavoriteGame struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Flag struct {
|
type Flag struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
BetID pgtype.Int8 `json:"bet_id"`
|
BetID pgtype.Int8 `json:"bet_id"`
|
||||||
OddID pgtype.Int8 `json:"odd_id"`
|
OddsMarketID pgtype.Int8 `json:"odds_market_id"`
|
||||||
Reason pgtype.Text `json:"reason"`
|
Reason pgtype.Text `json:"reason"`
|
||||||
FlaggedAt pgtype.Timestamp `json:"flagged_at"`
|
FlaggedAt pgtype.Timestamp `json:"flagged_at"`
|
||||||
Resolved pgtype.Bool `json:"resolved"`
|
Resolved pgtype.Bool `json:"resolved"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GlobalSetting struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type League struct {
|
type League struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Img pgtype.Text `json:"img"`
|
ImgUrl pgtype.Text `json:"img_url"`
|
||||||
CountryCode pgtype.Text `json:"country_code"`
|
CountryCode pgtype.Text `json:"country_code"`
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
||||||
SportID int32 `json:"sport_id"`
|
SportID int32 `json:"sport_id"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
IsFeatured pgtype.Bool `json:"is_featured"`
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LeagueWithSetting 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 int64 `json:"company_id"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
IsFeatured bool `json:"is_featured"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
|
|
@ -328,23 +470,60 @@ type Notification struct {
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Odd struct {
|
type OddHistory struct {
|
||||||
ID int32 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
EventID pgtype.Text `json:"event_id"`
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
Fi pgtype.Text `json:"fi"`
|
RawOddID int64 `json:"raw_odd_id"`
|
||||||
MarketType string `json:"market_type"`
|
MarketID string `json:"market_id"`
|
||||||
MarketName pgtype.Text `json:"market_name"`
|
EventID string `json:"event_id"`
|
||||||
MarketCategory pgtype.Text `json:"market_category"`
|
OddValue float64 `json:"odd_value"`
|
||||||
MarketID pgtype.Text `json:"market_id"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
Name pgtype.Text `json:"name"`
|
}
|
||||||
Handicap pgtype.Text `json:"handicap"`
|
|
||||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
type OddsMarket struct {
|
||||||
Section string `json:"section"`
|
ID int64 `json:"id"`
|
||||||
Category pgtype.Text `json:"category"`
|
EventID string `json:"event_id"`
|
||||||
RawOdds []byte `json:"raw_odds"`
|
MarketType string `json:"market_type"`
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
MarketName string `json:"market_name"`
|
||||||
Source pgtype.Text `json:"source"`
|
MarketCategory string `json:"market_category"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
MarketID string `json:"market_id"`
|
||||||
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OddsMarketWithEvent 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"`
|
||||||
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
|
IsMonitored bool `json:"is_monitored"`
|
||||||
|
IsLive bool `json:"is_live"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OddsMarketWithSetting 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 int64 `json:"company_id"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
RawOdds []byte `json:"raw_odds"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Otp struct {
|
type Otp struct {
|
||||||
|
|
@ -422,11 +601,21 @@ type Result struct {
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Setting struct {
|
type ResultLog struct {
|
||||||
Key string `json:"key"`
|
ID int64 `json:"id"`
|
||||||
Value string `json:"value"`
|
StatusNotFinishedCount int32 `json:"status_not_finished_count"`
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
StatusNotFinishedBets int32 `json:"status_not_finished_bets"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
StatusToBeFixedCount int32 `json:"status_to_be_fixed_count"`
|
||||||
|
StatusToBeFixedBets int32 `json:"status_to_be_fixed_bets"`
|
||||||
|
StatusPostponedCount int32 `json:"status_postponed_count"`
|
||||||
|
StatusPostponedBets int32 `json:"status_postponed_bets"`
|
||||||
|
StatusEndedCount int32 `json:"status_ended_count"`
|
||||||
|
StatusEndedBets int32 `json:"status_ended_bets"`
|
||||||
|
StatusRemovedCount int32 `json:"status_removed_count"`
|
||||||
|
StatusRemovedBets int32 `json:"status_removed_bets"`
|
||||||
|
RemovedCount int32 `json:"removed_count"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShopBet struct {
|
type ShopBet struct {
|
||||||
|
|
@ -545,15 +734,16 @@ type SupportedOperation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Team struct {
|
type Team struct {
|
||||||
ID string `json:"id"`
|
ID int64 `json:"id"`
|
||||||
TeamName string `json:"team_name"`
|
TeamName string `json:"team_name"`
|
||||||
Country pgtype.Text `json:"country"`
|
CountryCode string `json:"country_code"`
|
||||||
Bet365ID pgtype.Int4 `json:"bet365_id"`
|
Bet365ID pgtype.Int8 `json:"bet365_id"`
|
||||||
LogoUrl pgtype.Text `json:"logo_url"`
|
ImgUrl pgtype.Text `json:"img_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
|
|
@ -580,6 +770,7 @@ type TicketOutcome struct {
|
||||||
|
|
||||||
type TicketWithOutcome struct {
|
type TicketWithOutcome struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
|
|
@ -695,6 +886,7 @@ type VirtualGameTransaction struct {
|
||||||
type Wallet struct {
|
type Wallet struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Balance int64 `json:"balance"`
|
Balance int64 `json:"balance"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
IsWithdraw bool `json:"is_withdraw"`
|
IsWithdraw bool `json:"is_withdraw"`
|
||||||
IsBettable bool `json:"is_bettable"`
|
IsBettable bool `json:"is_bettable"`
|
||||||
IsTransferable bool `json:"is_transferable"`
|
IsTransferable bool `json:"is_transferable"`
|
||||||
|
|
@ -703,7 +895,6 @@ type Wallet struct {
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
Currency string `json:"currency"`
|
|
||||||
BonusBalance pgtype.Numeric `json:"bonus_balance"`
|
BonusBalance pgtype.Numeric `json:"bonus_balance"`
|
||||||
CashBalance pgtype.Numeric `json:"cash_balance"`
|
CashBalance pgtype.Numeric `json:"cash_balance"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
203
gen/db/odd_history.sql.go
Normal file
203
gen/db/odd_history.sql.go
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.29.0
|
||||||
|
// source: odd_history.sql
|
||||||
|
|
||||||
|
package dbgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const GetAllOddHistory = `-- name: GetAllOddHistory :many
|
||||||
|
SELECT id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||||
|
FROM odd_history
|
||||||
|
WHERE (
|
||||||
|
odds_market_id = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
market_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
raw_odd_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
event_id = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $6
|
||||||
|
OR $6 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllOddHistoryParams struct {
|
||||||
|
OddID pgtype.Int8 `json:"odd_id"`
|
||||||
|
MarketID pgtype.Text `json:"market_id"`
|
||||||
|
RawOddID pgtype.Int8 `json:"raw_odd_id"`
|
||||||
|
EventID pgtype.Text `json:"event_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllOddHistory(ctx context.Context, arg GetAllOddHistoryParams) ([]OddHistory, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllOddHistory,
|
||||||
|
arg.OddID,
|
||||||
|
arg.MarketID,
|
||||||
|
arg.RawOddID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []OddHistory
|
||||||
|
for rows.Next() {
|
||||||
|
var i OddHistory
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.OddValue,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetInitialOddPerDay = `-- name: GetInitialOddPerDay :many
|
||||||
|
SELECT DISTINCT ON (DATE_TRUNC($1, created_at)) id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||||
|
FROM odd_history
|
||||||
|
WHERE (
|
||||||
|
odds_market_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
market_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
raw_odd_id = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
event_id = $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $6
|
||||||
|
OR $6 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $7
|
||||||
|
OR $7 IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY DATE_TRUNC($1, created_at),
|
||||||
|
created_at ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetInitialOddPerDayParams struct {
|
||||||
|
DateTrunc string `json:"date_trunc"`
|
||||||
|
OddID pgtype.Int8 `json:"odd_id"`
|
||||||
|
MarketID pgtype.Text `json:"market_id"`
|
||||||
|
RawOddID pgtype.Int8 `json:"raw_odd_id"`
|
||||||
|
EventID pgtype.Text `json:"event_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetInitialOddPerDay(ctx context.Context, arg GetInitialOddPerDayParams) ([]OddHistory, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetInitialOddPerDay,
|
||||||
|
arg.DateTrunc,
|
||||||
|
arg.OddID,
|
||||||
|
arg.MarketID,
|
||||||
|
arg.RawOddID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []OddHistory
|
||||||
|
for rows.Next() {
|
||||||
|
var i OddHistory
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.OddValue,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertOddHistory = `-- name: InsertOddHistory :one
|
||||||
|
INSERT INTO odd_history (
|
||||||
|
odds_market_id,
|
||||||
|
market_id,
|
||||||
|
raw_odd_id,
|
||||||
|
event_id,
|
||||||
|
odd_value
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
RETURNING id, odds_market_id, raw_odd_id, market_id, event_id, odd_value, created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertOddHistoryParams struct {
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
MarketID string `json:"market_id"`
|
||||||
|
RawOddID int64 `json:"raw_odd_id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
OddValue float64 `json:"odd_value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) InsertOddHistory(ctx context.Context, arg InsertOddHistoryParams) (OddHistory, error) {
|
||||||
|
row := q.db.QueryRow(ctx, InsertOddHistory,
|
||||||
|
arg.OddsMarketID,
|
||||||
|
arg.MarketID,
|
||||||
|
arg.RawOddID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.OddValue,
|
||||||
|
)
|
||||||
|
var i OddHistory
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.OddsMarketID,
|
||||||
|
&i.RawOddID,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.OddValue,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
@ -12,134 +12,50 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const DeleteOddsForEvent = `-- name: DeleteOddsForEvent :exec
|
const DeleteOddsForEvent = `-- name: DeleteOddsForEvent :exec
|
||||||
DELETE FROM odds
|
DELETE FROM odds_market
|
||||||
Where fi = $1
|
Where event_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) DeleteOddsForEvent(ctx context.Context, fi pgtype.Text) error {
|
func (q *Queries) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||||
_, err := q.db.Exec(ctx, DeleteOddsForEvent, fi)
|
_, err := q.db.Exec(ctx, DeleteOddsForEvent, eventID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetALLPrematchOdds = `-- name: GetALLPrematchOdds :many
|
const GetAllOdds = `-- name: GetAllOdds :many
|
||||||
SELECT event_id,
|
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
|
||||||
fi,
|
FROM odds_market_with_event
|
||||||
market_type,
|
LIMIT $2 OFFSET $1
|
||||||
market_name,
|
|
||||||
market_category,
|
|
||||||
market_id,
|
|
||||||
name,
|
|
||||||
handicap,
|
|
||||||
odds_value,
|
|
||||||
section,
|
|
||||||
category,
|
|
||||||
raw_odds,
|
|
||||||
fetched_at,
|
|
||||||
source,
|
|
||||||
is_active
|
|
||||||
FROM odds
|
|
||||||
WHERE is_active = true
|
|
||||||
AND source = 'bet365'
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetALLPrematchOddsRow struct {
|
type GetAllOddsParams struct {
|
||||||
EventID pgtype.Text `json:"event_id"`
|
|
||||||
Fi pgtype.Text `json:"fi"`
|
|
||||||
MarketType string `json:"market_type"`
|
|
||||||
MarketName pgtype.Text `json:"market_name"`
|
|
||||||
MarketCategory pgtype.Text `json:"market_category"`
|
|
||||||
MarketID pgtype.Text `json:"market_id"`
|
|
||||||
Name pgtype.Text `json:"name"`
|
|
||||||
Handicap pgtype.Text `json:"handicap"`
|
|
||||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
|
||||||
Section string `json:"section"`
|
|
||||||
Category pgtype.Text `json:"category"`
|
|
||||||
RawOdds []byte `json:"raw_odds"`
|
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
|
||||||
Source pgtype.Text `json:"source"`
|
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetALLPrematchOdds(ctx context.Context) ([]GetALLPrematchOddsRow, error) {
|
|
||||||
rows, err := q.db.Query(ctx, GetALLPrematchOdds)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
var items []GetALLPrematchOddsRow
|
|
||||||
for rows.Next() {
|
|
||||||
var i GetALLPrematchOddsRow
|
|
||||||
if err := rows.Scan(
|
|
||||||
&i.EventID,
|
|
||||||
&i.Fi,
|
|
||||||
&i.MarketType,
|
|
||||||
&i.MarketName,
|
|
||||||
&i.MarketCategory,
|
|
||||||
&i.MarketID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Handicap,
|
|
||||||
&i.OddsValue,
|
|
||||||
&i.Section,
|
|
||||||
&i.Category,
|
|
||||||
&i.RawOdds,
|
|
||||||
&i.FetchedAt,
|
|
||||||
&i.Source,
|
|
||||||
&i.IsActive,
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
items = append(items, i)
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return items, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const GetPaginatedPrematchOddsByUpcomingID = `-- name: GetPaginatedPrematchOddsByUpcomingID :many
|
|
||||||
SELECT o.id, o.event_id, o.fi, o.market_type, o.market_name, o.market_category, o.market_id, o.name, o.handicap, o.odds_value, o.section, o.category, o.raw_odds, o.fetched_at, o.source, o.is_active
|
|
||||||
FROM odds o
|
|
||||||
JOIN events e ON o.fi = e.id
|
|
||||||
WHERE e.id = $1
|
|
||||||
AND e.is_live = false
|
|
||||||
AND e.status = 'upcoming'
|
|
||||||
AND o.is_active = true
|
|
||||||
AND o.source = 'bet365'
|
|
||||||
LIMIT $3 OFFSET $2
|
|
||||||
`
|
|
||||||
|
|
||||||
type GetPaginatedPrematchOddsByUpcomingIDParams struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Offset pgtype.Int4 `json:"offset"`
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
Limit pgtype.Int4 `json:"limit"`
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, arg GetPaginatedPrematchOddsByUpcomingIDParams) ([]Odd, error) {
|
func (q *Queries) GetAllOdds(ctx context.Context, arg GetAllOddsParams) ([]OddsMarketWithEvent, error) {
|
||||||
rows, err := q.db.Query(ctx, GetPaginatedPrematchOddsByUpcomingID, arg.ID, arg.Offset, arg.Limit)
|
rows, err := q.db.Query(ctx, GetAllOdds, arg.Offset, arg.Limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []Odd
|
var items []OddsMarketWithEvent
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i Odd
|
var i OddsMarketWithEvent
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.EventID,
|
&i.EventID,
|
||||||
&i.Fi,
|
|
||||||
&i.MarketType,
|
&i.MarketType,
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.Name,
|
|
||||||
&i.Handicap,
|
|
||||||
&i.OddsValue,
|
|
||||||
&i.Section,
|
|
||||||
&i.Category,
|
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.ExpiresAt,
|
||||||
|
&i.IsMonitored,
|
||||||
|
&i.IsLive,
|
||||||
|
&i.Status,
|
||||||
&i.Source,
|
&i.Source,
|
||||||
&i.IsActive,
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -151,118 +67,42 @@ func (q *Queries) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, arg
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetPrematchOdds = `-- name: GetPrematchOdds :many
|
const GetAllOddsWithSettings = `-- name: GetAllOddsWithSettings :many
|
||||||
SELECT event_id,
|
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
|
||||||
fi,
|
FROM odds_market_with_settings
|
||||||
market_type,
|
WHERE company_id = $1
|
||||||
market_name,
|
LIMIT $3 OFFSET $2
|
||||||
market_category,
|
|
||||||
market_id,
|
|
||||||
name,
|
|
||||||
handicap,
|
|
||||||
odds_value,
|
|
||||||
section,
|
|
||||||
category,
|
|
||||||
raw_odds,
|
|
||||||
fetched_at,
|
|
||||||
source,
|
|
||||||
is_active
|
|
||||||
FROM odds
|
|
||||||
WHERE is_active = true
|
|
||||||
AND source = 'bet365'
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetPrematchOddsRow struct {
|
type GetAllOddsWithSettingsParams struct {
|
||||||
EventID pgtype.Text `json:"event_id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
Fi pgtype.Text `json:"fi"`
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
MarketType string `json:"market_type"`
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
MarketName pgtype.Text `json:"market_name"`
|
|
||||||
MarketCategory pgtype.Text `json:"market_category"`
|
|
||||||
MarketID pgtype.Text `json:"market_id"`
|
|
||||||
Name pgtype.Text `json:"name"`
|
|
||||||
Handicap pgtype.Text `json:"handicap"`
|
|
||||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
|
||||||
Section string `json:"section"`
|
|
||||||
Category pgtype.Text `json:"category"`
|
|
||||||
RawOdds []byte `json:"raw_odds"`
|
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
|
||||||
Source pgtype.Text `json:"source"`
|
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetPrematchOdds(ctx context.Context) ([]GetPrematchOddsRow, error) {
|
func (q *Queries) GetAllOddsWithSettings(ctx context.Context, arg GetAllOddsWithSettingsParams) ([]OddsMarketWithSetting, error) {
|
||||||
rows, err := q.db.Query(ctx, GetPrematchOdds)
|
rows, err := q.db.Query(ctx, GetAllOddsWithSettings, arg.CompanyID, arg.Offset, arg.Limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []GetPrematchOddsRow
|
var items []OddsMarketWithSetting
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i GetPrematchOddsRow
|
var i OddsMarketWithSetting
|
||||||
if err := rows.Scan(
|
|
||||||
&i.EventID,
|
|
||||||
&i.Fi,
|
|
||||||
&i.MarketType,
|
|
||||||
&i.MarketName,
|
|
||||||
&i.MarketCategory,
|
|
||||||
&i.MarketID,
|
|
||||||
&i.Name,
|
|
||||||
&i.Handicap,
|
|
||||||
&i.OddsValue,
|
|
||||||
&i.Section,
|
|
||||||
&i.Category,
|
|
||||||
&i.RawOdds,
|
|
||||||
&i.FetchedAt,
|
|
||||||
&i.Source,
|
|
||||||
&i.IsActive,
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
items = append(items, i)
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return items, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const GetPrematchOddsByUpcomingID = `-- name: GetPrematchOddsByUpcomingID :many
|
|
||||||
SELECT o.id, o.event_id, o.fi, o.market_type, o.market_name, o.market_category, o.market_id, o.name, o.handicap, o.odds_value, o.section, o.category, o.raw_odds, o.fetched_at, o.source, o.is_active
|
|
||||||
FROM odds o
|
|
||||||
JOIN events e ON o.fi = e.id
|
|
||||||
WHERE e.id = $1
|
|
||||||
AND e.is_live = false
|
|
||||||
AND e.status = 'upcoming'
|
|
||||||
AND o.is_active = true
|
|
||||||
AND o.source = 'bet365'
|
|
||||||
`
|
|
||||||
|
|
||||||
func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, id string) ([]Odd, error) {
|
|
||||||
rows, err := q.db.Query(ctx, GetPrematchOddsByUpcomingID, id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
var items []Odd
|
|
||||||
for rows.Next() {
|
|
||||||
var i Odd
|
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.EventID,
|
&i.EventID,
|
||||||
&i.Fi,
|
|
||||||
&i.MarketType,
|
&i.MarketType,
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.MarketCategory,
|
&i.MarketCategory,
|
||||||
&i.MarketID,
|
&i.MarketID,
|
||||||
&i.Name,
|
&i.DefaultIsActive,
|
||||||
&i.Handicap,
|
|
||||||
&i.OddsValue,
|
|
||||||
&i.Section,
|
|
||||||
&i.Category,
|
|
||||||
&i.RawOdds,
|
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
&i.Source,
|
&i.ExpiresAt,
|
||||||
|
&i.CompanyID,
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
|
&i.RawOdds,
|
||||||
|
&i.UpdatedAt,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -274,62 +114,239 @@ func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, id string) ([
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetRawOddsByMarketID = `-- name: GetRawOddsByMarketID :one
|
const GetOddsByEventID = `-- name: GetOddsByEventID :many
|
||||||
SELECT id,
|
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
|
||||||
market_name,
|
FROM odds_market_with_event
|
||||||
handicap,
|
WHERE event_id = $1
|
||||||
raw_odds,
|
AND (
|
||||||
fetched_at
|
is_live = $2
|
||||||
FROM odds
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
status = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
source = $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
LIMIT $6 OFFSET $5
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetOddsByEventIDParams struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
IsLive pgtype.Bool `json:"is_live"`
|
||||||
|
Status pgtype.Text `json:"status"`
|
||||||
|
Source pgtype.Text `json:"source"`
|
||||||
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetOddsByEventID(ctx context.Context, arg GetOddsByEventIDParams) ([]OddsMarketWithEvent, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetOddsByEventID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.IsLive,
|
||||||
|
arg.Status,
|
||||||
|
arg.Source,
|
||||||
|
arg.Offset,
|
||||||
|
arg.Limit,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []OddsMarketWithEvent
|
||||||
|
for rows.Next() {
|
||||||
|
var i OddsMarketWithEvent
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.MarketType,
|
||||||
|
&i.MarketName,
|
||||||
|
&i.MarketCategory,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.RawOdds,
|
||||||
|
&i.DefaultIsActive,
|
||||||
|
&i.FetchedAt,
|
||||||
|
&i.ExpiresAt,
|
||||||
|
&i.IsMonitored,
|
||||||
|
&i.IsLive,
|
||||||
|
&i.Status,
|
||||||
|
&i.Source,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
FROM odds_market_with_event
|
||||||
WHERE market_id = $1
|
WHERE market_id = $1
|
||||||
AND fi = $2
|
AND event_id = $2
|
||||||
AND is_active = true
|
|
||||||
AND source = 'bet365'
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetRawOddsByMarketIDParams struct {
|
type GetOddsByMarketIDParams struct {
|
||||||
MarketID pgtype.Text `json:"market_id"`
|
MarketID string `json:"market_id"`
|
||||||
Fi pgtype.Text `json:"fi"`
|
EventID string `json:"event_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetRawOddsByMarketIDRow struct {
|
func (q *Queries) GetOddsByMarketID(ctx context.Context, arg GetOddsByMarketIDParams) (OddsMarketWithEvent, error) {
|
||||||
ID int32 `json:"id"`
|
row := q.db.QueryRow(ctx, GetOddsByMarketID, arg.MarketID, arg.EventID)
|
||||||
MarketName pgtype.Text `json:"market_name"`
|
var i OddsMarketWithEvent
|
||||||
Handicap pgtype.Text `json:"handicap"`
|
|
||||||
RawOdds []byte `json:"raw_odds"`
|
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetRawOddsByMarketID(ctx context.Context, arg GetRawOddsByMarketIDParams) (GetRawOddsByMarketIDRow, error) {
|
|
||||||
row := q.db.QueryRow(ctx, GetRawOddsByMarketID, arg.MarketID, arg.Fi)
|
|
||||||
var i GetRawOddsByMarketIDRow
|
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.MarketType,
|
||||||
&i.MarketName,
|
&i.MarketName,
|
||||||
&i.Handicap,
|
&i.MarketCategory,
|
||||||
|
&i.MarketID,
|
||||||
&i.RawOdds,
|
&i.RawOdds,
|
||||||
|
&i.DefaultIsActive,
|
||||||
&i.FetchedAt,
|
&i.FetchedAt,
|
||||||
|
&i.ExpiresAt,
|
||||||
|
&i.IsMonitored,
|
||||||
|
&i.IsLive,
|
||||||
|
&i.Status,
|
||||||
|
&i.Source,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const InsertNonLiveOdd = `-- name: InsertNonLiveOdd :exec
|
const GetOddsWithSettingsByEventID = `-- name: GetOddsWithSettingsByEventID :many
|
||||||
INSERT INTO odds (
|
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
|
||||||
|
AND company_id = $2
|
||||||
|
LIMIT $4 OFFSET $3
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetOddsWithSettingsByEventIDParams struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Offset pgtype.Int4 `json:"offset"`
|
||||||
|
Limit pgtype.Int4 `json:"limit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetOddsWithSettingsByEventID(ctx context.Context, arg GetOddsWithSettingsByEventIDParams) ([]OddsMarketWithSetting, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetOddsWithSettingsByEventID,
|
||||||
|
arg.EventID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.Offset,
|
||||||
|
arg.Limit,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []OddsMarketWithSetting
|
||||||
|
for rows.Next() {
|
||||||
|
var i OddsMarketWithSetting
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.MarketType,
|
||||||
|
&i.MarketName,
|
||||||
|
&i.MarketCategory,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.DefaultIsActive,
|
||||||
|
&i.FetchedAt,
|
||||||
|
&i.ExpiresAt,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.IsActive,
|
||||||
|
&i.RawOdds,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
WHERE market_id = $1
|
||||||
|
AND event_id = $2
|
||||||
|
AND company_id = $3
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetOddsWithSettingsByMarketIDParams struct {
|
||||||
|
MarketID string `json:"market_id"`
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetOddsWithSettingsByMarketID(ctx context.Context, arg GetOddsWithSettingsByMarketIDParams) (OddsMarketWithSetting, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetOddsWithSettingsByMarketID, arg.MarketID, arg.EventID, arg.CompanyID)
|
||||||
|
var i OddsMarketWithSetting
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.EventID,
|
||||||
|
&i.MarketType,
|
||||||
|
&i.MarketName,
|
||||||
|
&i.MarketCategory,
|
||||||
|
&i.MarketID,
|
||||||
|
&i.DefaultIsActive,
|
||||||
|
&i.FetchedAt,
|
||||||
|
&i.ExpiresAt,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.IsActive,
|
||||||
|
&i.RawOdds,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertOddSettings = `-- name: InsertOddSettings :exec
|
||||||
|
INSERT INTO company_odd_settings (
|
||||||
|
company_id,
|
||||||
|
odds_market_id,
|
||||||
|
is_active,
|
||||||
|
custom_raw_odds
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4) ON CONFLICT (company_id, odds_market_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET is_active = EXCLUDED.is_active,
|
||||||
|
custom_raw_odds = EXCLUDED.custom_raw_odds
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertOddSettingsParams struct {
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
OddsMarketID int64 `json:"odds_market_id"`
|
||||||
|
IsActive pgtype.Bool `json:"is_active"`
|
||||||
|
CustomRawOdds []byte `json:"custom_raw_odds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) InsertOddSettings(ctx context.Context, arg InsertOddSettingsParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, InsertOddSettings,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.OddsMarketID,
|
||||||
|
arg.IsActive,
|
||||||
|
arg.CustomRawOdds,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertOddsMarket = `-- name: InsertOddsMarket :exec
|
||||||
|
INSERT INTO odds_market (
|
||||||
event_id,
|
event_id,
|
||||||
fi,
|
|
||||||
market_type,
|
market_type,
|
||||||
market_name,
|
market_name,
|
||||||
market_category,
|
market_category,
|
||||||
market_id,
|
market_id,
|
||||||
name,
|
|
||||||
handicap,
|
|
||||||
odds_value,
|
|
||||||
section,
|
|
||||||
category,
|
|
||||||
raw_odds,
|
raw_odds,
|
||||||
is_active,
|
fetched_at,
|
||||||
source,
|
expires_at
|
||||||
fetched_at
|
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
$1,
|
$1,
|
||||||
|
|
@ -339,64 +356,38 @@ VALUES (
|
||||||
$5,
|
$5,
|
||||||
$6,
|
$6,
|
||||||
$7,
|
$7,
|
||||||
$8,
|
$8
|
||||||
$9,
|
|
||||||
$10,
|
|
||||||
$11,
|
|
||||||
$12,
|
|
||||||
$13,
|
|
||||||
$14,
|
|
||||||
$15
|
|
||||||
) ON CONFLICT (event_id, market_id) DO
|
) ON CONFLICT (event_id, market_id) DO
|
||||||
UPDATE
|
UPDATE
|
||||||
SET odds_value = EXCLUDED.odds_value,
|
SET market_type = EXCLUDED.market_type,
|
||||||
raw_odds = EXCLUDED.raw_odds,
|
|
||||||
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,
|
||||||
name = EXCLUDED.name,
|
raw_odds = EXCLUDED.raw_odds,
|
||||||
handicap = EXCLUDED.handicap,
|
|
||||||
fetched_at = EXCLUDED.fetched_at,
|
fetched_at = EXCLUDED.fetched_at,
|
||||||
is_active = EXCLUDED.is_active,
|
expires_at = EXCLUDED.expires_at
|
||||||
source = EXCLUDED.source,
|
|
||||||
fi = EXCLUDED.fi
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type InsertNonLiveOddParams struct {
|
type InsertOddsMarketParams struct {
|
||||||
EventID pgtype.Text `json:"event_id"`
|
EventID string `json:"event_id"`
|
||||||
Fi pgtype.Text `json:"fi"`
|
|
||||||
MarketType string `json:"market_type"`
|
MarketType string `json:"market_type"`
|
||||||
MarketName pgtype.Text `json:"market_name"`
|
MarketName string `json:"market_name"`
|
||||||
MarketCategory pgtype.Text `json:"market_category"`
|
MarketCategory string `json:"market_category"`
|
||||||
MarketID pgtype.Text `json:"market_id"`
|
MarketID string `json:"market_id"`
|
||||||
Name pgtype.Text `json:"name"`
|
|
||||||
Handicap pgtype.Text `json:"handicap"`
|
|
||||||
OddsValue pgtype.Float8 `json:"odds_value"`
|
|
||||||
Section string `json:"section"`
|
|
||||||
Category pgtype.Text `json:"category"`
|
|
||||||
RawOdds []byte `json:"raw_odds"`
|
RawOdds []byte `json:"raw_odds"`
|
||||||
IsActive pgtype.Bool `json:"is_active"`
|
|
||||||
Source pgtype.Text `json:"source"`
|
|
||||||
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
FetchedAt pgtype.Timestamp `json:"fetched_at"`
|
||||||
|
ExpiresAt pgtype.Timestamp `json:"expires_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) InsertNonLiveOdd(ctx context.Context, arg InsertNonLiveOddParams) error {
|
func (q *Queries) InsertOddsMarket(ctx context.Context, arg InsertOddsMarketParams) error {
|
||||||
_, err := q.db.Exec(ctx, InsertNonLiveOdd,
|
_, err := q.db.Exec(ctx, InsertOddsMarket,
|
||||||
arg.EventID,
|
arg.EventID,
|
||||||
arg.Fi,
|
|
||||||
arg.MarketType,
|
arg.MarketType,
|
||||||
arg.MarketName,
|
arg.MarketName,
|
||||||
arg.MarketCategory,
|
arg.MarketCategory,
|
||||||
arg.MarketID,
|
arg.MarketID,
|
||||||
arg.Name,
|
|
||||||
arg.Handicap,
|
|
||||||
arg.OddsValue,
|
|
||||||
arg.Section,
|
|
||||||
arg.Category,
|
|
||||||
arg.RawOdds,
|
arg.RawOdds,
|
||||||
arg.IsActive,
|
|
||||||
arg.Source,
|
|
||||||
arg.FetchedAt,
|
arg.FetchedAt,
|
||||||
|
arg.ExpiresAt,
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
132
gen/db/result_log.sql.go
Normal file
132
gen/db/result_log.sql.go
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.29.0
|
||||||
|
// source: result_log.sql
|
||||||
|
|
||||||
|
package dbgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CreateResultLog = `-- name: CreateResultLog :one
|
||||||
|
INSERT INTO result_log (
|
||||||
|
status_not_finished_count,
|
||||||
|
status_not_finished_bets,
|
||||||
|
status_to_be_fixed_count,
|
||||||
|
status_to_be_fixed_bets,
|
||||||
|
status_postponed_count,
|
||||||
|
status_postponed_bets,
|
||||||
|
status_ended_count,
|
||||||
|
status_ended_bets,
|
||||||
|
status_removed_count,
|
||||||
|
status_removed_bets,
|
||||||
|
removed_count
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
|
RETURNING id, status_not_finished_count, status_not_finished_bets, status_to_be_fixed_count, status_to_be_fixed_bets, status_postponed_count, status_postponed_bets, status_ended_count, status_ended_bets, status_removed_count, status_removed_bets, removed_count, created_at, updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateResultLogParams struct {
|
||||||
|
StatusNotFinishedCount int32 `json:"status_not_finished_count"`
|
||||||
|
StatusNotFinishedBets int32 `json:"status_not_finished_bets"`
|
||||||
|
StatusToBeFixedCount int32 `json:"status_to_be_fixed_count"`
|
||||||
|
StatusToBeFixedBets int32 `json:"status_to_be_fixed_bets"`
|
||||||
|
StatusPostponedCount int32 `json:"status_postponed_count"`
|
||||||
|
StatusPostponedBets int32 `json:"status_postponed_bets"`
|
||||||
|
StatusEndedCount int32 `json:"status_ended_count"`
|
||||||
|
StatusEndedBets int32 `json:"status_ended_bets"`
|
||||||
|
StatusRemovedCount int32 `json:"status_removed_count"`
|
||||||
|
StatusRemovedBets int32 `json:"status_removed_bets"`
|
||||||
|
RemovedCount int32 `json:"removed_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateResultLog(ctx context.Context, arg CreateResultLogParams) (ResultLog, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CreateResultLog,
|
||||||
|
arg.StatusNotFinishedCount,
|
||||||
|
arg.StatusNotFinishedBets,
|
||||||
|
arg.StatusToBeFixedCount,
|
||||||
|
arg.StatusToBeFixedBets,
|
||||||
|
arg.StatusPostponedCount,
|
||||||
|
arg.StatusPostponedBets,
|
||||||
|
arg.StatusEndedCount,
|
||||||
|
arg.StatusEndedBets,
|
||||||
|
arg.StatusRemovedCount,
|
||||||
|
arg.StatusRemovedBets,
|
||||||
|
arg.RemovedCount,
|
||||||
|
)
|
||||||
|
var i ResultLog
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.StatusNotFinishedCount,
|
||||||
|
&i.StatusNotFinishedBets,
|
||||||
|
&i.StatusToBeFixedCount,
|
||||||
|
&i.StatusToBeFixedBets,
|
||||||
|
&i.StatusPostponedCount,
|
||||||
|
&i.StatusPostponedBets,
|
||||||
|
&i.StatusEndedCount,
|
||||||
|
&i.StatusEndedBets,
|
||||||
|
&i.StatusRemovedCount,
|
||||||
|
&i.StatusRemovedBets,
|
||||||
|
&i.RemovedCount,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllResultLog = `-- name: GetAllResultLog :many
|
||||||
|
SELECT id, status_not_finished_count, status_not_finished_bets, status_to_be_fixed_count, status_to_be_fixed_bets, status_postponed_count, status_postponed_bets, status_ended_count, status_ended_bets, status_removed_count, status_removed_bets, removed_count, created_at, updated_at
|
||||||
|
FROM result_log
|
||||||
|
WHERE (
|
||||||
|
created_at < $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllResultLogParams struct {
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllResultLog(ctx context.Context, arg GetAllResultLogParams) ([]ResultLog, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllResultLog, arg.CreatedBefore, arg.CreatedAfter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ResultLog
|
||||||
|
for rows.Next() {
|
||||||
|
var i ResultLog
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.StatusNotFinishedCount,
|
||||||
|
&i.StatusNotFinishedBets,
|
||||||
|
&i.StatusToBeFixedCount,
|
||||||
|
&i.StatusToBeFixedBets,
|
||||||
|
&i.StatusPostponedCount,
|
||||||
|
&i.StatusPostponedBets,
|
||||||
|
&i.StatusEndedCount,
|
||||||
|
&i.StatusEndedBets,
|
||||||
|
&i.StatusRemovedCount,
|
||||||
|
&i.StatusRemovedBets,
|
||||||
|
&i.RemovedCount,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
@ -7,17 +7,140 @@ package dbgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
const GetSetting = `-- name: GetSetting :one
|
const DeleteAllCompanySetting = `-- name: DeleteAllCompanySetting :exec
|
||||||
SELECT key, value, created_at, updated_at
|
DELETE FROM company_settings
|
||||||
FROM settings
|
WHERE company_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteAllCompanySetting(ctx context.Context, companyID int64) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteAllCompanySetting, companyID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteCompanySetting = `-- name: DeleteCompanySetting :exec
|
||||||
|
DELETE FROM company_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
AND key = $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type DeleteCompanySettingParams struct {
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) DeleteCompanySetting(ctx context.Context, arg DeleteCompanySettingParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, DeleteCompanySetting, arg.CompanyID, arg.Key)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllCompanySettings = `-- name: GetAllCompanySettings :many
|
||||||
|
SELECT company_id, key, value, created_at, updated_at
|
||||||
|
FROM company_settings
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetAllCompanySettings(ctx context.Context) ([]CompanySetting, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllCompanySettings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []CompanySetting
|
||||||
|
for rows.Next() {
|
||||||
|
var i CompanySetting
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Key,
|
||||||
|
&i.Value,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetCompanySetting = `-- name: GetCompanySetting :many
|
||||||
|
SELECT company_id, key, value, created_at, updated_at
|
||||||
|
FROM company_settings
|
||||||
|
WHERE company_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetCompanySetting(ctx context.Context, companyID int64) ([]CompanySetting, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetCompanySetting, companyID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []CompanySetting
|
||||||
|
for rows.Next() {
|
||||||
|
var i CompanySetting
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Key,
|
||||||
|
&i.Value,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetCompanySettingsByKey = `-- name: GetCompanySettingsByKey :many
|
||||||
|
SELECT company_id, key, value, created_at, updated_at
|
||||||
|
FROM company_settings
|
||||||
WHERE key = $1
|
WHERE key = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetSetting(ctx context.Context, key string) (Setting, error) {
|
func (q *Queries) GetCompanySettingsByKey(ctx context.Context, key string) ([]CompanySetting, error) {
|
||||||
row := q.db.QueryRow(ctx, GetSetting, key)
|
rows, err := q.db.Query(ctx, GetCompanySettingsByKey, key)
|
||||||
var i Setting
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []CompanySetting
|
||||||
|
for rows.Next() {
|
||||||
|
var i CompanySetting
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Key,
|
||||||
|
&i.Value,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetGlobalSetting = `-- name: GetGlobalSetting :one
|
||||||
|
SELECT key, value, created_at, updated_at
|
||||||
|
FROM global_settings
|
||||||
|
WHERE key = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetGlobalSetting(ctx context.Context, key string) (GlobalSetting, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetGlobalSetting, key)
|
||||||
|
var i GlobalSetting
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.Key,
|
&i.Key,
|
||||||
&i.Value,
|
&i.Value,
|
||||||
|
|
@ -27,20 +150,20 @@ func (q *Queries) GetSetting(ctx context.Context, key string) (Setting, error) {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetSettings = `-- name: GetSettings :many
|
const GetGlobalSettings = `-- name: GetGlobalSettings :many
|
||||||
SELECT key, value, created_at, updated_at
|
SELECT key, value, created_at, updated_at
|
||||||
FROM settings
|
FROM global_settings
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetSettings(ctx context.Context) ([]Setting, error) {
|
func (q *Queries) GetGlobalSettings(ctx context.Context) ([]GlobalSetting, error) {
|
||||||
rows, err := q.db.Query(ctx, GetSettings)
|
rows, err := q.db.Query(ctx, GetGlobalSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []Setting
|
var items []GlobalSetting
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i Setting
|
var i GlobalSetting
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.Key,
|
&i.Key,
|
||||||
&i.Value,
|
&i.Value,
|
||||||
|
|
@ -57,27 +180,79 @@ func (q *Queries) GetSettings(ctx context.Context) ([]Setting, error) {
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const SaveSetting = `-- name: SaveSetting :one
|
const GetOverrideSettings = `-- name: GetOverrideSettings :many
|
||||||
INSERT INTO settings (key, value, updated_at)
|
SELECT gs.key, gs.value, gs.created_at, gs.updated_at,
|
||||||
VALUES ($1, $2, CURRENT_TIMESTAMP) ON CONFLICT (key) DO
|
COALESCE(cs.value, gs.value) AS value
|
||||||
UPDATE
|
FROM global_settings gs
|
||||||
SET value = EXCLUDED.value
|
LEFT JOIN company_settings cs ON cs.key = gs.key
|
||||||
RETURNING key, value, created_at, updated_at
|
AND cs.company_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type SaveSettingParams struct {
|
type GetOverrideSettingsRow struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
Value_2 string `json:"value_2"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetOverrideSettings(ctx context.Context, companyID int64) ([]GetOverrideSettingsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetOverrideSettings, companyID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetOverrideSettingsRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetOverrideSettingsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.Key,
|
||||||
|
&i.Value,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.Value_2,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertCompanySetting = `-- name: InsertCompanySetting :exec
|
||||||
|
INSERT INTO company_settings (company_id, key, value)
|
||||||
|
VALUES ($1, $2, $3) ON CONFLICT (company_id, key) DO
|
||||||
|
UPDATE
|
||||||
|
SET value = EXCLUDED.value
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertCompanySettingParams struct {
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) InsertCompanySetting(ctx context.Context, arg InsertCompanySettingParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, InsertCompanySetting, arg.CompanyID, arg.Key, arg.Value)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateGlobalSetting = `-- name: UpdateGlobalSetting :exec
|
||||||
|
UPDATE global_settings
|
||||||
|
SET value = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE key = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateGlobalSettingParams struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SaveSetting(ctx context.Context, arg SaveSettingParams) (Setting, error) {
|
func (q *Queries) UpdateGlobalSetting(ctx context.Context, arg UpdateGlobalSettingParams) error {
|
||||||
row := q.db.QueryRow(ctx, SaveSetting, arg.Key, arg.Value)
|
_, err := q.db.Exec(ctx, UpdateGlobalSetting, arg.Key, arg.Value)
|
||||||
var i Setting
|
return err
|
||||||
err := row.Scan(
|
|
||||||
&i.Key,
|
|
||||||
&i.Value,
|
|
||||||
&i.CreatedAt,
|
|
||||||
&i.UpdatedAt,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,29 @@ func (q *Queries) CountTicketByIP(ctx context.Context, ip string) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateTicket = `-- name: CreateTicket :one
|
const CreateTicket = `-- name: CreateTicket :one
|
||||||
INSERT INTO tickets (amount, total_odds, ip)
|
INSERT INTO tickets (amount, total_odds, ip, company_id)
|
||||||
VALUES ($1, $2, $3)
|
VALUES ($1, $2, $3, $4)
|
||||||
RETURNING id, amount, total_odds, ip, created_at, updated_at
|
RETURNING id, company_id, amount, total_odds, ip, created_at, updated_at
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateTicketParams struct {
|
type CreateTicketParams struct {
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
TotalOdds float32 `json:"total_odds"`
|
TotalOdds float32 `json:"total_odds"`
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Ticket, error) {
|
func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Ticket, error) {
|
||||||
row := q.db.QueryRow(ctx, CreateTicket, arg.Amount, arg.TotalOdds, arg.Ip)
|
row := q.db.QueryRow(ctx, CreateTicket,
|
||||||
|
arg.Amount,
|
||||||
|
arg.TotalOdds,
|
||||||
|
arg.Ip,
|
||||||
|
arg.CompanyID,
|
||||||
|
)
|
||||||
var i Ticket
|
var i Ticket
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Ip,
|
&i.Ip,
|
||||||
|
|
@ -96,12 +103,16 @@ func (q *Queries) DeleteTicketOutcome(ctx context.Context, ticketID int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllTickets = `-- name: GetAllTickets :many
|
const GetAllTickets = `-- name: GetAllTickets :many
|
||||||
SELECT id, amount, total_odds, ip, created_at, updated_at, outcomes
|
SELECT id, company_id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||||
FROM ticket_with_outcomes
|
FROM ticket_with_outcomes
|
||||||
|
WHERE (
|
||||||
|
company_id = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error) {
|
func (q *Queries) GetAllTickets(ctx context.Context, companyID pgtype.Int8) ([]TicketWithOutcome, error) {
|
||||||
rows, err := q.db.Query(ctx, GetAllTickets)
|
rows, err := q.db.Query(ctx, GetAllTickets, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -111,6 +122,7 @@ func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error
|
||||||
var i TicketWithOutcome
|
var i TicketWithOutcome
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Ip,
|
&i.Ip,
|
||||||
|
|
@ -129,7 +141,8 @@ func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllTicketsInRange = `-- name: GetAllTicketsInRange :one
|
const GetAllTicketsInRange = `-- name: GetAllTicketsInRange :one
|
||||||
SELECT COUNT(*) as total_tickets, COALESCE(SUM(amount), 0) as total_amount
|
SELECT COUNT(*) as total_tickets,
|
||||||
|
COALESCE(SUM(amount), 0) as total_amount
|
||||||
FROM tickets
|
FROM tickets
|
||||||
WHERE created_at BETWEEN $1 AND $2
|
WHERE created_at BETWEEN $1 AND $2
|
||||||
`
|
`
|
||||||
|
|
@ -152,7 +165,7 @@ func (q *Queries) GetAllTicketsInRange(ctx context.Context, arg GetAllTicketsInR
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetTicketByID = `-- name: GetTicketByID :one
|
const GetTicketByID = `-- name: GetTicketByID :one
|
||||||
SELECT id, amount, total_odds, ip, created_at, updated_at, outcomes
|
SELECT id, company_id, amount, total_odds, ip, created_at, updated_at, outcomes
|
||||||
FROM ticket_with_outcomes
|
FROM ticket_with_outcomes
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -162,6 +175,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int64) (TicketWithOutcom
|
||||||
var i TicketWithOutcome
|
var i TicketWithOutcome
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
&i.CompanyID,
|
||||||
&i.Amount,
|
&i.Amount,
|
||||||
&i.TotalOdds,
|
&i.TotalOdds,
|
||||||
&i.Ip,
|
&i.Ip,
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,20 @@ SELECT EXISTS (
|
||||||
FROM users
|
FROM users
|
||||||
WHERE users.phone_number = $1
|
WHERE users.phone_number = $1
|
||||||
AND users.phone_number IS NOT NULL
|
AND users.phone_number IS NOT NULL
|
||||||
|
AND users.company_id = $2
|
||||||
) AS phone_exists,
|
) AS phone_exists,
|
||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM users
|
FROM users
|
||||||
WHERE users.email = $2
|
WHERE users.email = $3
|
||||||
AND users.email IS NOT NULL
|
AND users.email IS NOT NULL
|
||||||
|
AND users.company_id = $2
|
||||||
) AS email_exists
|
) AS email_exists
|
||||||
`
|
`
|
||||||
|
|
||||||
type CheckPhoneEmailExistParams struct {
|
type CheckPhoneEmailExistParams struct {
|
||||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
Email pgtype.Text `json:"email"`
|
Email pgtype.Text `json:"email"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +40,7 @@ type CheckPhoneEmailExistRow struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailExistParams) (CheckPhoneEmailExistRow, error) {
|
func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailExistParams) (CheckPhoneEmailExistRow, error) {
|
||||||
row := q.db.QueryRow(ctx, CheckPhoneEmailExist, arg.PhoneNumber, arg.Email)
|
row := q.db.QueryRow(ctx, CheckPhoneEmailExist, arg.PhoneNumber, arg.CompanyID, arg.Email)
|
||||||
var i CheckPhoneEmailExistRow
|
var i CheckPhoneEmailExistRow
|
||||||
err := row.Scan(&i.PhoneExists, &i.EmailExists)
|
err := row.Scan(&i.PhoneExists, &i.EmailExists)
|
||||||
return i, err
|
return i, err
|
||||||
|
|
@ -339,8 +342,14 @@ SELECT id,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE email = $1
|
WHERE email = $1
|
||||||
|
AND company_id = $2
|
||||||
`
|
`
|
||||||
|
|
||||||
|
type GetUserByEmailParams struct {
|
||||||
|
Email pgtype.Text `json:"email"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetUserByEmailRow struct {
|
type GetUserByEmailRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
FirstName string `json:"first_name"`
|
FirstName string `json:"first_name"`
|
||||||
|
|
@ -357,8 +366,8 @@ type GetUserByEmailRow struct {
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetUserByEmail(ctx context.Context, email pgtype.Text) (GetUserByEmailRow, error) {
|
func (q *Queries) GetUserByEmail(ctx context.Context, arg GetUserByEmailParams) (GetUserByEmailRow, error) {
|
||||||
row := q.db.QueryRow(ctx, GetUserByEmail, email)
|
row := q.db.QueryRow(ctx, GetUserByEmail, arg.Email, arg.CompanyID)
|
||||||
var i GetUserByEmailRow
|
var i GetUserByEmailRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
|
@ -424,8 +433,14 @@ SELECT id,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE phone_number = $1
|
WHERE phone_number = $1
|
||||||
|
AND company_id = $2
|
||||||
`
|
`
|
||||||
|
|
||||||
|
type GetUserByPhoneParams struct {
|
||||||
|
PhoneNumber pgtype.Text `json:"phone_number"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetUserByPhoneRow struct {
|
type GetUserByPhoneRow struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
FirstName string `json:"first_name"`
|
FirstName string `json:"first_name"`
|
||||||
|
|
@ -442,8 +457,8 @@ type GetUserByPhoneRow struct {
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetUserByPhone(ctx context.Context, phoneNumber pgtype.Text) (GetUserByPhoneRow, error) {
|
func (q *Queries) GetUserByPhone(ctx context.Context, arg GetUserByPhoneParams) (GetUserByPhoneRow, error) {
|
||||||
row := q.db.QueryRow(ctx, GetUserByPhone, phoneNumber)
|
row := q.db.QueryRow(ctx, GetUserByPhone, arg.PhoneNumber, arg.CompanyID)
|
||||||
var i GetUserByPhoneRow
|
var i GetUserByPhoneRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
|
@ -478,25 +493,22 @@ SELECT id,
|
||||||
suspended_at,
|
suspended_at,
|
||||||
company_id
|
company_id
|
||||||
FROM users
|
FROM users
|
||||||
WHERE (
|
WHERE (company_id = $1)
|
||||||
first_name ILIKE '%' || $1 || '%'
|
AND (
|
||||||
OR last_name ILIKE '%' || $1 || '%'
|
first_name ILIKE '%' || $2 || '%'
|
||||||
OR phone_number LIKE '%' || $1 || '%'
|
OR last_name ILIKE '%' || $2 || '%'
|
||||||
|
OR phone_number LIKE '%' || $2 || '%'
|
||||||
)
|
)
|
||||||
AND (
|
AND (
|
||||||
role = $2
|
role = $3
|
||||||
OR $2 IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
company_id = $3
|
|
||||||
OR $3 IS NULL
|
OR $3 IS NULL
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
type SearchUserByNameOrPhoneParams struct {
|
type SearchUserByNameOrPhoneParams struct {
|
||||||
Column1 pgtype.Text `json:"column_1"`
|
|
||||||
Role pgtype.Text `json:"role"`
|
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
Column2 pgtype.Text `json:"column_2"`
|
||||||
|
Role pgtype.Text `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchUserByNameOrPhoneRow struct {
|
type SearchUserByNameOrPhoneRow struct {
|
||||||
|
|
@ -516,7 +528,7 @@ type SearchUserByNameOrPhoneRow struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByNameOrPhoneParams) ([]SearchUserByNameOrPhoneRow, error) {
|
func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, arg SearchUserByNameOrPhoneParams) ([]SearchUserByNameOrPhoneRow, error) {
|
||||||
rows, err := q.db.Query(ctx, SearchUserByNameOrPhone, arg.Column1, arg.Role, arg.CompanyID)
|
rows, err := q.db.Query(ctx, SearchUserByNameOrPhone, arg.CompanyID, arg.Column2, arg.Role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -575,6 +587,7 @@ SET password = $1,
|
||||||
WHERE (
|
WHERE (
|
||||||
email = $2
|
email = $2
|
||||||
OR phone_number = $3
|
OR phone_number = $3
|
||||||
|
AND company_id = $4
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ INSERT INTO wallets (
|
||||||
type
|
type
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
RETURNING id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateWalletParams struct {
|
type CreateWalletParams struct {
|
||||||
|
|
@ -73,6 +73,7 @@ func (q *Queries) CreateWallet(ctx context.Context, arg CreateWalletParams) (Wal
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
|
&i.Currency,
|
||||||
&i.IsWithdraw,
|
&i.IsWithdraw,
|
||||||
&i.IsBettable,
|
&i.IsBettable,
|
||||||
&i.IsTransferable,
|
&i.IsTransferable,
|
||||||
|
|
@ -81,7 +82,6 @@ func (q *Queries) CreateWallet(ctx context.Context, arg CreateWalletParams) (Wal
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
&i.Currency,
|
|
||||||
&i.BonusBalance,
|
&i.BonusBalance,
|
||||||
&i.CashBalance,
|
&i.CashBalance,
|
||||||
)
|
)
|
||||||
|
|
@ -188,7 +188,7 @@ func (q *Queries) GetAllCustomerWallet(ctx context.Context) ([]CustomerWalletDet
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllWallets = `-- name: GetAllWallets :many
|
const GetAllWallets = `-- name: GetAllWallets :many
|
||||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||||
FROM wallets
|
FROM wallets
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -204,6 +204,7 @@ func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
|
&i.Currency,
|
||||||
&i.IsWithdraw,
|
&i.IsWithdraw,
|
||||||
&i.IsBettable,
|
&i.IsBettable,
|
||||||
&i.IsTransferable,
|
&i.IsTransferable,
|
||||||
|
|
@ -212,7 +213,6 @@ func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
&i.Currency,
|
|
||||||
&i.BonusBalance,
|
&i.BonusBalance,
|
||||||
&i.CashBalance,
|
&i.CashBalance,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
@ -319,7 +319,7 @@ func (q *Queries) GetCustomerWallet(ctx context.Context, customerID int64) (Cust
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetWalletByID = `-- name: GetWalletByID :one
|
const GetWalletByID = `-- name: GetWalletByID :one
|
||||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||||
FROM wallets
|
FROM wallets
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -330,6 +330,7 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
|
&i.Currency,
|
||||||
&i.IsWithdraw,
|
&i.IsWithdraw,
|
||||||
&i.IsBettable,
|
&i.IsBettable,
|
||||||
&i.IsTransferable,
|
&i.IsTransferable,
|
||||||
|
|
@ -338,7 +339,6 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
&i.Currency,
|
|
||||||
&i.BonusBalance,
|
&i.BonusBalance,
|
||||||
&i.CashBalance,
|
&i.CashBalance,
|
||||||
)
|
)
|
||||||
|
|
@ -346,7 +346,7 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetWalletByUserID = `-- name: GetWalletByUserID :many
|
const GetWalletByUserID = `-- name: GetWalletByUserID :many
|
||||||
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, currency, bonus_balance, cash_balance
|
SELECT id, balance, currency, is_withdraw, is_bettable, is_transferable, user_id, type, is_active, created_at, updated_at, bonus_balance, cash_balance
|
||||||
FROM wallets
|
FROM wallets
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
`
|
`
|
||||||
|
|
@ -363,6 +363,7 @@ func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Balance,
|
&i.Balance,
|
||||||
|
&i.Currency,
|
||||||
&i.IsWithdraw,
|
&i.IsWithdraw,
|
||||||
&i.IsBettable,
|
&i.IsBettable,
|
||||||
&i.IsTransferable,
|
&i.IsTransferable,
|
||||||
|
|
@ -371,7 +372,6 @@ func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet
|
||||||
&i.IsActive,
|
&i.IsActive,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
&i.Currency,
|
|
||||||
&i.BonusBalance,
|
&i.BonusBalance,
|
||||||
&i.CashBalance,
|
&i.CashBalance,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,14 @@ package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The Odd ID here is not the odd id from our database
|
||||||
|
// but the raw_odd_id from the betapi.from within the raw_odds json
|
||||||
|
// This can be refactor later
|
||||||
type BetOutcome struct {
|
type BetOutcome struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
BetID int64 `json:"bet_id" example:"1"`
|
BetID int64 `json:"bet_id" example:"1"`
|
||||||
|
|
@ -46,6 +52,7 @@ type Bet struct {
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
Status OutcomeStatus
|
Status OutcomeStatus
|
||||||
UserID int64
|
UserID int64
|
||||||
|
CompanyID int64
|
||||||
IsShopBet bool
|
IsShopBet bool
|
||||||
CashedOut bool
|
CashedOut bool
|
||||||
FastCode string
|
FastCode string
|
||||||
|
|
@ -54,6 +61,7 @@ type Bet struct {
|
||||||
|
|
||||||
type BetFilter struct {
|
type BetFilter struct {
|
||||||
UserID ValidInt64
|
UserID ValidInt64
|
||||||
|
CompanyID ValidInt64
|
||||||
CashedOut ValidBool
|
CashedOut ValidBool
|
||||||
IsShopBet ValidBool
|
IsShopBet ValidBool
|
||||||
Query ValidString
|
Query ValidString
|
||||||
|
|
@ -78,6 +86,7 @@ type GetBet struct {
|
||||||
FullName string
|
FullName string
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
UserID int64
|
UserID int64
|
||||||
|
CompanyID int64
|
||||||
IsShopBet bool
|
IsShopBet bool
|
||||||
CashedOut bool
|
CashedOut bool
|
||||||
Outcomes []BetOutcome
|
Outcomes []BetOutcome
|
||||||
|
|
@ -90,6 +99,7 @@ type CreateBet struct {
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
Status OutcomeStatus
|
Status OutcomeStatus
|
||||||
UserID int64
|
UserID int64
|
||||||
|
CompanyID int64
|
||||||
IsShopBet bool
|
IsShopBet bool
|
||||||
OutcomesHash string
|
OutcomesHash string
|
||||||
FastCode string
|
FastCode string
|
||||||
|
|
@ -130,6 +140,7 @@ type CreateBetRes struct {
|
||||||
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"`
|
||||||
UserID int64 `json:"user_id" example:"2"`
|
UserID int64 `json:"user_id" example:"2"`
|
||||||
|
CompanyID int64 `json:"company_id" example:"1"`
|
||||||
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||||
CreatedNumber int64 `json:"created_number" example:"2"`
|
CreatedNumber int64 `json:"created_number" example:"2"`
|
||||||
FastCode string `json:"fast_code"`
|
FastCode string `json:"fast_code"`
|
||||||
|
|
@ -142,19 +153,21 @@ type BetRes struct {
|
||||||
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"`
|
||||||
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||||
CashedOut bool `json:"cashed_out" example:"false"`
|
CashedOut bool `json:"cashed_out" example:"false"`
|
||||||
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
|
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
|
||||||
FastCode string `json:"fast_code"`
|
FastCode string `json:"fast_code"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateBet(bet Bet, createdNumber int64) CreateBetRes {
|
func ConvertCreateBetRes(bet Bet, createdNumber int64) CreateBetRes {
|
||||||
return CreateBetRes{
|
return CreateBetRes{
|
||||||
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,
|
||||||
UserID: bet.UserID,
|
UserID: bet.UserID,
|
||||||
|
CompanyID: bet.CompanyID,
|
||||||
CreatedNumber: createdNumber,
|
CreatedNumber: createdNumber,
|
||||||
IsShopBet: bet.IsShopBet,
|
IsShopBet: bet.IsShopBet,
|
||||||
FastCode: bet.FastCode,
|
FastCode: bet.FastCode,
|
||||||
|
|
@ -169,6 +182,7 @@ func ConvertBet(bet GetBet) BetRes {
|
||||||
Status: bet.Status,
|
Status: bet.Status,
|
||||||
Fullname: bet.FullName,
|
Fullname: bet.FullName,
|
||||||
UserID: bet.UserID,
|
UserID: bet.UserID,
|
||||||
|
CompanyID: bet.CompanyID,
|
||||||
Outcomes: bet.Outcomes,
|
Outcomes: bet.Outcomes,
|
||||||
IsShopBet: bet.IsShopBet,
|
IsShopBet: bet.IsShopBet,
|
||||||
CashedOut: bet.CashedOut,
|
CashedOut: bet.CashedOut,
|
||||||
|
|
@ -176,3 +190,106 @@ func ConvertBet(bet GetBet) BetRes {
|
||||||
FastCode: bet.FastCode,
|
FastCode: bet.FastCode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertDBBet(bet dbgen.Bet) Bet {
|
||||||
|
return Bet{
|
||||||
|
ID: bet.ID,
|
||||||
|
Amount: Currency(bet.Amount),
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
Status: OutcomeStatus(bet.Status),
|
||||||
|
UserID: bet.UserID,
|
||||||
|
CompanyID: bet.CompanyID,
|
||||||
|
IsShopBet: bet.IsShopBet,
|
||||||
|
CashedOut: bet.CashedOut,
|
||||||
|
FastCode: bet.FastCode,
|
||||||
|
CreatedAt: bet.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBBetOutcomes(outcome dbgen.BetOutcome) BetOutcome {
|
||||||
|
return BetOutcome{
|
||||||
|
ID: outcome.ID,
|
||||||
|
BetID: outcome.BetID,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBBetWithOutcomes(bet dbgen.BetWithOutcome) GetBet {
|
||||||
|
var outcomes []BetOutcome = make([]BetOutcome, 0, len(bet.Outcomes))
|
||||||
|
|
||||||
|
for _, outcome := range bet.Outcomes {
|
||||||
|
outcomes = append(outcomes, ConvertDBBetOutcomes(outcome))
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetBet{
|
||||||
|
ID: bet.ID,
|
||||||
|
Amount: Currency(bet.Amount),
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
Status: OutcomeStatus(bet.Status),
|
||||||
|
FullName: bet.FullName.(string),
|
||||||
|
PhoneNumber: bet.PhoneNumber.String,
|
||||||
|
UserID: bet.UserID,
|
||||||
|
IsShopBet: bet.IsShopBet,
|
||||||
|
CashedOut: bet.CashedOut,
|
||||||
|
Outcomes: outcomes,
|
||||||
|
FastCode: bet.FastCode,
|
||||||
|
CreatedAt: bet.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBFlag(flag dbgen.Flag) Flag {
|
||||||
|
return Flag{
|
||||||
|
ID: flag.ID,
|
||||||
|
BetID: flag.BetID.Int64,
|
||||||
|
OddID: flag.OddsMarketID.Int64,
|
||||||
|
Reason: flag.Reason.String,
|
||||||
|
FlaggedAt: flag.FlaggedAt.Time,
|
||||||
|
Resolved: flag.Resolved.Bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBCreateBetOutcome(betOutcome CreateBetOutcome) dbgen.CreateBetOutcomeParams {
|
||||||
|
return dbgen.CreateBetOutcomeParams{
|
||||||
|
BetID: betOutcome.BetID,
|
||||||
|
EventID: betOutcome.EventID,
|
||||||
|
SportID: betOutcome.SportID,
|
||||||
|
OddID: betOutcome.OddID,
|
||||||
|
HomeTeamName: betOutcome.HomeTeamName,
|
||||||
|
AwayTeamName: betOutcome.AwayTeamName,
|
||||||
|
MarketID: betOutcome.MarketID,
|
||||||
|
MarketName: betOutcome.MarketName,
|
||||||
|
Odd: betOutcome.Odd,
|
||||||
|
OddName: betOutcome.OddName,
|
||||||
|
OddHeader: betOutcome.OddHeader,
|
||||||
|
OddHandicap: betOutcome.OddHandicap,
|
||||||
|
Expires: pgtype.Timestamp{
|
||||||
|
Time: betOutcome.Expires,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateBet(bet CreateBet) dbgen.CreateBetParams {
|
||||||
|
return dbgen.CreateBetParams{
|
||||||
|
Amount: int64(bet.Amount),
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
Status: int32(bet.Status),
|
||||||
|
UserID: bet.UserID,
|
||||||
|
CompanyID: bet.CompanyID,
|
||||||
|
IsShopBet: bet.IsShopBet,
|
||||||
|
OutcomesHash: bet.OutcomesHash,
|
||||||
|
FastCode: bet.FastCode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,11 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var MongoDBLogger *zap.Logger
|
var MongoDBLogger *zap.Logger
|
||||||
|
|
||||||
type ValidInt64 struct {
|
|
||||||
Value int64
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
type ValidInt struct {
|
|
||||||
Value int
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
type ValidInt32 struct {
|
|
||||||
Value int32
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValidFloat32 struct {
|
|
||||||
Value float32
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValidString struct {
|
|
||||||
Value string
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
type ValidTime struct {
|
|
||||||
Value time.Time
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
type ValidBool struct {
|
|
||||||
Value bool
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Currency int64
|
|
||||||
|
|
||||||
// ToCurrency converts a float32 to Currency
|
|
||||||
func ToCurrency(f float32) Currency {
|
|
||||||
return Currency((f * 100) + 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32 converts a Currency to float32
|
|
||||||
func (m Currency) Float32() float32 {
|
|
||||||
x := float32(m)
|
|
||||||
x = x / 100
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a formatted Currency value
|
|
||||||
func (m Currency) String() string {
|
|
||||||
x := float32(m)
|
|
||||||
x = x / 100
|
|
||||||
return fmt.Sprintf("$%.2f", x)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResponseWDataFactory[T any] struct {
|
type ResponseWDataFactory[T any] struct {
|
||||||
Data T `json:"data"`
|
Data T `json:"data"`
|
||||||
Response
|
Response
|
||||||
|
|
@ -95,73 +38,3 @@ type Pagination struct {
|
||||||
|
|
||||||
func PtrFloat64(v float64) *float64 { return &v }
|
func PtrFloat64(v float64) *float64 { return &v }
|
||||||
func PtrInt64(v int64) *int64 { return &v }
|
func PtrInt64(v int64) *int64 { return &v }
|
||||||
|
|
||||||
type Int64JSON int64
|
|
||||||
|
|
||||||
// func (i *Int64JSON) Parse() (int64, error) {
|
|
||||||
// var asString string
|
|
||||||
// if err := json.Unmarshal(i, &asString); err == nil {
|
|
||||||
// // Try to parse the string to int64
|
|
||||||
// return strconv.ParseInt(strings.TrimSpace(asString), 10, 64)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var asInt int64
|
|
||||||
// if err := json.Unmarshal(i, &asInt); err == nil {
|
|
||||||
// return asInt, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Neither string nor int worked
|
|
||||||
// return 0, fmt.Errorf("invalid int64 value: %s", string(i))
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (i *Int64JSON) UnmarshalJSON(data []byte) error {
|
|
||||||
var s string
|
|
||||||
if err := json.Unmarshal(data, &s); err == nil {
|
|
||||||
// it was a string, parse it
|
|
||||||
v, err := strconv.ParseInt(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*i = Int64JSON(v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var v int64
|
|
||||||
if err := json.Unmarshal(data, &v); err == nil {
|
|
||||||
*i = Int64JSON(v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("invalid int64 value: %s", string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
type NullableInt64JSON struct {
|
|
||||||
Int64 int64
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NullableInt64JSON) UnmarshalJSON(data []byte) error {
|
|
||||||
var s string
|
|
||||||
if err := json.Unmarshal(data, &s); err == nil {
|
|
||||||
if s == "" {
|
|
||||||
n.Valid = false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
v, err := strconv.ParseInt(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n.Int64, n.Valid = v, true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var v int64
|
|
||||||
if err := json.Unmarshal(data, &v); err == nil {
|
|
||||||
n.Int64, n.Valid = v, true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("invalid int64 value: %s", string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
34
internal/domain/common_log.go
Normal file
34
internal/domain/common_log.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// var BadRequestZapFields = []zap.Field{
|
||||||
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
// zap.Time("timestamp", time.Now()),
|
||||||
|
// }
|
||||||
|
// var InternalServerErrorZapFields = []zap.Field{
|
||||||
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
// zap.Time("timestamp", time.Now()),
|
||||||
|
// }
|
||||||
|
|
||||||
|
var SuccessResZapFields = []zap.Field{
|
||||||
|
zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
zap.Time("timestamp", time.Now()),
|
||||||
|
}
|
||||||
|
|
||||||
|
// var BadRequestLogger = MongoDBLogger.With(
|
||||||
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
||||||
|
// zap.Time("timestamp", time.Now()))
|
||||||
|
|
||||||
|
// var InternalServerErrorLogger = MongoDBLogger.With(
|
||||||
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
||||||
|
// zap.Time("timestamp", time.Now()))
|
||||||
|
|
||||||
|
// var SuccessResLogger = MongoDBLogger.With(
|
||||||
|
// zap.Int("status_code", fiber.StatusOK),
|
||||||
|
// zap.Time("timestamp", time.Now()))
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
type Company struct {
|
type Company struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
|
Slug string
|
||||||
AdminID int64
|
AdminID int64
|
||||||
WalletID int64
|
WalletID int64
|
||||||
DeductedPercentage float32
|
DeductedPercentage float32
|
||||||
|
|
@ -27,6 +28,7 @@ type CompanyFilter struct {
|
||||||
type GetCompany struct {
|
type GetCompany struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
|
Slug string
|
||||||
AdminID int64
|
AdminID int64
|
||||||
AdminFirstName string
|
AdminFirstName string
|
||||||
AdminLastName string
|
AdminLastName string
|
||||||
|
|
@ -68,6 +70,7 @@ type UpdateCompanyReq struct {
|
||||||
type CompanyRes struct {
|
type CompanyRes struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
Name string `json:"name" example:"CompanyName"`
|
Name string `json:"name" example:"CompanyName"`
|
||||||
|
Slug string `json:"slug" example:"slug"`
|
||||||
AdminID int64 `json:"admin_id" example:"1"`
|
AdminID int64 `json:"admin_id" example:"1"`
|
||||||
WalletID int64 `json:"wallet_id" example:"1"`
|
WalletID int64 `json:"wallet_id" example:"1"`
|
||||||
DeductedPercentage float32 `json:"deducted_percentage" example:"0.1"`
|
DeductedPercentage float32 `json:"deducted_percentage" example:"0.1"`
|
||||||
|
|
@ -77,6 +80,7 @@ type CompanyRes struct {
|
||||||
type GetCompanyRes struct {
|
type GetCompanyRes struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
Name string `json:"name" example:"CompanyName"`
|
Name string `json:"name" example:"CompanyName"`
|
||||||
|
Slug string `json:"slug" example:"slug"`
|
||||||
AdminID int64 `json:"admin_id" example:"1"`
|
AdminID int64 `json:"admin_id" example:"1"`
|
||||||
WalletID int64 `json:"wallet_id" example:"1"`
|
WalletID int64 `json:"wallet_id" example:"1"`
|
||||||
WalletBalance float32 `json:"balance" example:"1"`
|
WalletBalance float32 `json:"balance" example:"1"`
|
||||||
|
|
@ -89,20 +93,14 @@ type GetCompanyRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCompany(company Company) CompanyRes {
|
func ConvertCompany(company Company) CompanyRes {
|
||||||
return CompanyRes{
|
return CompanyRes(company)
|
||||||
ID: company.ID,
|
|
||||||
Name: company.Name,
|
|
||||||
AdminID: company.AdminID,
|
|
||||||
WalletID: company.WalletID,
|
|
||||||
IsActive: company.IsActive,
|
|
||||||
DeductedPercentage: company.DeductedPercentage,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
||||||
return GetCompanyRes{
|
return GetCompanyRes{
|
||||||
ID: company.ID,
|
ID: company.ID,
|
||||||
Name: company.Name,
|
Name: company.Name,
|
||||||
|
Slug: company.Slug,
|
||||||
AdminID: company.AdminID,
|
AdminID: company.AdminID,
|
||||||
WalletID: company.WalletID,
|
WalletID: company.WalletID,
|
||||||
WalletBalance: company.WalletBalance.Float32(),
|
WalletBalance: company.WalletBalance.Float32(),
|
||||||
|
|
@ -112,13 +110,13 @@ func ConvertGetCompany(company GetCompany) GetCompanyRes {
|
||||||
AdminFirstName: company.AdminFirstName,
|
AdminFirstName: company.AdminFirstName,
|
||||||
AdminLastName: company.AdminLastName,
|
AdminLastName: company.AdminLastName,
|
||||||
AdminPhoneNumber: company.AdminPhoneNumber,
|
AdminPhoneNumber: company.AdminPhoneNumber,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCreateCompany(company CreateCompany) dbgen.CreateCompanyParams {
|
func ConvertCreateCompany(company CreateCompany, uniqueSlug string) dbgen.CreateCompanyParams {
|
||||||
return dbgen.CreateCompanyParams{
|
return dbgen.CreateCompanyParams{
|
||||||
Name: company.Name,
|
Name: company.Name,
|
||||||
|
Slug: uniqueSlug,
|
||||||
AdminID: company.AdminID,
|
AdminID: company.AdminID,
|
||||||
WalletID: company.WalletID,
|
WalletID: company.WalletID,
|
||||||
DeductedPercentage: company.DeductedPercentage,
|
DeductedPercentage: company.DeductedPercentage,
|
||||||
|
|
@ -129,6 +127,7 @@ func ConvertDBCompany(dbCompany dbgen.Company) Company {
|
||||||
return Company{
|
return Company{
|
||||||
ID: dbCompany.ID,
|
ID: dbCompany.ID,
|
||||||
Name: dbCompany.Name,
|
Name: dbCompany.Name,
|
||||||
|
Slug: dbCompany.Slug,
|
||||||
AdminID: dbCompany.AdminID,
|
AdminID: dbCompany.AdminID,
|
||||||
WalletID: dbCompany.WalletID,
|
WalletID: dbCompany.WalletID,
|
||||||
DeductedPercentage: dbCompany.DeductedPercentage,
|
DeductedPercentage: dbCompany.DeductedPercentage,
|
||||||
|
|
@ -140,6 +139,7 @@ func ConvertDBCompanyDetails(dbCompany dbgen.CompaniesDetail) GetCompany {
|
||||||
return GetCompany{
|
return GetCompany{
|
||||||
ID: dbCompany.ID,
|
ID: dbCompany.ID,
|
||||||
Name: dbCompany.Name,
|
Name: dbCompany.Name,
|
||||||
|
Slug: dbCompany.Slug,
|
||||||
AdminID: dbCompany.AdminID,
|
AdminID: dbCompany.AdminID,
|
||||||
WalletID: dbCompany.WalletID,
|
WalletID: dbCompany.WalletID,
|
||||||
WalletBalance: Currency(dbCompany.Balance),
|
WalletBalance: Currency(dbCompany.Balance),
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,28 @@ package domain
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Currency int64
|
||||||
|
|
||||||
|
// ToCurrency converts a float32 (like 12.34) into Currency (stored in cents).
|
||||||
|
func ToCurrency(f float32) Currency {
|
||||||
|
cents := math.Round(float64(f) * 100) // avoid float32 precision issues
|
||||||
|
return Currency(int64(cents))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 converts a Currency back into float32 (like 12.34).
|
||||||
|
func (m Currency) Float32() float32 {
|
||||||
|
return float32(m) / 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 (
|
||||||
|
|
|
||||||
69
internal/domain/custom_odds.go
Normal file
69
internal/domain/custom_odds.go
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "encoding/json"
|
||||||
|
// "time"
|
||||||
|
|
||||||
|
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// type CustomOdd struct {
|
||||||
|
// ID int64
|
||||||
|
// OddID int64
|
||||||
|
// CompanyID int64
|
||||||
|
// EventID string
|
||||||
|
// RawOdds []json.RawMessage
|
||||||
|
// CreatedAt time.Time
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type CreateCustomOdd struct {
|
||||||
|
// OddID int64
|
||||||
|
// CompanyID int64
|
||||||
|
// EventID string
|
||||||
|
// RawOdds []json.RawMessage
|
||||||
|
// }
|
||||||
|
|
||||||
|
// type CustomOddFilter struct {
|
||||||
|
// CompanyID ValidInt64
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func ConvertCreateCustomOdd(odd CreateCustomOdd) (dbgen.InsertCustomOddParams, error) {
|
||||||
|
// rawOddsBytes, err := json.Marshal(odd.RawOdds)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return dbgen.InsertCustomOddParams{}, err
|
||||||
|
// }
|
||||||
|
// return dbgen.InsertCustomOddParams{
|
||||||
|
// OddID: odd.OddID,
|
||||||
|
// CompanyID: odd.CompanyID,
|
||||||
|
// EventID: odd.EventID,
|
||||||
|
// RawOdds: rawOddsBytes,
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func ConvertDBCustomOdd(dbCustomOdd dbgen.CustomOdd) (CustomOdd, error) {
|
||||||
|
// var rawOdds []json.RawMessage
|
||||||
|
// if err := json.Unmarshal(dbCustomOdd.RawOdds, &rawOdds); err != nil {
|
||||||
|
// return CustomOdd{}, err
|
||||||
|
// }
|
||||||
|
// return CustomOdd{
|
||||||
|
// ID: dbCustomOdd.ID,
|
||||||
|
// OddID: dbCustomOdd.OddID,
|
||||||
|
// CompanyID: dbCustomOdd.CompanyID,
|
||||||
|
// EventID: dbCustomOdd.EventID,
|
||||||
|
// RawOdds: rawOdds,
|
||||||
|
// CreatedAt: dbCustomOdd.CreatedAt.Time,
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func ConvertDbCustomOdds(list []dbgen.CustomOdd) ([]CustomOdd, error) {
|
||||||
|
// result := make([]CustomOdd, 0, len(list))
|
||||||
|
// for _, item := range list {
|
||||||
|
// convertedItem, err := ConvertDBCustomOdd(item)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// result = append(result, convertedItem)
|
||||||
|
// }
|
||||||
|
// return result, nil
|
||||||
|
// }
|
||||||
51
internal/domain/disabled_odds.go
Normal file
51
internal/domain/disabled_odds.go
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DisabledOdd struct {
|
||||||
|
ID int64
|
||||||
|
OddMarketID int64
|
||||||
|
RawOddID int64
|
||||||
|
EventID string
|
||||||
|
CompanyID int64
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateDisabledOdd struct {
|
||||||
|
OddMarketID int64
|
||||||
|
RawOddID int64
|
||||||
|
EventID string
|
||||||
|
CompanyID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateDisabledOdd(odd CreateDisabledOdd) dbgen.InsertDisabledOddsParams {
|
||||||
|
return dbgen.InsertDisabledOddsParams{
|
||||||
|
OddsMarketID: odd.OddMarketID,
|
||||||
|
EventID: odd.EventID,
|
||||||
|
CompanyID: odd.CompanyID,
|
||||||
|
RawOddID: odd.RawOddID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBDisabledOdd(dbDisabledOdd dbgen.DisabledOdd) DisabledOdd {
|
||||||
|
return DisabledOdd{
|
||||||
|
ID: dbDisabledOdd.ID,
|
||||||
|
OddMarketID: dbDisabledOdd.OddsMarketID,
|
||||||
|
RawOddID: dbDisabledOdd.RawOddID,
|
||||||
|
EventID: dbDisabledOdd.EventID,
|
||||||
|
CompanyID: dbDisabledOdd.CompanyID,
|
||||||
|
CreatedAt: dbDisabledOdd.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDisabledOdds(list []dbgen.DisabledOdd) []DisabledOdd {
|
||||||
|
result := make([]DisabledOdd, 0, len(list))
|
||||||
|
for _, item := range list {
|
||||||
|
result = append(result, ConvertDBDisabledOdd(item))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: turn status into an enum
|
// TODO: turn status into an enum
|
||||||
// Status represents the status of an event.
|
// Status represents the status of an event.
|
||||||
|
|
@ -35,100 +40,408 @@ const (
|
||||||
STATUS_REMOVED EventStatus = "removed"
|
STATUS_REMOVED EventStatus = "removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Event struct {
|
type EventSource string
|
||||||
ID string
|
|
||||||
SportID int32
|
const (
|
||||||
MatchName string
|
EVENT_SOURCE_BET365 EventSource = "b365api"
|
||||||
HomeTeam string
|
EVENT_SOURCE_BWIN EventSource = "bwin"
|
||||||
AwayTeam string
|
EVENT_SOURCE_BETFAIR EventSource = "bfair"
|
||||||
HomeTeamID int32
|
EVENT_SOURCE_1XBET EventSource = "1xbet"
|
||||||
AwayTeamID int32
|
EVENT_SOURCE_ENET EventSource = "enetpulse"
|
||||||
HomeKitImage string
|
)
|
||||||
AwayKitImage string
|
|
||||||
LeagueID int32
|
type BaseEvent struct {
|
||||||
LeagueName string
|
ID string
|
||||||
LeagueCC string
|
SportID int32
|
||||||
StartTime string
|
MatchName string
|
||||||
Score string
|
HomeTeam string
|
||||||
MatchMinute int
|
AwayTeam string
|
||||||
TimerStatus string
|
HomeTeamID int64
|
||||||
AddedTime int
|
AwayTeamID int64
|
||||||
MatchPeriod int
|
HomeTeamImage string
|
||||||
IsLive bool
|
AwayTeamImage string
|
||||||
Status string
|
LeagueID int64
|
||||||
Source string
|
LeagueName string
|
||||||
|
LeagueCC ValidString
|
||||||
|
StartTime time.Time
|
||||||
|
Source EventSource
|
||||||
|
Status EventStatus
|
||||||
|
IsMonitored bool
|
||||||
|
DefaultIsFeatured bool
|
||||||
|
DefaultIsActive bool
|
||||||
|
DefaultWinningUpperLimit int32
|
||||||
|
Score ValidString
|
||||||
|
MatchMinute ValidInt
|
||||||
|
TimerStatus ValidString
|
||||||
|
AddedTime ValidInt
|
||||||
|
MatchPeriod ValidInt
|
||||||
|
IsLive bool
|
||||||
|
FetchedAt time.Time
|
||||||
|
}
|
||||||
|
type BaseEventRes 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"`
|
||||||
|
HomeTeamImage string `json:"home_team_image"`
|
||||||
|
AwayTeamImage string `json:"away_team_image"`
|
||||||
|
LeagueID int64 `json:"league_id"`
|
||||||
|
LeagueName string `json:"league_name"`
|
||||||
|
LeagueCC string `json:"league_cc"`
|
||||||
|
StartTime time.Time `json:"start_time"`
|
||||||
|
Source EventSource `json:"source"`
|
||||||
|
Status EventStatus `json:"status"`
|
||||||
|
IsMonitored bool `json:"is_monitored"`
|
||||||
|
DefaultIsFeatured bool `json:"default_is_featured"`
|
||||||
|
DefaultIsActive bool `json:"default_is_active"`
|
||||||
|
DefaultWinningUpperLimit int32 `json:"default_winning_upper_limit"`
|
||||||
|
Score string `json:"score,omitempty"`
|
||||||
|
MatchMinute int `json:"match_minute,omitempty"`
|
||||||
|
TimerStatus string `json:"timer_status,omitempty"`
|
||||||
|
AddedTime int `json:"added_time,omitempty"`
|
||||||
|
MatchPeriod int `json:"match_period,omitempty"`
|
||||||
|
IsLive bool `json:"is_live"`
|
||||||
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
|
}
|
||||||
|
type EventWithSettings struct {
|
||||||
|
ID string
|
||||||
|
SportID int32
|
||||||
|
MatchName string
|
||||||
|
HomeTeam string
|
||||||
|
AwayTeam string
|
||||||
|
HomeTeamID int64
|
||||||
|
AwayTeamID int64
|
||||||
|
HomeTeamImage string
|
||||||
|
AwayTeamImage string
|
||||||
|
LeagueID int64
|
||||||
|
LeagueName string
|
||||||
|
LeagueCC ValidString
|
||||||
|
StartTime time.Time
|
||||||
|
Source EventSource
|
||||||
|
Status EventStatus
|
||||||
|
IsFeatured bool
|
||||||
|
IsMonitored bool
|
||||||
|
IsActive bool
|
||||||
|
WinningUpperLimit int32
|
||||||
|
Score ValidString
|
||||||
|
MatchMinute ValidInt
|
||||||
|
TimerStatus ValidString
|
||||||
|
AddedTime ValidInt
|
||||||
|
MatchPeriod ValidInt
|
||||||
|
IsLive bool
|
||||||
|
UpdatedAt time.Time
|
||||||
|
FetchedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type BetResult struct {
|
type CreateEvent struct {
|
||||||
Success int `json:"success"`
|
ID string
|
||||||
Pager struct {
|
SportID int32
|
||||||
Page int `json:"page"`
|
MatchName string
|
||||||
PerPage int `json:"per_page"`
|
HomeTeam string
|
||||||
Total int `json:"total"`
|
AwayTeam string
|
||||||
}
|
HomeTeamID int64
|
||||||
Results []struct {
|
AwayTeamID int64
|
||||||
ID string `json:"id"`
|
HomeTeamImage string
|
||||||
SportID string `json:"sport_id"`
|
AwayTeamImage string
|
||||||
Time string `json:"time"`
|
LeagueID int64
|
||||||
League struct {
|
LeagueName string
|
||||||
ID string `json:"id"`
|
StartTime time.Time
|
||||||
Name string `json:"name"`
|
IsLive bool
|
||||||
} `json:"league"`
|
Status EventStatus
|
||||||
Home struct {
|
Source EventSource
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"home"`
|
|
||||||
Away *struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"away"`
|
|
||||||
} `json:"results"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpcomingEvent struct {
|
type EventWithSettingsRes struct {
|
||||||
ID string `json:"id"` // Event ID
|
ID string `json:"id"`
|
||||||
SportID int32 `json:"sport_id"` // Sport ID
|
SportID int32 `json:"sport_id"`
|
||||||
MatchName string `json:"match_name"` // Match or event name
|
MatchName string `json:"match_name"`
|
||||||
HomeTeam string `json:"home_team"` // Home team name (if available)
|
HomeTeam string `json:"home_team"`
|
||||||
AwayTeam string `json:"away_team"` // Away team name (can be empty/null)
|
AwayTeam string `json:"away_team"`
|
||||||
HomeTeamID int32 `json:"home_team_id"` // Home team ID
|
HomeTeamID int64 `json:"home_team_id"`
|
||||||
AwayTeamID int32 `json:"away_team_id"` // Away team ID (can be empty/null)
|
AwayTeamID int64 `json:"away_team_id"`
|
||||||
HomeKitImage string `json:"home_kit_image"` // Kit or image for home team (optional)
|
HomeTeamImage string `json:"home_team_image"`
|
||||||
AwayKitImage string `json:"away_kit_image"` // Kit or image for away team (optional)
|
AwayTeamImage string `json:"away_team_image"`
|
||||||
LeagueID int32 `json:"league_id"` // League ID
|
LeagueID int64 `json:"league_id"`
|
||||||
LeagueName string `json:"league_name"` // League name
|
LeagueName string `json:"league_name"`
|
||||||
LeagueCC string `json:"league_cc"` // League country code
|
LeagueCC string `json:"league_cc"`
|
||||||
StartTime time.Time `json:"start_time"` // Converted from "time" field in UNIX format
|
StartTime time.Time `json:"start_time"`
|
||||||
Source string `json:"source"` // bet api provider (bet365, betfair)
|
Source EventSource `json:"source"`
|
||||||
Status EventStatus `json:"status"` //Match Status for event
|
Status EventStatus `json:"status"`
|
||||||
IsFeatured bool `json:"is_featured"` //Whether the event is featured or not
|
IsFeatured bool `json:"is_featured"`
|
||||||
IsActive bool `json:"is_active"` //Whether the event is featured or not
|
IsMonitored bool `json:"is_monitored"`
|
||||||
}
|
IsActive bool `json:"is_active"`
|
||||||
type MatchResult struct {
|
WinningUpperLimit int32 `json:"winning_upper_limit"`
|
||||||
EventID string
|
Score string `json:"score,omitempty"`
|
||||||
FullScore string
|
MatchMinute int `json:"match_minute,omitempty"`
|
||||||
HalfScore string
|
TimerStatus string `json:"timer_status,omitempty"`
|
||||||
Status string
|
AddedTime int `json:"added_time,omitempty"`
|
||||||
Scores map[string]map[string]string
|
MatchPeriod int `json:"match_period,omitempty"`
|
||||||
|
IsLive bool `json:"is_live"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Odds struct {
|
type EventSettings struct {
|
||||||
ID int64 `json:"id"`
|
CompanyID int64
|
||||||
EventID string `json:"event_id"`
|
EventID string
|
||||||
MarketType string `json:"market_type"`
|
IsActive ValidBool
|
||||||
Name string `json:"name"`
|
IsFeatured ValidBool
|
||||||
HitStatus string `json:"hit_status"`
|
WinningUpperLimit ValidInt
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateEventSettings struct {
|
||||||
|
CompanyID int64
|
||||||
|
EventID string
|
||||||
|
IsActive ValidBool
|
||||||
|
IsFeatured ValidBool
|
||||||
|
WinningUpperLimit ValidInt
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventFilter struct {
|
type EventFilter struct {
|
||||||
Query ValidString
|
Query ValidString
|
||||||
SportID ValidInt32
|
SportID ValidInt32
|
||||||
LeagueID ValidInt32
|
LeagueID ValidInt64
|
||||||
CountryCode ValidString
|
CountryCode ValidString
|
||||||
FirstStartTime ValidTime
|
FirstStartTime ValidTime
|
||||||
LastStartTime ValidTime
|
LastStartTime ValidTime
|
||||||
Limit ValidInt64
|
Limit ValidInt32
|
||||||
Offset ValidInt64
|
Offset ValidInt32
|
||||||
MatchStatus ValidString // e.g., "upcoming", "in_play", "ended"
|
MatchStatus ValidString // e.g., "upcoming", "in_play", "ended"
|
||||||
Featured ValidBool
|
Featured ValidBool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertDBEvent(event dbgen.EventWithCountry) BaseEvent {
|
||||||
|
return BaseEvent{
|
||||||
|
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: ValidString{
|
||||||
|
Value: event.LeagueCc.String,
|
||||||
|
Valid: event.LeagueCc.Valid,
|
||||||
|
},
|
||||||
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
|
Source: EventSource(event.Source),
|
||||||
|
Status: EventStatus(event.Status),
|
||||||
|
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||||
|
IsMonitored: event.IsMonitored,
|
||||||
|
DefaultIsActive: event.DefaultIsActive,
|
||||||
|
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||||
|
Score: ValidString{
|
||||||
|
Value: event.Score.String,
|
||||||
|
Valid: event.Score.Valid,
|
||||||
|
},
|
||||||
|
MatchMinute: ValidInt{
|
||||||
|
Value: int(event.MatchMinute.Int32),
|
||||||
|
Valid: event.MatchMinute.Valid,
|
||||||
|
},
|
||||||
|
TimerStatus: ValidString{
|
||||||
|
Value: event.TimerStatus.String,
|
||||||
|
Valid: event.TimerStatus.Valid,
|
||||||
|
},
|
||||||
|
AddedTime: ValidInt{
|
||||||
|
Value: int(event.AddedTime.Int32),
|
||||||
|
Valid: event.AddedTime.Valid,
|
||||||
|
},
|
||||||
|
MatchPeriod: ValidInt{
|
||||||
|
Value: int(event.MatchPeriod.Int32),
|
||||||
|
Valid: event.MatchPeriod.Valid,
|
||||||
|
},
|
||||||
|
IsLive: event.IsLive,
|
||||||
|
FetchedAt: event.FetchedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBEvents(events []dbgen.EventWithCountry) []BaseEvent {
|
||||||
|
result := make([]BaseEvent, len(events))
|
||||||
|
for i, e := range events {
|
||||||
|
result[i] = ConvertDBEvent(e)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateEvent(e CreateEvent) dbgen.InsertEventParams {
|
||||||
|
return dbgen.InsertEventParams{
|
||||||
|
ID: e.ID,
|
||||||
|
SportID: e.SportID,
|
||||||
|
MatchName: e.MatchName,
|
||||||
|
HomeTeam: e.HomeTeam,
|
||||||
|
AwayTeam: e.AwayTeam,
|
||||||
|
HomeTeamID: e.HomeTeamID,
|
||||||
|
AwayTeamID: e.AwayTeamID,
|
||||||
|
HomeKitImage: e.HomeTeamImage,
|
||||||
|
AwayKitImage: e.AwayTeamImage,
|
||||||
|
LeagueID: e.LeagueID,
|
||||||
|
LeagueName: e.LeagueName,
|
||||||
|
StartTime: pgtype.Timestamp{Time: e.StartTime, Valid: true},
|
||||||
|
IsLive: e.IsLive,
|
||||||
|
Status: string(e.Status),
|
||||||
|
Source: string(e.Source),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateEventSettings(eventSettings CreateEventSettings) dbgen.InsertEventSettingsParams {
|
||||||
|
return dbgen.InsertEventSettingsParams{
|
||||||
|
CompanyID: eventSettings.CompanyID,
|
||||||
|
EventID: eventSettings.EventID,
|
||||||
|
IsActive: eventSettings.IsActive.ToPG(),
|
||||||
|
IsFeatured: eventSettings.IsFeatured.ToPG(),
|
||||||
|
WinningUpperLimit: eventSettings.WinningUpperLimit.ToPG(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBEventWithSetting(event dbgen.EventWithSetting) EventWithSettings {
|
||||||
|
return 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: ValidString{
|
||||||
|
Value: event.LeagueCc.String,
|
||||||
|
Valid: event.LeagueCc.Valid,
|
||||||
|
},
|
||||||
|
StartTime: event.StartTime.Time.UTC(),
|
||||||
|
Source: EventSource(event.Source),
|
||||||
|
Status: EventStatus(event.Status),
|
||||||
|
IsFeatured: event.IsFeatured,
|
||||||
|
IsMonitored: event.IsMonitored,
|
||||||
|
IsActive: event.IsActive,
|
||||||
|
WinningUpperLimit: event.WinningUpperLimit,
|
||||||
|
Score: ValidString{
|
||||||
|
Value: event.Score.String,
|
||||||
|
Valid: event.Score.Valid,
|
||||||
|
},
|
||||||
|
MatchMinute: ValidInt{
|
||||||
|
Value: int(event.MatchMinute.Int32),
|
||||||
|
Valid: event.MatchMinute.Valid,
|
||||||
|
},
|
||||||
|
TimerStatus: ValidString{
|
||||||
|
Value: event.TimerStatus.String,
|
||||||
|
Valid: event.TimerStatus.Valid,
|
||||||
|
},
|
||||||
|
AddedTime: ValidInt{
|
||||||
|
Value: int(event.AddedTime.Int32),
|
||||||
|
Valid: event.AddedTime.Valid,
|
||||||
|
},
|
||||||
|
MatchPeriod: ValidInt{
|
||||||
|
Value: int(event.MatchPeriod.Int32),
|
||||||
|
Valid: event.MatchPeriod.Valid,
|
||||||
|
},
|
||||||
|
IsLive: event.IsLive,
|
||||||
|
UpdatedAt: event.UpdatedAt.Time,
|
||||||
|
FetchedAt: event.FetchedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBEventWithSettings(events []dbgen.EventWithSetting) []EventWithSettings {
|
||||||
|
result := make([]EventWithSettings, len(events))
|
||||||
|
for i, e := range events {
|
||||||
|
result[i] = ConvertDBEventWithSetting(e)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertUpdateEventSettings(event CreateEventSettings) dbgen.UpdateEventSettingsParams {
|
||||||
|
return dbgen.UpdateEventSettingsParams{
|
||||||
|
EventID: event.EventID,
|
||||||
|
CompanyID: event.CompanyID,
|
||||||
|
IsActive: event.IsActive.ToPG(),
|
||||||
|
IsFeatured: event.IsFeatured.ToPG(),
|
||||||
|
WinningUpperLimit: event.WinningUpperLimit.ToPG(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertEventRes(event BaseEvent) BaseEventRes {
|
||||||
|
return BaseEventRes{
|
||||||
|
ID: event.ID,
|
||||||
|
SportID: event.SportID,
|
||||||
|
MatchName: event.MatchName,
|
||||||
|
HomeTeam: event.HomeTeam,
|
||||||
|
AwayTeam: event.AwayTeam,
|
||||||
|
HomeTeamID: event.HomeTeamID,
|
||||||
|
AwayTeamID: event.AwayTeamID,
|
||||||
|
HomeTeamImage: event.HomeTeamImage,
|
||||||
|
AwayTeamImage: event.AwayTeamImage,
|
||||||
|
LeagueID: event.LeagueID,
|
||||||
|
LeagueName: event.LeagueName,
|
||||||
|
LeagueCC: event.LeagueCC.Value,
|
||||||
|
StartTime: event.StartTime.UTC(),
|
||||||
|
Source: EventSource(event.Source),
|
||||||
|
Status: EventStatus(event.Status),
|
||||||
|
DefaultIsFeatured: event.DefaultIsFeatured,
|
||||||
|
IsMonitored: event.IsMonitored,
|
||||||
|
DefaultIsActive: event.DefaultIsActive,
|
||||||
|
DefaultWinningUpperLimit: event.DefaultWinningUpperLimit,
|
||||||
|
Score: event.Score.Value,
|
||||||
|
MatchMinute: event.MatchMinute.Value,
|
||||||
|
TimerStatus: event.TimerStatus.Value,
|
||||||
|
AddedTime: event.AddedTime.Value,
|
||||||
|
MatchPeriod: event.MatchPeriod.Value,
|
||||||
|
IsLive: event.IsLive,
|
||||||
|
FetchedAt: event.FetchedAt.UTC(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func ConvertEventResList(events []BaseEvent) []BaseEventRes {
|
||||||
|
result := make([]BaseEventRes, 0, len(events))
|
||||||
|
for _, event := range events {
|
||||||
|
result = append(result, ConvertEventRes(event))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertEventWitSettingRes(event EventWithSettings) EventWithSettingsRes {
|
||||||
|
return EventWithSettingsRes{
|
||||||
|
ID: event.ID,
|
||||||
|
SportID: event.SportID,
|
||||||
|
MatchName: event.MatchName,
|
||||||
|
HomeTeam: event.HomeTeam,
|
||||||
|
AwayTeam: event.AwayTeam,
|
||||||
|
HomeTeamID: event.HomeTeamID,
|
||||||
|
AwayTeamID: event.AwayTeamID,
|
||||||
|
HomeTeamImage: event.HomeTeamImage,
|
||||||
|
AwayTeamImage: event.AwayTeamImage,
|
||||||
|
LeagueID: event.LeagueID,
|
||||||
|
LeagueName: event.LeagueName,
|
||||||
|
LeagueCC: event.LeagueCC.Value,
|
||||||
|
StartTime: event.StartTime.UTC(),
|
||||||
|
Source: EventSource(event.Source),
|
||||||
|
Status: EventStatus(event.Status),
|
||||||
|
IsFeatured: event.IsFeatured,
|
||||||
|
IsMonitored: event.IsMonitored,
|
||||||
|
IsActive: event.IsActive,
|
||||||
|
WinningUpperLimit: event.WinningUpperLimit,
|
||||||
|
Score: event.Score.Value,
|
||||||
|
MatchMinute: event.MatchMinute.Value,
|
||||||
|
TimerStatus: event.TimerStatus.Value,
|
||||||
|
AddedTime: event.AddedTime.Value,
|
||||||
|
MatchPeriod: event.MatchPeriod.Value,
|
||||||
|
IsLive: event.IsLive,
|
||||||
|
FetchedAt: event.FetchedAt.UTC(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertEventWithSettingResList(events []EventWithSettings) []EventWithSettingsRes {
|
||||||
|
result := make([]EventWithSettingsRes, 0, len(events))
|
||||||
|
for _, event := range events {
|
||||||
|
result = append(result, ConvertEventWitSettingRes(event))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
||||||
41
internal/domain/event_history.go
Normal file
41
internal/domain/event_history.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EventHistory struct {
|
||||||
|
ID int64
|
||||||
|
EventID string
|
||||||
|
Status string
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateEventHistory struct {
|
||||||
|
EventID string
|
||||||
|
Status string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventHistoryFilter struct {
|
||||||
|
EventID ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateEventHistory(eventHistory CreateEventHistory) dbgen.InsertEventHistoryParams {
|
||||||
|
return dbgen.InsertEventHistoryParams{
|
||||||
|
EventID: eventHistory.EventID,
|
||||||
|
Status: eventHistory.Status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBEventHistory(eventHistory dbgen.EventHistory) EventHistory {
|
||||||
|
return EventHistory{
|
||||||
|
ID: eventHistory.ID,
|
||||||
|
EventID: eventHistory.EventID,
|
||||||
|
Status: eventHistory.Status,
|
||||||
|
CreatedAt: eventHistory.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
35
internal/domain/eventres.go
Normal file
35
internal/domain/eventres.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
type MatchResult struct {
|
||||||
|
EventID string
|
||||||
|
FullScore string
|
||||||
|
HalfScore string
|
||||||
|
Status string
|
||||||
|
Scores map[string]map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type B365UpcomingRes struct {
|
||||||
|
Success int `json:"success"`
|
||||||
|
Pager struct {
|
||||||
|
Page int `json:"page"`
|
||||||
|
PerPage int `json:"per_page"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
}
|
||||||
|
Results []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
SportID string `json:"sport_id"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
League struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"league"`
|
||||||
|
Home struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"home"`
|
||||||
|
Away *struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"away"`
|
||||||
|
} `json:"results"`
|
||||||
|
}
|
||||||
63
internal/domain/featured_leagues.go
Normal file
63
internal/domain/featured_leagues.go
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
// These leagues are automatically featured when the league is created
|
||||||
|
var FeaturedLeagues = []int64{
|
||||||
|
// Football
|
||||||
|
10044469, // Ethiopian Premier League
|
||||||
|
10041282, //Premier League
|
||||||
|
10083364, //La Liga
|
||||||
|
10041095, //German Bundesliga
|
||||||
|
10041100, //Ligue 1
|
||||||
|
10041809, //UEFA Champions League
|
||||||
|
10041957, //UEFA Europa League
|
||||||
|
10079560, //UEFA Conference League
|
||||||
|
10050282, //UEFA Nations League
|
||||||
|
10044685, //FIFA Club World Cup
|
||||||
|
10050346, //UEFA Super Cup
|
||||||
|
10081269, //CONCACAF Champions Cup
|
||||||
|
10070189, //CONCACAF Gold Cup
|
||||||
|
10076185, //UEFA Regions Cup
|
||||||
|
|
||||||
|
10067913, //Europe - World Cup Qualifying
|
||||||
|
10040162, //Asia - World Cup Qualifying
|
||||||
|
10067624, //South America - World Cup Qualifying
|
||||||
|
10073057, //North & Central America - World Cup Qualifying
|
||||||
|
|
||||||
|
10037075, //International Match
|
||||||
|
10077480, //Women’s International
|
||||||
|
10037109, //Europe Friendlies
|
||||||
|
10068837, //Euro U21
|
||||||
|
|
||||||
|
10041315, //Italian Serie A
|
||||||
|
10036538, //Spain Segunda
|
||||||
|
10047168, // US MLS
|
||||||
|
|
||||||
|
10043156, //England FA Cup
|
||||||
|
10042103, //France Cup
|
||||||
|
10041088, //Premier League 2
|
||||||
|
10084250, //Turkiye Super League
|
||||||
|
10041187, //Kenya Super League
|
||||||
|
10041391, //Netherlands Eredivisie
|
||||||
|
|
||||||
|
// Basketball
|
||||||
|
10041830, //NBA
|
||||||
|
10049984, //WNBA
|
||||||
|
10037165, //German Bundesliga
|
||||||
|
10036608, //Italian Lega 1
|
||||||
|
10040795, //EuroLeague
|
||||||
|
10041534, //Basketball Africa League
|
||||||
|
|
||||||
|
// Ice Hockey
|
||||||
|
10037477, //NHL
|
||||||
|
10037447, //AHL
|
||||||
|
10069385, //IIHF World Championship
|
||||||
|
|
||||||
|
// AMERICAN FOOTBALL
|
||||||
|
10037219, //NFL
|
||||||
|
|
||||||
|
// BASEBALL
|
||||||
|
10037485, // MLB
|
||||||
|
|
||||||
|
// VOLLEYBALL
|
||||||
|
10069666, //FIVB Nations League
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,24 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
type League struct {
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The ID and the Bet365 IDs we have here are both gotten from the betapi
|
||||||
|
type LeagueWithSettings struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
CompanyID int64
|
||||||
|
CountryCode ValidString
|
||||||
|
Bet365ID ValidInt32
|
||||||
|
SportID int32
|
||||||
|
IsActive bool
|
||||||
|
IsFeatured bool
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
type LeagueWithSettingsRes struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
Name string `json:"name" example:"BPL"`
|
Name string `json:"name" example:"BPL"`
|
||||||
CountryCode string `json:"cc" example:"uk"`
|
CountryCode string `json:"cc" example:"uk"`
|
||||||
|
|
@ -9,6 +27,49 @@ type League struct {
|
||||||
SportID int32 `json:"sport_id" example:"1"`
|
SportID int32 `json:"sport_id" example:"1"`
|
||||||
IsFeatured bool `json:"is_featured" example:"false"`
|
IsFeatured bool `json:"is_featured" example:"false"`
|
||||||
}
|
}
|
||||||
|
type BaseLeague struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
CountryCode ValidString
|
||||||
|
Bet365ID ValidInt32
|
||||||
|
SportID int32
|
||||||
|
DefaultIsActive bool
|
||||||
|
DefaultIsFeatured bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseLeagueRes struct {
|
||||||
|
ID int64 `json:"id" example:"1"`
|
||||||
|
Name string `json:"name" example:"BPL"`
|
||||||
|
CountryCode string `json:"cc" example:"uk"`
|
||||||
|
Bet365ID int32 `json:"bet365_id" example:"1121"`
|
||||||
|
SportID int32 `json:"sport_id" example:"1"`
|
||||||
|
DefaultIsActive bool `json:"default_is_active" example:"false"`
|
||||||
|
DefaultIsFeatured bool `json:"default_is_featured" example:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateLeague struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
CountryCode ValidString
|
||||||
|
Bet365ID ValidInt32
|
||||||
|
SportID int32
|
||||||
|
DefaultIsActive bool
|
||||||
|
DefaultIsFeatured bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type LeagueSettings struct {
|
||||||
|
CompanyID int64
|
||||||
|
LeagueID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
IsFeatured ValidBool
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
type CreateLeagueSettings struct {
|
||||||
|
CompanyID int64
|
||||||
|
LeagueID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
IsFeatured ValidBool
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateLeague struct {
|
type UpdateLeague struct {
|
||||||
ID int64 `json:"id" example:"1"`
|
ID int64 `json:"id" example:"1"`
|
||||||
|
|
@ -29,64 +90,87 @@ type LeagueFilter struct {
|
||||||
Offset ValidInt64
|
Offset ValidInt64
|
||||||
}
|
}
|
||||||
|
|
||||||
// These leagues are automatically featured when the league is created
|
func ConvertCreateLeague(league CreateLeague) dbgen.InsertLeagueParams {
|
||||||
var FeaturedLeagues = []int64{
|
return dbgen.InsertLeagueParams{
|
||||||
// Football
|
ID: league.ID,
|
||||||
10044469, // Ethiopian Premier League
|
Name: league.Name,
|
||||||
10041282, //Premier League
|
CountryCode: league.CountryCode.ToPG(),
|
||||||
10083364, //La Liga
|
Bet365ID: league.Bet365ID.ToPG(),
|
||||||
10041095, //German Bundesliga
|
SportID: league.SportID,
|
||||||
10041100, //Ligue 1
|
DefaultIsActive: league.DefaultIsActive,
|
||||||
10041809, //UEFA Champions League
|
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||||
10041957, //UEFA Europa League
|
}
|
||||||
10079560, //UEFA Conference League
|
}
|
||||||
10050282, //UEFA Nations League
|
|
||||||
10044685, //FIFA Club World Cup
|
func ConvertCreateLeagueSettings(leagueSetting CreateLeagueSettings) dbgen.InsertLeagueSettingsParams {
|
||||||
10050346, //UEFA Super Cup
|
return dbgen.InsertLeagueSettingsParams{
|
||||||
10081269, //CONCACAF Champions Cup
|
CompanyID: leagueSetting.CompanyID,
|
||||||
10070189, //CONCACAF Gold Cup
|
LeagueID: leagueSetting.LeagueID,
|
||||||
10076185, //UEFA Regions Cup
|
IsActive: leagueSetting.IsActive.ToPG(),
|
||||||
|
IsFeatured: leagueSetting.IsFeatured.ToPG(),
|
||||||
10067913, //Europe - World Cup Qualifying
|
}
|
||||||
10040162, //Asia - World Cup Qualifying
|
}
|
||||||
10067624, //South America - World Cup Qualifying
|
|
||||||
10073057, //North & Central America - World Cup Qualifying
|
func ConvertDBBaseLeague(league dbgen.League) BaseLeague {
|
||||||
|
return BaseLeague{
|
||||||
10037075, //International Match
|
ID: league.ID,
|
||||||
10077480, //Women’s International
|
Name: league.Name,
|
||||||
10037109, //Europe Friendlies
|
CountryCode: ValidString{
|
||||||
10068837, //Euro U21
|
Value: league.CountryCode.String,
|
||||||
|
Valid: league.CountryCode.Valid,
|
||||||
10041315, //Italian Serie A
|
},
|
||||||
10036538, //Spain Segunda
|
Bet365ID: ValidInt32{
|
||||||
10047168, // US MLS
|
Value: league.Bet365ID.Int32,
|
||||||
|
Valid: league.Bet365ID.Valid,
|
||||||
10043156, //England FA Cup
|
},
|
||||||
10042103, //France Cup
|
SportID: league.SportID,
|
||||||
10041088, //Premier League 2
|
DefaultIsActive: league.DefaultIsActive,
|
||||||
10084250, //Turkiye Super League
|
DefaultIsFeatured: league.DefaultIsFeatured,
|
||||||
10041187, //Kenya Super League
|
}
|
||||||
10041391, //Netherlands Eredivisie
|
}
|
||||||
|
|
||||||
// Basketball
|
func ConvertDBBaseLeagues(leagues []dbgen.League) []BaseLeague {
|
||||||
10041830, //NBA
|
result := make([]BaseLeague, len(leagues))
|
||||||
10049984, //WNBA
|
for i, league := range leagues {
|
||||||
10037165, //German Bundesliga
|
result[i] = ConvertDBBaseLeague(league)
|
||||||
10036608, //Italian Lega 1
|
}
|
||||||
10040795, //EuroLeague
|
return result
|
||||||
10041534, //Basketball Africa League
|
}
|
||||||
|
|
||||||
// Ice Hockey
|
func ConvertDBLeagueWithSetting(lws dbgen.LeagueWithSetting) LeagueWithSettings {
|
||||||
10037477, //NHL
|
return LeagueWithSettings{
|
||||||
10037447, //AHL
|
ID: lws.ID,
|
||||||
10069385, //IIHF World Championship
|
Name: lws.Name,
|
||||||
|
CompanyID: lws.CompanyID,
|
||||||
// AMERICAN FOOTBALL
|
CountryCode: ValidString{
|
||||||
10037219, //NFL
|
Value: lws.CountryCode.String,
|
||||||
|
Valid: lws.CountryCode.Valid,
|
||||||
// BASEBALL
|
},
|
||||||
10037485, // MLB
|
Bet365ID: ValidInt32{
|
||||||
|
Value: lws.Bet365ID.Int32,
|
||||||
// VOLLEYBALL
|
Valid: lws.Bet365ID.Valid,
|
||||||
10069666, //FIVB Nations League
|
},
|
||||||
|
IsActive: lws.IsActive,
|
||||||
|
SportID: lws.SportID,
|
||||||
|
IsFeatured: lws.IsFeatured,
|
||||||
|
UpdatedAt: lws.UpdatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBLeagueWithSettings(lws []dbgen.LeagueWithSetting) []LeagueWithSettings {
|
||||||
|
result := make([]LeagueWithSettings, len(lws))
|
||||||
|
for i, league := range lws {
|
||||||
|
result[i] = ConvertDBLeagueWithSetting(league)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertUpdateLeague(updateLeague UpdateLeague) dbgen.UpdateLeagueParams {
|
||||||
|
return dbgen.UpdateLeagueParams{
|
||||||
|
ID: updateLeague.ID,
|
||||||
|
Name: updateLeague.Name.ToPG(),
|
||||||
|
CountryCode: updateLeague.CountryCode.ToPG(),
|
||||||
|
Bet365ID: updateLeague.Bet365ID.ToPG(),
|
||||||
|
SportID: updateLeague.SportID.ToPG(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ type RawOdd struct {
|
||||||
|
|
||||||
// The Market ID for the json data can be either string / int which is causing problems when UnMarshalling
|
// The Market ID for the json data can be either string / int which is causing problems when UnMarshalling
|
||||||
type OddsMarket struct {
|
type OddsMarket struct {
|
||||||
ID NullableInt64JSON `json:"id"`
|
ID ValidInt64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Odds []json.RawMessage `json:"odds"`
|
Odds []json.RawMessage `json:"odds"`
|
||||||
Header string `json:"header,omitempty"`
|
Header string `json:"header,omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,186 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RawMessage interface{}
|
type CreateOddMarket struct {
|
||||||
|
|
||||||
type Market struct {
|
|
||||||
EventID string
|
EventID string
|
||||||
FI string
|
|
||||||
MarketCategory string
|
MarketCategory string
|
||||||
MarketType string
|
MarketType string
|
||||||
MarketName string
|
MarketName string
|
||||||
MarketID string
|
MarketID string
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
Odds []map[string]interface{}
|
Odds []map[string]interface{}
|
||||||
Name string
|
|
||||||
Handicap string
|
|
||||||
OddsVal float64
|
|
||||||
Source string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Odd struct {
|
type OddMarket struct {
|
||||||
EventID string `json:"event_id"`
|
ID int64 `json:"id"`
|
||||||
Fi string `json:"fi"`
|
EventID string `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 string `json:"market_id"`
|
MarketID string `json:"market_id"`
|
||||||
Name string `json:"name"`
|
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||||
Handicap string `json:"handicap"`
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
OddsValue float64 `json:"odds_value"`
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
Section string `json:"section"`
|
DefaultIsActive bool `json:"is_active"`
|
||||||
Category string `json:"category"`
|
IsMonitored bool `json:"is_monitored"`
|
||||||
RawOdds []RawMessage `json:"raw_odds"`
|
IsLive bool `json:"is_live"`
|
||||||
FetchedAt time.Time `json:"fetched_at"`
|
Status EventStatus `json:"status"`
|
||||||
Source string `json:"source"`
|
Source EventSource `json:"source"`
|
||||||
IsActive bool `json:"is_active"`
|
|
||||||
}
|
}
|
||||||
type RawOddsByMarketID struct {
|
type OddMarketWithSettings struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
MarketName string `json:"market_name"`
|
EventID string `json:"event_id"`
|
||||||
Handicap string `json:"handicap"`
|
MarketType string `json:"market_type"`
|
||||||
RawOdds []RawMessage `json:"raw_odds"`
|
MarketName string `json:"market_name"`
|
||||||
FetchedAt time.Time `json:"fetched_at"`
|
MarketCategory string `json:"market_category"`
|
||||||
|
MarketID string `json:"market_id"`
|
||||||
|
RawOdds []json.RawMessage `json:"raw_odds"`
|
||||||
|
FetchedAt time.Time `json:"fetched_at"`
|
||||||
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OddMarketSettings struct {
|
||||||
|
CompanyID int64
|
||||||
|
OddMarketID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
CustomRawOdds string
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
type CreateOddMarketSettings struct {
|
||||||
|
CompanyID int64
|
||||||
|
OddMarketID int64
|
||||||
|
IsActive ValidBool
|
||||||
|
CustomRawOdds []map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// type RawOddsByMarketID struct {
|
||||||
|
// ID int64 `json:"id"`
|
||||||
|
// MarketName string `json:"market_name"`
|
||||||
|
// Handicap string `json:"handicap"`
|
||||||
|
// RawOdds []json.RawMessage `json:"raw_odds"`
|
||||||
|
// FetchedAt time.Time `json:"fetched_at"`
|
||||||
|
// ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
type OddMarketFilter struct {
|
||||||
|
Limit ValidInt32
|
||||||
|
Offset ValidInt32
|
||||||
|
}
|
||||||
|
type OddMarketWithEventFilter struct {
|
||||||
|
Limit ValidInt32
|
||||||
|
Offset ValidInt32
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOddMarket(oddMarket dbgen.OddsMarketWithEvent) (OddMarket, error) {
|
||||||
|
var rawOdds []json.RawMessage
|
||||||
|
if len(oddMarket.RawOdds) > 0 {
|
||||||
|
if err := json.Unmarshal(oddMarket.RawOdds, &rawOdds); err != nil {
|
||||||
|
return OddMarket{}, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||||
|
}
|
||||||
|
return OddMarket{
|
||||||
|
ID: oddMarket.ID,
|
||||||
|
EventID: oddMarket.EventID,
|
||||||
|
MarketType: oddMarket.MarketType,
|
||||||
|
MarketName: oddMarket.MarketName,
|
||||||
|
MarketCategory: oddMarket.MarketCategory,
|
||||||
|
MarketID: oddMarket.MarketID,
|
||||||
|
RawOdds: rawOdds,
|
||||||
|
FetchedAt: oddMarket.FetchedAt.Time,
|
||||||
|
ExpiresAt: oddMarket.ExpiresAt.Time,
|
||||||
|
DefaultIsActive: oddMarket.DefaultIsActive,
|
||||||
|
IsMonitored: oddMarket.IsMonitored,
|
||||||
|
IsLive: oddMarket.IsLive,
|
||||||
|
Status: EventStatus(oddMarket.Status),
|
||||||
|
Source: EventSource(oddMarket.Source),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOddMarkets(oddMarkets []dbgen.OddsMarketWithEvent) ([]OddMarket, error) {
|
||||||
|
result := make([]OddMarket, len(oddMarkets))
|
||||||
|
for i, om := range oddMarkets {
|
||||||
|
convertedMarket, err := ConvertDBOddMarket(om)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result[i] = convertedMarket
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateOddMarket(oddMarket CreateOddMarket) (dbgen.InsertOddsMarketParams, error) {
|
||||||
|
rawOddsBytes, err := json.Marshal(oddMarket.Odds)
|
||||||
|
if err != nil {
|
||||||
|
return dbgen.InsertOddsMarketParams{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbgen.InsertOddsMarketParams{
|
||||||
|
EventID: oddMarket.EventID,
|
||||||
|
MarketType: oddMarket.MarketType,
|
||||||
|
MarketName: oddMarket.MarketName,
|
||||||
|
MarketCategory: oddMarket.MarketCategory,
|
||||||
|
MarketID: oddMarket.MarketID,
|
||||||
|
RawOdds: rawOddsBytes,
|
||||||
|
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
||||||
|
ExpiresAt: pgtype.Timestamp{Time: (time.Now()).Add(time.Hour), Valid: true},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateOddMarketSetting(oms CreateOddMarketSettings) (dbgen.InsertOddSettingsParams, error) {
|
||||||
|
rawOddsBytes, err := json.Marshal(oms.CustomRawOdds)
|
||||||
|
if err != nil {
|
||||||
|
return dbgen.InsertOddSettingsParams{}, err
|
||||||
|
}
|
||||||
|
return dbgen.InsertOddSettingsParams{
|
||||||
|
CompanyID: oms.CompanyID,
|
||||||
|
OddsMarketID: oms.OddMarketID,
|
||||||
|
IsActive: oms.IsActive.ToPG(),
|
||||||
|
CustomRawOdds: rawOddsBytes,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOddMarketWithSetting(oms dbgen.OddsMarketWithSetting) (OddMarketWithSettings, error) {
|
||||||
|
var rawOdds []json.RawMessage
|
||||||
|
if len(oms.RawOdds) > 0 {
|
||||||
|
if err := json.Unmarshal(oms.RawOdds, &rawOdds); err != nil {
|
||||||
|
return OddMarketWithSettings{}, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rawOdds = []json.RawMessage{} // explicit empty slice
|
||||||
|
}
|
||||||
|
return OddMarketWithSettings{
|
||||||
|
ID: oms.ID,
|
||||||
|
EventID: oms.EventID,
|
||||||
|
MarketType: oms.MarketType,
|
||||||
|
MarketName: oms.MarketName,
|
||||||
|
MarketCategory: oms.MarketCategory,
|
||||||
|
MarketID: oms.MarketID,
|
||||||
|
RawOdds: rawOdds,
|
||||||
|
FetchedAt: oms.FetchedAt.Time,
|
||||||
|
ExpiresAt: oms.ExpiresAt.Time,
|
||||||
|
IsActive: oms.IsActive,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOddMarketWithSettings(oms []dbgen.OddsMarketWithSetting) ([]OddMarketWithSettings, error) {
|
||||||
|
result := make([]OddMarketWithSettings, len(oms))
|
||||||
|
for i, o := range oms {
|
||||||
|
converted, err := ConvertDBOddMarketWithSetting(o)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result[i] = converted
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
64
internal/domain/odds_history.go
Normal file
64
internal/domain/odds_history.go
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OddHistory struct {
|
||||||
|
ID int64
|
||||||
|
OddID int64
|
||||||
|
MarketID string
|
||||||
|
RawOddID int64
|
||||||
|
EventID string
|
||||||
|
OddValue float64
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateOddHistory struct {
|
||||||
|
OddID int64
|
||||||
|
MarketID string
|
||||||
|
RawOddID int64
|
||||||
|
EventID string
|
||||||
|
OddValue float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type OddHistoryFilter struct {
|
||||||
|
OddID ValidInt64
|
||||||
|
MarketID ValidString
|
||||||
|
RawOddID ValidInt64
|
||||||
|
EventID ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateOddHistory(odd CreateOddHistory) dbgen.InsertOddHistoryParams {
|
||||||
|
return dbgen.InsertOddHistoryParams{
|
||||||
|
OddsMarketID: odd.OddID,
|
||||||
|
MarketID: odd.MarketID,
|
||||||
|
RawOddID: odd.RawOddID,
|
||||||
|
EventID: odd.EventID,
|
||||||
|
OddValue: odd.OddValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOddHistory(dbOddHistory dbgen.OddHistory) OddHistory {
|
||||||
|
return OddHistory{
|
||||||
|
ID: dbOddHistory.ID,
|
||||||
|
OddID: dbOddHistory.OddsMarketID,
|
||||||
|
MarketID: dbOddHistory.MarketID,
|
||||||
|
RawOddID: dbOddHistory.RawOddID,
|
||||||
|
EventID: dbOddHistory.EventID,
|
||||||
|
OddValue: dbOddHistory.OddValue,
|
||||||
|
CreatedAt: dbOddHistory.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertOddHistories(list []dbgen.OddHistory) []OddHistory {
|
||||||
|
result := make([]OddHistory, 0, len(list))
|
||||||
|
for _, item := range list {
|
||||||
|
result = append(result, ConvertDBOddHistory(item))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MarketConfig struct {
|
type MarketConfig struct {
|
||||||
|
|
@ -21,7 +23,7 @@ type Result struct {
|
||||||
FullTimeScore string
|
FullTimeScore string
|
||||||
HalfTimeScore string
|
HalfTimeScore string
|
||||||
SS string
|
SS string
|
||||||
Scores map[string]Score
|
Scores map[string]ScoreResultResponse
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
@ -83,22 +85,78 @@ const (
|
||||||
TIME_STATUS_REMOVED TimeStatus = 99
|
TIME_STATUS_REMOVED TimeStatus = 99
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResultStatusCounts struct {
|
type ResultLog struct {
|
||||||
IsNotFinished int `json:"is_not_finished"`
|
ID int64 `json:"id"`
|
||||||
IsNotFinishedBets int `json:"is_not_finished_bets"`
|
StatusNotFinishedCount int `json:"status_not_finished_count"`
|
||||||
IsToBeFixed int `json:"is_to_be_fixed"`
|
StatusNotFinishedBets int `json:"status_not_finished_bets"`
|
||||||
IsToBeFixedBets int `json:"is_to_be_fixed_bets"`
|
StatusToBeFixedCount int `json:"status_to_be_fixed_count"`
|
||||||
IsPostponed int `json:"is_postponed"`
|
StatusToBeFixedBets int `json:"status_to_be_fixed_bets"`
|
||||||
IsPostponedBets int `json:"is_postponed_bets"`
|
StatusPostponedCount int `json:"status_postponed_count"`
|
||||||
IsEnded int `json:"is_ended"`
|
StatusPostponedBets int `json:"status_postponed_bets"`
|
||||||
IsEndedBets int `json:"is_ended_bets"`
|
StatusEndedCount int `json:"status_ended_count"`
|
||||||
IsRemoved int `json:"is_removed"`
|
StatusEndedBets int `json:"status_ended_bets"`
|
||||||
IsRemovedBets int `json:"is_removed_bets"`
|
StatusRemovedCount int `json:"status_removed_count"`
|
||||||
|
StatusRemovedBets int `json:"status_removed_bets"`
|
||||||
|
RemovedCount int `json:"removed"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateResultLog struct {
|
||||||
|
StatusNotFinishedCount int `json:"status_not_finished_count"`
|
||||||
|
StatusNotFinishedBets int `json:"status_not_finished_bets"`
|
||||||
|
StatusToBeFixedCount int `json:"status_to_be_fixed_count"`
|
||||||
|
StatusToBeFixedBets int `json:"status_to_be_fixed_bets"`
|
||||||
|
StatusPostponedCount int `json:"status_postponed_count"`
|
||||||
|
StatusPostponedBets int `json:"status_postponed_bets"`
|
||||||
|
StatusEndedCount int `json:"status_ended_count"`
|
||||||
|
StatusEndedBets int `json:"status_ended_bets"`
|
||||||
|
StatusRemovedCount int `json:"status_removed_count"`
|
||||||
|
StatusRemovedBets int `json:"status_removed_bets"`
|
||||||
|
RemovedCount int `json:"removed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResultFilter struct {
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
}
|
}
|
||||||
type ResultStatusBets struct {
|
type ResultStatusBets struct {
|
||||||
IsNotFinished []int64 `json:"is_not_finished"`
|
StatusNotFinished []int64 `json:"status_not_finished"`
|
||||||
IsToBeFixed []int64 `json:"is_to_be_fixed"`
|
StatusToBeFixed []int64 `json:"status_to_be_fixed"`
|
||||||
IsPostponed []int64 `json:"is_postponed"`
|
StatusPostponed []int64 `json:"status_postponed"`
|
||||||
IsEnded []int64 `json:"is_ended"`
|
StatusEnded []int64 `json:"status_ended"`
|
||||||
IsRemoved []int64 `json:"is_removed"`
|
StatusRemoved []int64 `json:"status_removed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBResultLog(result dbgen.ResultLog) ResultLog {
|
||||||
|
return ResultLog{
|
||||||
|
ID: result.ID,
|
||||||
|
StatusNotFinishedCount: int(result.StatusNotFinishedCount),
|
||||||
|
StatusNotFinishedBets: int(result.StatusNotFinishedBets),
|
||||||
|
StatusToBeFixedCount: int(result.StatusToBeFixedCount),
|
||||||
|
StatusToBeFixedBets: int(result.StatusToBeFixedBets),
|
||||||
|
StatusPostponedCount: int(result.StatusPostponedCount),
|
||||||
|
StatusPostponedBets: int(result.StatusPostponedBets),
|
||||||
|
StatusEndedCount: int(result.StatusEndedCount),
|
||||||
|
StatusEndedBets: int(result.StatusEndedBets),
|
||||||
|
StatusRemovedCount: int(result.StatusRemovedCount),
|
||||||
|
StatusRemovedBets: int(result.StatusRemovedBets),
|
||||||
|
RemovedCount: int(result.RemovedCount),
|
||||||
|
CreatedAt: result.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCreateResultLog(result CreateResultLog) dbgen.CreateResultLogParams {
|
||||||
|
return dbgen.CreateResultLogParams{
|
||||||
|
StatusNotFinishedCount: int32(result.StatusNotFinishedCount),
|
||||||
|
StatusNotFinishedBets: int32(result.StatusNotFinishedBets),
|
||||||
|
StatusToBeFixedCount: int32(result.StatusToBeFixedCount),
|
||||||
|
StatusToBeFixedBets: int32(result.StatusToBeFixedBets),
|
||||||
|
StatusPostponedCount: int32(result.StatusPostponedCount),
|
||||||
|
StatusPostponedBets: int32(result.StatusPostponedBets),
|
||||||
|
StatusEndedCount: int32(result.StatusEndedCount),
|
||||||
|
StatusEndedBets: int32(result.StatusEndedBets),
|
||||||
|
StatusRemovedCount: int32(result.StatusRemovedCount),
|
||||||
|
StatusRemovedBets: int32(result.StatusRemovedBets),
|
||||||
|
RemovedCount: int32(result.RemovedCount),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,47 +9,47 @@ type BaseResultResponse struct {
|
||||||
Results []json.RawMessage `json:"results"`
|
Results []json.RawMessage `json:"results"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LeagueRes struct {
|
type LeagueResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CC string `json:"cc"`
|
CC string `json:"cc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Team struct {
|
type TeamResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ImageID NullableInt64JSON `json:"image_id"`
|
ImageID ValidInt64 `json:"image_id"`
|
||||||
CC string `json:"cc"`
|
CC string `json:"cc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Score struct {
|
type ScoreResultResponse struct {
|
||||||
Home string `json:"home"`
|
Home string `json:"home"`
|
||||||
Away string `json:"away"`
|
Away string `json:"away"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommonResultResponse struct {
|
type CommonResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
SportID string `json:"sport_id"`
|
SportID string `json:"sport_id"`
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
TimeStatus NullableInt64JSON `json:"time_status"`
|
TimeStatus ValidInt64 `json:"time_status"`
|
||||||
League LeagueRes `json:"league"`
|
League LeagueResultResponse `json:"league"`
|
||||||
Home Team `json:"home"`
|
Home TeamResultResponse `json:"home"`
|
||||||
Away Team `json:"away"`
|
Away TeamResultResponse `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FootballResultResponse struct {
|
type FootballResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
SportID string `json:"sport_id"`
|
SportID string `json:"sport_id"`
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
TimeStatus string `json:"time_status"`
|
TimeStatus string `json:"time_status"`
|
||||||
League LeagueRes `json:"league"`
|
League LeagueResultResponse `json:"league"`
|
||||||
Home Team `json:"home"`
|
Home TeamResultResponse `json:"home"`
|
||||||
Away Team `json:"away"`
|
Away TeamResultResponse `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstHalf Score `json:"1"`
|
FirstHalf ScoreResultResponse `json:"1"`
|
||||||
SecondHalf Score `json:"2"`
|
SecondHalf ScoreResultResponse `json:"2"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
Attacks []string `json:"attacks"`
|
Attacks []string `json:"attacks"`
|
||||||
|
|
@ -78,21 +78,21 @@ type FootballResultResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BasketballResultResponse struct {
|
type BasketballResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
SportID string `json:"sport_id"`
|
SportID string `json:"sport_id"`
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
TimeStatus string `json:"time_status"`
|
TimeStatus string `json:"time_status"`
|
||||||
League LeagueRes `json:"league"`
|
League LeagueResultResponse `json:"league"`
|
||||||
Home Team `json:"home"`
|
Home TeamResultResponse `json:"home"`
|
||||||
Away Team `json:"away"`
|
Away TeamResultResponse `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstQuarter Score `json:"1"`
|
FirstQuarter ScoreResultResponse `json:"1"`
|
||||||
SecondQuarter Score `json:"2"`
|
SecondQuarter ScoreResultResponse `json:"2"`
|
||||||
FirstHalf Score `json:"3"`
|
FirstHalf ScoreResultResponse `json:"3"`
|
||||||
ThirdQuarter Score `json:"4"`
|
ThirdQuarter ScoreResultResponse `json:"4"`
|
||||||
FourthQuarter Score `json:"5"`
|
FourthQuarter ScoreResultResponse `json:"5"`
|
||||||
TotalScore Score `json:"7"`
|
TotalScore ScoreResultResponse `json:"7"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
TwoPoints []string `json:"2points"`
|
TwoPoints []string `json:"2points"`
|
||||||
|
|
@ -125,19 +125,19 @@ type BasketballResultResponse struct {
|
||||||
Bet365ID string `json:"bet365_id"`
|
Bet365ID string `json:"bet365_id"`
|
||||||
}
|
}
|
||||||
type IceHockeyResultResponse struct {
|
type IceHockeyResultResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
SportID string `json:"sport_id"`
|
SportID string `json:"sport_id"`
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
TimeStatus string `json:"time_status"`
|
TimeStatus string `json:"time_status"`
|
||||||
League LeagueRes `json:"league"`
|
League LeagueResultResponse `json:"league"`
|
||||||
Home Team `json:"home"`
|
Home TeamResultResponse `json:"home"`
|
||||||
Away Team `json:"away"`
|
Away TeamResultResponse `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstPeriod Score `json:"1"`
|
FirstPeriod ScoreResultResponse `json:"1"`
|
||||||
SecondPeriod Score `json:"2"`
|
SecondPeriod ScoreResultResponse `json:"2"`
|
||||||
ThirdPeriod Score `json:"3"`
|
ThirdPeriod ScoreResultResponse `json:"3"`
|
||||||
TotalScore Score `json:"5"`
|
TotalScore ScoreResultResponse `json:"5"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
|
|
||||||
Stats struct {
|
Stats struct {
|
||||||
|
|
@ -222,11 +222,11 @@ type VolleyballResultResponse struct {
|
||||||
} `json:"away"`
|
} `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstSet Score `json:"1"`
|
FirstSet ScoreResultResponse `json:"1"`
|
||||||
SecondSet Score `json:"2"`
|
SecondSet ScoreResultResponse `json:"2"`
|
||||||
ThirdSet Score `json:"3"`
|
ThirdSet ScoreResultResponse `json:"3"`
|
||||||
FourthSet Score `json:"4"`
|
FourthSet ScoreResultResponse `json:"4"`
|
||||||
FivethSet Score `json:"5"`
|
FivethSet ScoreResultResponse `json:"5"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
PointsWonOnServe []string `json:"points_won_on_serve"`
|
PointsWonOnServe []string `json:"points_won_on_serve"`
|
||||||
|
|
@ -290,10 +290,10 @@ type FutsalResultResponse struct {
|
||||||
} `json:"away"`
|
} `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstPeriod Score `json:"1"`
|
FirstPeriod ScoreResultResponse `json:"1"`
|
||||||
SecondPeriod Score `json:"2"`
|
SecondPeriod ScoreResultResponse `json:"2"`
|
||||||
ThirdPeriod Score `json:"3"`
|
ThirdPeriod ScoreResultResponse `json:"3"`
|
||||||
TotalScore Score `json:"4"`
|
TotalScore ScoreResultResponse `json:"4"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Events []map[string]string `json:"events"`
|
Events []map[string]string `json:"events"`
|
||||||
InplayCreatedAt string `json:"inplay_created_at"`
|
InplayCreatedAt string `json:"inplay_created_at"`
|
||||||
|
|
@ -327,12 +327,12 @@ type NFLResultResponse struct {
|
||||||
} `json:"away"`
|
} `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstQuarter Score `json:"1"`
|
FirstQuarter ScoreResultResponse `json:"1"`
|
||||||
SecondQuarter Score `json:"2"`
|
SecondQuarter ScoreResultResponse `json:"2"`
|
||||||
ThirdQuarter Score `json:"3"`
|
ThirdQuarter ScoreResultResponse `json:"3"`
|
||||||
FourthQuarter Score `json:"4"`
|
FourthQuarter ScoreResultResponse `json:"4"`
|
||||||
Overtime Score `json:"5"`
|
Overtime ScoreResultResponse `json:"5"`
|
||||||
TotalScore Score `json:"7"`
|
TotalScore ScoreResultResponse `json:"7"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
FirstDowns []string `json:"first_downs"`
|
FirstDowns []string `json:"first_downs"`
|
||||||
|
|
@ -381,9 +381,9 @@ type RugbyResultResponse struct {
|
||||||
} `json:"away"`
|
} `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstHalf Score `json:"1"`
|
FirstHalf ScoreResultResponse `json:"1"`
|
||||||
SecondHalf Score `json:"2"`
|
SecondHalf ScoreResultResponse `json:"2"`
|
||||||
TotalScore Score `json:"7"`
|
TotalScore ScoreResultResponse `json:"7"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
Tries []string `json:"tries"`
|
Tries []string `json:"tries"`
|
||||||
|
|
@ -433,17 +433,17 @@ type BaseballResultResponse struct {
|
||||||
} `json:"away"`
|
} `json:"away"`
|
||||||
SS string `json:"ss"`
|
SS string `json:"ss"`
|
||||||
Scores struct {
|
Scores struct {
|
||||||
FirstInning Score `json:"1"`
|
FirstInning ScoreResultResponse `json:"1"`
|
||||||
SecondInning Score `json:"2"`
|
SecondInning ScoreResultResponse `json:"2"`
|
||||||
ThirdInning Score `json:"3"`
|
ThirdInning ScoreResultResponse `json:"3"`
|
||||||
FourthInning Score `json:"4"`
|
FourthInning ScoreResultResponse `json:"4"`
|
||||||
FifthInning Score `json:"5"`
|
FifthInning ScoreResultResponse `json:"5"`
|
||||||
SixthInning Score `json:"6"`
|
SixthInning ScoreResultResponse `json:"6"`
|
||||||
SeventhInning Score `json:"7"`
|
SeventhInning ScoreResultResponse `json:"7"`
|
||||||
EighthInning Score `json:"8"`
|
EighthInning ScoreResultResponse `json:"8"`
|
||||||
NinthInning Score `json:"9"`
|
NinthInning ScoreResultResponse `json:"9"`
|
||||||
ExtraInnings Score `json:"10"`
|
ExtraInnings ScoreResultResponse `json:"10"`
|
||||||
TotalScore Score `json:"11"`
|
TotalScore ScoreResultResponse `json:"11"`
|
||||||
} `json:"scores"`
|
} `json:"scores"`
|
||||||
Stats struct {
|
Stats struct {
|
||||||
Hits []string `json:"hits"`
|
Hits []string `json:"hits"`
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,12 @@ const (
|
||||||
RoleCustomer Role = "customer"
|
RoleCustomer Role = "customer"
|
||||||
RoleCashier Role = "cashier"
|
RoleCashier Role = "cashier"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (r Role) IsValid() bool {
|
||||||
|
switch r {
|
||||||
|
case RoleSuperAdmin, RoleAdmin, RoleBranchManager, RoleCustomer, RoleCashier:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
447
internal/domain/setting_list.go
Normal file
447
internal/domain/setting_list.go
Normal file
|
|
@ -0,0 +1,447 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrSettingNotFound = errors.New("cannot find setting in list")
|
||||||
|
)
|
||||||
|
|
||||||
|
type SettingList struct {
|
||||||
|
SMSProvider SMSProvider `json:"sms_provider"`
|
||||||
|
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
||||||
|
BetAmountLimit Currency `json:"bet_amount_limit"`
|
||||||
|
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
||||||
|
TotalWinningLimit Currency `json:"total_winning_limit"`
|
||||||
|
AmountForBetReferral Currency `json:"amount_for_bet_referral"`
|
||||||
|
CashbackAmountCap Currency `json:"cashback_amount_cap"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SettingListRes struct {
|
||||||
|
SMSProvider SMSProvider `json:"sms_provider"`
|
||||||
|
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
||||||
|
BetAmountLimit float32 `json:"bet_amount_limit"`
|
||||||
|
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
||||||
|
TotalWinningLimit float32 `json:"total_winning_limit"`
|
||||||
|
AmountForBetReferral float32 `json:"amount_for_bet_referral"`
|
||||||
|
CashbackAmountCap float32 `json:"cashback_amount_cap"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SaveSettingListReq struct {
|
||||||
|
SMSProvider *string `json:"sms_provider,omitempty"`
|
||||||
|
MaxNumberOfOutcomes *int64 `json:"max_number_of_outcomes,omitempty"`
|
||||||
|
BetAmountLimit *float32 `json:"bet_amount_limit,omitempty"`
|
||||||
|
DailyTicketPerIP *int64 `json:"daily_ticket_limit,omitempty"`
|
||||||
|
TotalWinningLimit *float32 `json:"total_winning_limit,omitempty"`
|
||||||
|
AmountForBetReferral *float32 `json:"amount_for_bet_referral,omitempty"`
|
||||||
|
CashbackAmountCap *float32 `json:"cashback_amount_cap,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertSaveSettingListReq(settings SaveSettingListReq) ValidSettingList {
|
||||||
|
return ValidSettingList{
|
||||||
|
SMSProvider: ConvertStringPtr(settings.SMSProvider),
|
||||||
|
MaxNumberOfOutcomes: ConvertInt64Ptr(settings.MaxNumberOfOutcomes),
|
||||||
|
BetAmountLimit: ConvertFloat32PtrToCurrency(settings.BetAmountLimit),
|
||||||
|
DailyTicketPerIP: ConvertInt64Ptr(settings.DailyTicketPerIP),
|
||||||
|
TotalWinningLimit: ConvertFloat32PtrToCurrency(settings.TotalWinningLimit),
|
||||||
|
AmountForBetReferral: ConvertFloat32PtrToCurrency(settings.AmountForBetReferral),
|
||||||
|
CashbackAmountCap: ConvertFloat32PtrToCurrency(settings.CashbackAmountCap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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{
|
||||||
|
SMSProvider: SMSProvider(vsl.SMSProvider.Value),
|
||||||
|
MaxNumberOfOutcomes: vsl.MaxNumberOfOutcomes.Value,
|
||||||
|
BetAmountLimit: Currency(vsl.BetAmountLimit.Value),
|
||||||
|
DailyTicketPerIP: vsl.DailyTicketPerIP.Value,
|
||||||
|
TotalWinningLimit: Currency(vsl.TotalWinningLimit.Value),
|
||||||
|
AmountForBetReferral: Currency(vsl.AmountForBetReferral.Value),
|
||||||
|
CashbackAmountCap: Currency(vsl.CashbackAmountCap.Value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom Validations for non-generic types
|
||||||
|
func (vsl *ValidSettingList) CustomValidationSettings() error {
|
||||||
|
if !SMSProvider(vsl.SMSProvider.Value).IsValid() {
|
||||||
|
return fmt.Errorf("sms provider invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetInt64SettingsMap() map[string]*ValidInt64 {
|
||||||
|
return map[string]*ValidInt64{
|
||||||
|
"max_number_of_outcomes": &vsl.MaxNumberOfOutcomes,
|
||||||
|
"daily_ticket_limit": &vsl.DailyTicketPerIP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetCurrencySettingsMap() map[string]*ValidCurrency {
|
||||||
|
return map[string]*ValidCurrency{
|
||||||
|
"bet_amount_limit": &vsl.BetAmountLimit,
|
||||||
|
"total_winnings_limit": &vsl.TotalWinningLimit,
|
||||||
|
"amount_for_bet_referral": &vsl.AmountForBetReferral,
|
||||||
|
"cashback_amount_cap": &vsl.CashbackAmountCap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetStringSettingsMap() map[string]*ValidString {
|
||||||
|
return map[string]*ValidString{
|
||||||
|
"sms_provider": &vsl.SMSProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetBoolSettingsMap() map[string]*ValidBool {
|
||||||
|
return map[string]*ValidBool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetFloat32SettingsMap() map[string]*ValidFloat32 {
|
||||||
|
return map[string]*ValidFloat32{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetTimeSettingsMap() map[string]*ValidTime {
|
||||||
|
return map[string]*ValidTime{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetTotalSettings() int {
|
||||||
|
return len(vsl.GetInt64SettingsMap()) +
|
||||||
|
len(vsl.GetCurrencySettingsMap()) +
|
||||||
|
len(vsl.GetStringSettingsMap()) +
|
||||||
|
len(vsl.GetBoolSettingsMap()) +
|
||||||
|
len(vsl.GetFloat32SettingsMap()) +
|
||||||
|
len(vsl.GetTimeSettingsMap())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) GetAllValid() map[string]*bool {
|
||||||
|
|
||||||
|
settingValid := make(map[string]*bool)
|
||||||
|
|
||||||
|
for key, setting := range vsl.GetInt64SettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
for key, setting := range vsl.GetCurrencySettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
for key, setting := range vsl.GetStringSettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
for key, setting := range vsl.GetBoolSettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
for key, setting := range vsl.GetFloat32SettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
for key, setting := range vsl.GetTimeSettingsMap() {
|
||||||
|
settingValid[key] = &(*setting).Valid
|
||||||
|
}
|
||||||
|
|
||||||
|
return settingValid
|
||||||
|
}
|
||||||
|
|
||||||
|
func setValidSetting[T any](settings map[string]*T, searchKey string, setVal T) error {
|
||||||
|
for key, setting := range settings {
|
||||||
|
if key == searchKey {
|
||||||
|
*setting = setVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrSettingNotFound
|
||||||
|
}
|
||||||
|
func (vsl *ValidSettingList) SetInt64Setting(searchKey string, searchVal string) error {
|
||||||
|
value, err := strconv.ParseInt(searchVal, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return setValidSetting(vsl.GetInt64SettingsMap(), searchKey, ValidInt64{Value: value, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetCurrencySetting(searchKey string, searchVal string) error {
|
||||||
|
value, err := strconv.ParseInt(searchVal, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return setValidSetting(vsl.GetCurrencySettingsMap(), searchKey, ValidCurrency{Value: Currency(value), Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetStringSetting(searchKey string, searchVal string) error {
|
||||||
|
return setValidSetting(vsl.GetStringSettingsMap(), searchKey, ValidString{Value: searchVal, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetBoolSetting(searchKey string, searchVal string) error {
|
||||||
|
value, err := strconv.ParseBool(searchVal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return setValidSetting(vsl.GetBoolSettingsMap(), searchKey, ValidBool{Value: value, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetFloat32Setting(searchKey string, searchVal string) error {
|
||||||
|
value, err := strconv.ParseFloat(searchVal, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return setValidSetting(vsl.GetFloat32SettingsMap(), searchKey, ValidFloat32{Value: float32(value), Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetTimeSetting(searchKey string, searchVal string) error {
|
||||||
|
value, err := time.Parse(time.RFC3339, searchVal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return setValidSetting(vsl.GetTimeSettingsMap(), searchKey, ValidTime{Value: value, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) SetSetting(searchKey string, searchVal string) error {
|
||||||
|
setters := []func(string, string) error{
|
||||||
|
vsl.SetInt64Setting,
|
||||||
|
vsl.SetCurrencySetting,
|
||||||
|
vsl.SetStringSetting,
|
||||||
|
vsl.SetBoolSetting,
|
||||||
|
vsl.SetFloat32Setting,
|
||||||
|
vsl.SetTimeSetting,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, setter := range setters {
|
||||||
|
if err := setter(searchKey, searchVal); err != nil {
|
||||||
|
if err == ErrSettingNotFound {
|
||||||
|
continue // not this setter, try the next
|
||||||
|
}
|
||||||
|
return fmt.Errorf("error while processing setting %q: %w", searchKey, err)
|
||||||
|
}
|
||||||
|
return nil // successfully set
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, none of the setters matched
|
||||||
|
return ErrSettingNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertValidSettings[T any](
|
||||||
|
settings map[string]*T,
|
||||||
|
isValid func(*T) bool,
|
||||||
|
toString func(*T) string,
|
||||||
|
) []Setting {
|
||||||
|
result := make([]Setting, 0, len(settings))
|
||||||
|
for key, s := range settings {
|
||||||
|
if isValid(s) {
|
||||||
|
result = append(result, Setting{
|
||||||
|
Key: key,
|
||||||
|
Value: toString(s),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertInt64Settings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetInt64SettingsMap(),
|
||||||
|
func(s *ValidInt64) bool { return s.Valid },
|
||||||
|
func(s *ValidInt64) string { return strconv.FormatInt(s.Value, 10) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertCurrencySettings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetCurrencySettingsMap(),
|
||||||
|
func(s *ValidCurrency) bool { return s.Valid },
|
||||||
|
func(s *ValidCurrency) string { return strconv.FormatInt(int64(s.Value), 10) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertStringSettings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetStringSettingsMap(),
|
||||||
|
func(s *ValidString) bool { return s.Valid },
|
||||||
|
func(s *ValidString) string { return s.Value },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertBoolSettings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetBoolSettingsMap(),
|
||||||
|
func(s *ValidBool) bool { return s.Valid },
|
||||||
|
func(s *ValidBool) string { return strconv.FormatBool(s.Value) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertFloat32Settings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetFloat32SettingsMap(),
|
||||||
|
func(s *ValidFloat32) bool { return s.Valid },
|
||||||
|
func(s *ValidFloat32) string { return strconv.FormatFloat(float64(s.Value), 'f', -1, 32) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertTimeSettings() []Setting {
|
||||||
|
return convertValidSettings(
|
||||||
|
vsl.GetTimeSettingsMap(),
|
||||||
|
func(s *ValidTime) bool { return s.Valid },
|
||||||
|
func(s *ValidTime) string { return s.Value.Format(time.RFC3339) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateSettings[T any](
|
||||||
|
settings map[string]*T,
|
||||||
|
customValidator func(*T) bool,
|
||||||
|
) error {
|
||||||
|
var errs []string
|
||||||
|
for key, s := range settings {
|
||||||
|
if !customValidator(s) {
|
||||||
|
errs = append(errs, fmt.Sprintf("%v is invalid", key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.New(strings.Join(errs, "; "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateInt64Settings() error {
|
||||||
|
return validateSettings(vsl.GetInt64SettingsMap(),
|
||||||
|
func(s *ValidInt64) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateCurrencySettings() error {
|
||||||
|
return validateSettings(vsl.GetCurrencySettingsMap(),
|
||||||
|
func(s *ValidCurrency) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateStringSettings() error {
|
||||||
|
return validateSettings(vsl.GetStringSettingsMap(),
|
||||||
|
func(s *ValidString) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateBoolSettings() error {
|
||||||
|
return validateSettings(vsl.GetBoolSettingsMap(),
|
||||||
|
func(s *ValidBool) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateFloat32Settings() error {
|
||||||
|
return validateSettings(vsl.GetFloat32SettingsMap(),
|
||||||
|
func(s *ValidFloat32) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateTimeSettings() error {
|
||||||
|
return validateSettings(vsl.GetTimeSettingsMap(),
|
||||||
|
func(s *ValidTime) bool {
|
||||||
|
return s.Valid
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ValidateAllSettings() error {
|
||||||
|
var errs []string
|
||||||
|
validators := []func() error{
|
||||||
|
vsl.ValidateInt64Settings,
|
||||||
|
vsl.ValidateCurrencySettings,
|
||||||
|
vsl.ValidateStringSettings,
|
||||||
|
vsl.ValidateBoolSettings,
|
||||||
|
vsl.ValidateFloat32Settings,
|
||||||
|
vsl.ValidateTimeSettings,
|
||||||
|
vsl.CustomValidationSettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, validator := range validators {
|
||||||
|
if err := validator(); err != nil {
|
||||||
|
errs = append(errs, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.New(strings.Join(errs, "; "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vsl *ValidSettingList) ConvertAllSettings() []Setting {
|
||||||
|
totalCap := vsl.GetTotalSettings()
|
||||||
|
all := make([]Setting, 0, totalCap)
|
||||||
|
|
||||||
|
all = append(all, vsl.ConvertInt64Settings()...)
|
||||||
|
all = append(all, vsl.ConvertCurrencySettings()...)
|
||||||
|
all = append(all, vsl.ConvertStringSettings()...)
|
||||||
|
all = append(all, vsl.ConvertBoolSettings()...)
|
||||||
|
all = append(all, vsl.ConvertFloat32Settings()...)
|
||||||
|
all = append(all, vsl.ConvertTimeSettings()...)
|
||||||
|
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBGlobalSettingList(settings []dbgen.GlobalSetting) (SettingList, error) {
|
||||||
|
var dbSettingList ValidSettingList
|
||||||
|
|
||||||
|
for _, setting := range settings {
|
||||||
|
if err := dbSettingList.SetSetting(setting.Key, setting.Value); err != nil {
|
||||||
|
if err == ErrSettingNotFound {
|
||||||
|
MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbSettingList.ValidateAllSettings(); err != nil {
|
||||||
|
fmt.Printf("setting validation error: %v \n", err)
|
||||||
|
MongoDBLogger.Warn("setting validation error", zap.Error(err))
|
||||||
|
return SettingList{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
settingList := dbSettingList.ToSettingList()
|
||||||
|
|
||||||
|
return settingList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDBOverrideSettingList(settings []dbgen.GetOverrideSettingsRow) (SettingList, error) {
|
||||||
|
var dbSettingList ValidSettingList
|
||||||
|
|
||||||
|
for _, setting := range settings {
|
||||||
|
if err := dbSettingList.SetSetting(setting.Key, setting.Value); err != nil {
|
||||||
|
if err == ErrSettingNotFound {
|
||||||
|
MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbSettingList.ValidateAllSettings(); err != nil {
|
||||||
|
fmt.Printf("setting validation error: %v \n", err)
|
||||||
|
MongoDBLogger.Warn("setting validation error", zap.Error(err))
|
||||||
|
return SettingList{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
settingList := dbSettingList.ToSettingList()
|
||||||
|
|
||||||
|
return settingList, nil
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Setting struct {
|
type Setting struct {
|
||||||
|
|
@ -11,68 +13,44 @@ type Setting struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingRes struct {
|
type SettingRes struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
type CompanySetting struct {
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
CompanyID int64
|
||||||
|
UpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingList struct {
|
type CompanySettingRes struct {
|
||||||
SMSProvider SMSProvider `json:"sms_provider"`
|
Key string `json:"key"`
|
||||||
MaxNumberOfOutcomes int64 `json:"max_number_of_outcomes"`
|
Value string `json:"value"`
|
||||||
BetAmountLimit Currency `json:"bet_amount_limit"`
|
CompanyID int64 `json:"company_id"`
|
||||||
DailyTicketPerIP int64 `json:"daily_ticket_limit"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
TotalWinningLimit Currency `json:"total_winning_limit"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
AmountForBetReferral Currency `json:"amount_for_bet_referral"`
|
|
||||||
CashbackAmountCap Currency `json:"cashback_amount_cap"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DBSettingList struct {
|
func ConvertSetting(setting Setting) SettingRes {
|
||||||
SMSProvider ValidString
|
return SettingRes(setting)
|
||||||
MaxNumberOfOutcomes ValidInt64
|
|
||||||
BetAmountLimit ValidInt64
|
|
||||||
DailyTicketPerIP ValidInt64
|
|
||||||
TotalWinningLimit ValidInt64
|
|
||||||
AmountForBetReferral ValidInt64
|
|
||||||
CashbackAmountCap ValidInt64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertInt64SettingsMap(dbSettingList *DBSettingList) map[string]*ValidInt64 {
|
func ConvertCompanySetting(companySetting dbgen.CompanySetting) CompanySetting {
|
||||||
return map[string]*ValidInt64{
|
return CompanySetting{
|
||||||
"max_number_of_outcomes": &dbSettingList.MaxNumberOfOutcomes,
|
Key: companySetting.Key,
|
||||||
"bet_amount_limit": &dbSettingList.BetAmountLimit,
|
Value: companySetting.Value,
|
||||||
"daily_ticket_limit": &dbSettingList.DailyTicketPerIP,
|
CompanyID: companySetting.CompanyID,
|
||||||
"total_winnings_limit": &dbSettingList.TotalWinningLimit,
|
UpdatedAt: companySetting.UpdatedAt.Time,
|
||||||
"amount_for_bet_referral": &dbSettingList.AmountForBetReferral,
|
CreatedAt: companySetting.CreatedAt.Time,
|
||||||
"cashback_amount_cap": &dbSettingList.CashbackAmountCap,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertStringSettingsMap(dbSettingList *DBSettingList) map[string]*ValidString {
|
func ConvertCompanySettings(settings []dbgen.CompanySetting) []CompanySetting {
|
||||||
return map[string]*ValidString{
|
result := make([]CompanySetting, 0, len(settings))
|
||||||
"sms_provider": &dbSettingList.SMSProvider,
|
for _, setting := range settings {
|
||||||
}
|
result = append(result, ConvertCompanySetting(setting))
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertBoolSettingsMap(dbSettingList *DBSettingList) map[string]*ValidBool {
|
|
||||||
return map[string]*ValidBool{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertFloat32SettingsMap(dbSettingList *DBSettingList) map[string]*ValidFloat32 {
|
|
||||||
return map[string]*ValidFloat32{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertTimeSettingsMap(dbSettingList *DBSettingList) map[string]*ValidTime {
|
|
||||||
return map[string]*ValidTime{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertDBSetting(dbSettingList DBSettingList) SettingList {
|
|
||||||
return SettingList{
|
|
||||||
SMSProvider: SMSProvider(dbSettingList.SMSProvider.Value),
|
|
||||||
MaxNumberOfOutcomes: dbSettingList.MaxNumberOfOutcomes.Value,
|
|
||||||
BetAmountLimit: Currency(dbSettingList.BetAmountLimit.Value),
|
|
||||||
DailyTicketPerIP: dbSettingList.DailyTicketPerIP.Value,
|
|
||||||
TotalWinningLimit: Currency(dbSettingList.TotalWinningLimit.Value),
|
|
||||||
AmountForBetReferral: Currency(dbSettingList.AmountForBetReferral.Value),
|
|
||||||
CashbackAmountCap: Currency(dbSettingList.CashbackAmountCap.Value),
|
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ type Ticket struct {
|
||||||
ID int64
|
ID int64
|
||||||
Amount Currency
|
Amount Currency
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
|
CompanyID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetTicket struct {
|
type GetTicket struct {
|
||||||
|
|
@ -46,12 +47,14 @@ type GetTicket struct {
|
||||||
Amount Currency
|
Amount Currency
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
Outcomes []TicketOutcome
|
Outcomes []TicketOutcome
|
||||||
|
CompanyID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateTicket struct {
|
type CreateTicket struct {
|
||||||
Amount Currency
|
Amount Currency
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
IP string
|
IP string
|
||||||
|
CompanyID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateTicketOutcomeReq struct {
|
type CreateTicketOutcomeReq struct {
|
||||||
|
|
@ -80,4 +83,9 @@ type TicketRes struct {
|
||||||
Outcomes []TicketOutcome `json:"outcomes"`
|
Outcomes []TicketOutcome `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"`
|
||||||
|
CompanyID int64 `json:"company_id" example:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TicketFilter struct {
|
||||||
|
CompanyID ValidInt64
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,24 +10,20 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int64
|
ID int64
|
||||||
FirstName string
|
FirstName string
|
||||||
LastName string
|
LastName string
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
PhoneNumber string `json:"phone_number"`
|
PhoneNumber string `json:"phone_number"`
|
||||||
Password []byte
|
Password []byte
|
||||||
Role Role
|
Role Role
|
||||||
//
|
|
||||||
EmailVerified bool
|
EmailVerified bool
|
||||||
PhoneVerified bool
|
PhoneVerified bool
|
||||||
//
|
CreatedAt time.Time
|
||||||
CreatedAt time.Time
|
UpdatedAt time.Time
|
||||||
UpdatedAt time.Time
|
SuspendedAt time.Time
|
||||||
//
|
Suspended bool
|
||||||
SuspendedAt time.Time
|
CompanyID ValidInt64 //This should be null
|
||||||
Suspended bool
|
|
||||||
//
|
|
||||||
CompanyID ValidInt64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserFilter struct {
|
type UserFilter struct {
|
||||||
|
|
@ -39,10 +35,7 @@ type UserFilter struct {
|
||||||
CreatedBefore ValidTime
|
CreatedBefore ValidTime
|
||||||
CreatedAfter ValidTime
|
CreatedAfter ValidTime
|
||||||
}
|
}
|
||||||
type ValidRole struct {
|
|
||||||
Value Role
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterUserReq struct {
|
type RegisterUserReq struct {
|
||||||
FirstName string
|
FirstName string
|
||||||
|
|
@ -54,6 +47,7 @@ type RegisterUserReq struct {
|
||||||
Otp string
|
Otp string
|
||||||
ReferralCode string `json:"referral_code"`
|
ReferralCode string `json:"referral_code"`
|
||||||
OtpMedium OtpMedium
|
OtpMedium OtpMedium
|
||||||
|
CompanyID ValidInt64
|
||||||
}
|
}
|
||||||
type CreateUserReq struct {
|
type CreateUserReq struct {
|
||||||
FirstName string
|
FirstName string
|
||||||
|
|
|
||||||
245
internal/domain/validtypes.go
Normal file
245
internal/domain/validtypes.go
Normal file
|
|
@ -0,0 +1,245 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Valid Int64
|
||||||
|
type ValidInt64 struct {
|
||||||
|
Value int64
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidInt64) ToPG() pgtype.Int8 {
|
||||||
|
return pgtype.Int8{
|
||||||
|
Int64: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *ValidInt64) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err == nil {
|
||||||
|
if s == "" {
|
||||||
|
n.Valid = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v, err := strconv.ParseInt(s, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
n.Value, n.Valid = v, true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var v int64
|
||||||
|
if err := json.Unmarshal(data, &v); err == nil {
|
||||||
|
n.Value, n.Valid = v, true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("invalid int64 value: %s", string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertInt64Ptr(value *int64) ValidInt64 {
|
||||||
|
if value == nil {
|
||||||
|
return ValidInt64{}
|
||||||
|
}
|
||||||
|
return ValidInt64{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Int
|
||||||
|
type ValidInt struct {
|
||||||
|
Value int
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidInt) ToPG() pgtype.Int4 {
|
||||||
|
return pgtype.Int4{
|
||||||
|
Int32: int32(v.Value),
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func ConvertIntPtr(value *int) ValidInt {
|
||||||
|
if value == nil {
|
||||||
|
return ValidInt{}
|
||||||
|
}
|
||||||
|
return ValidInt{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Int32
|
||||||
|
type ValidInt32 struct {
|
||||||
|
Value int32
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidInt32) ToPG() pgtype.Int4 {
|
||||||
|
return pgtype.Int4{
|
||||||
|
Int32: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertInt32Ptr(value *int32) ValidInt32 {
|
||||||
|
if value == nil {
|
||||||
|
return ValidInt32{}
|
||||||
|
}
|
||||||
|
return ValidInt32{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Float32
|
||||||
|
type ValidFloat32 struct {
|
||||||
|
Value float32
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidFloat32) ToPG() pgtype.Float4 {
|
||||||
|
return pgtype.Float4{
|
||||||
|
Float32: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertFloat32Ptr(value *float32) ValidFloat32 {
|
||||||
|
if value == nil {
|
||||||
|
return ValidFloat32{}
|
||||||
|
}
|
||||||
|
return ValidFloat32{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid String
|
||||||
|
type ValidString struct {
|
||||||
|
Value string
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidString) ToPG() pgtype.Text {
|
||||||
|
return pgtype.Text{
|
||||||
|
String: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertStringPtr(value *string) ValidString {
|
||||||
|
if value == nil {
|
||||||
|
return ValidString{}
|
||||||
|
}
|
||||||
|
return ValidString{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Time
|
||||||
|
type ValidTime struct {
|
||||||
|
Value time.Time
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidTime) ToPG() pgtype.Timestamp {
|
||||||
|
return pgtype.Timestamp{
|
||||||
|
Time: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Bool
|
||||||
|
type ValidBool struct {
|
||||||
|
Value bool
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidBool) ToPG() pgtype.Bool {
|
||||||
|
return pgtype.Bool{
|
||||||
|
Bool: v.Value,
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertBoolPtr(value *bool) ValidBool {
|
||||||
|
if value == nil {
|
||||||
|
return ValidBool{}
|
||||||
|
}
|
||||||
|
return ValidBool{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Currency
|
||||||
|
type ValidCurrency struct {
|
||||||
|
Value Currency
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidCurrency) ToPG() pgtype.Int8 {
|
||||||
|
return pgtype.Int8{
|
||||||
|
Int64: int64(v.Value),
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCurrencyPtr(value *Currency) ValidCurrency {
|
||||||
|
if value == nil {
|
||||||
|
return ValidCurrency{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidCurrency{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertFloat32PtrToCurrency(value *float32) ValidCurrency {
|
||||||
|
if value == nil {
|
||||||
|
return ValidCurrency{}
|
||||||
|
}
|
||||||
|
|
||||||
|
converted := ToCurrency(*value)
|
||||||
|
|
||||||
|
return ValidCurrency{
|
||||||
|
Value: converted,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid Role
|
||||||
|
type ValidRole struct {
|
||||||
|
Value Role
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidRole) ToPG() pgtype.Text {
|
||||||
|
return pgtype.Text{
|
||||||
|
String: string(v.Value),
|
||||||
|
Valid: v.Valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertRolePtr(value *Role) ValidRole {
|
||||||
|
if value == nil {
|
||||||
|
return ValidRole{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidRole{
|
||||||
|
Value: *value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
42
internal/pkgs/helpers/slug.go
Normal file
42
internal/pkgs/helpers/slug.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// keep letters, numbers, spaces, and hyphens
|
||||||
|
slugRegex = regexp.MustCompile(`[^a-z0-9\s-]`)
|
||||||
|
spaceRe = regexp.MustCompile(`\s+`)
|
||||||
|
dashRe = regexp.MustCompile(`-+`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateSlug creates a URL-safe slug from a given string (e.g. company name).
|
||||||
|
func GenerateSlug(name string) string {
|
||||||
|
// lowercase
|
||||||
|
slug := strings.ToLower(name)
|
||||||
|
|
||||||
|
// normalize unicode accents (é -> e, ü -> u, etc.)
|
||||||
|
slug = strings.Map(func(r rune) rune {
|
||||||
|
if unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsSpace(r) || r == '-' {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}, slug)
|
||||||
|
|
||||||
|
// remove unwanted chars
|
||||||
|
slug = slugRegex.ReplaceAllString(slug, "")
|
||||||
|
|
||||||
|
// replace spaces with dash
|
||||||
|
slug = spaceRe.ReplaceAllString(slug, "-")
|
||||||
|
|
||||||
|
// collapse multiple dashes
|
||||||
|
slug = dashRe.ReplaceAllString(slug, "-")
|
||||||
|
|
||||||
|
// trim leading/trailing dash
|
||||||
|
slug = strings.Trim(slug, "-")
|
||||||
|
|
||||||
|
return slug
|
||||||
|
}
|
||||||
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string) (domain.User, error) {
|
func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error) {
|
||||||
user, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{
|
user, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{
|
||||||
Email: pgtype.Text{
|
Email: pgtype.Text{
|
||||||
String: email,
|
String: email,
|
||||||
|
|
@ -21,6 +21,7 @@ func (s *Store) GetUserByEmailPhone(ctx context.Context, email, phone string) (d
|
||||||
String: phone,
|
String: phone,
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
|
CompanyID: companyID.ToPG(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
|
|
||||||
|
|
@ -19,115 +19,14 @@ var (
|
||||||
mongoLogger *zap.Logger
|
mongoLogger *zap.Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertDBBet(bet dbgen.Bet) domain.Bet {
|
|
||||||
return domain.Bet{
|
|
||||||
ID: bet.ID,
|
|
||||||
Amount: domain.Currency(bet.Amount),
|
|
||||||
TotalOdds: bet.TotalOdds,
|
|
||||||
Status: domain.OutcomeStatus(bet.Status),
|
|
||||||
UserID: bet.UserID,
|
|
||||||
IsShopBet: bet.IsShopBet,
|
|
||||||
CashedOut: bet.CashedOut,
|
|
||||||
FastCode: bet.FastCode,
|
|
||||||
CreatedAt: bet.CreatedAt.Time,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertDBBetOutcomes(outcome dbgen.BetOutcome) domain.BetOutcome {
|
|
||||||
return domain.BetOutcome{
|
|
||||||
ID: outcome.ID,
|
|
||||||
BetID: outcome.BetID,
|
|
||||||
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: domain.OutcomeStatus(outcome.Status),
|
|
||||||
Expires: outcome.Expires.Time,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertDBBetWithOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
|
|
||||||
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
|
||||||
|
|
||||||
for _, outcome := range bet.Outcomes {
|
|
||||||
outcomes = append(outcomes, convertDBBetOutcomes(outcome))
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain.GetBet{
|
|
||||||
ID: bet.ID,
|
|
||||||
Amount: domain.Currency(bet.Amount),
|
|
||||||
TotalOdds: bet.TotalOdds,
|
|
||||||
Status: domain.OutcomeStatus(bet.Status),
|
|
||||||
FullName: bet.FullName.(string),
|
|
||||||
PhoneNumber: bet.PhoneNumber.String,
|
|
||||||
UserID: bet.UserID,
|
|
||||||
IsShopBet: bet.IsShopBet,
|
|
||||||
CashedOut: bet.CashedOut,
|
|
||||||
Outcomes: outcomes,
|
|
||||||
FastCode: bet.FastCode,
|
|
||||||
CreatedAt: bet.CreatedAt.Time,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertDBFlag(flag dbgen.Flag) domain.Flag {
|
|
||||||
return domain.Flag{
|
|
||||||
ID: flag.ID,
|
|
||||||
BetID: flag.BetID.Int64,
|
|
||||||
OddID: flag.OddID.Int64,
|
|
||||||
Reason: flag.Reason.String,
|
|
||||||
FlaggedAt: flag.FlaggedAt.Time,
|
|
||||||
Resolved: flag.Resolved.Bool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertDBCreateBetOutcome(betOutcome domain.CreateBetOutcome) dbgen.CreateBetOutcomeParams {
|
|
||||||
return dbgen.CreateBetOutcomeParams{
|
|
||||||
BetID: betOutcome.BetID,
|
|
||||||
EventID: betOutcome.EventID,
|
|
||||||
SportID: betOutcome.SportID,
|
|
||||||
OddID: betOutcome.OddID,
|
|
||||||
HomeTeamName: betOutcome.HomeTeamName,
|
|
||||||
AwayTeamName: betOutcome.AwayTeamName,
|
|
||||||
MarketID: betOutcome.MarketID,
|
|
||||||
MarketName: betOutcome.MarketName,
|
|
||||||
Odd: betOutcome.Odd,
|
|
||||||
OddName: betOutcome.OddName,
|
|
||||||
OddHeader: betOutcome.OddHeader,
|
|
||||||
OddHandicap: betOutcome.OddHandicap,
|
|
||||||
Expires: pgtype.Timestamp{
|
|
||||||
Time: betOutcome.Expires,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams {
|
|
||||||
return dbgen.CreateBetParams{
|
|
||||||
Amount: int64(bet.Amount),
|
|
||||||
TotalOdds: bet.TotalOdds,
|
|
||||||
Status: int32(bet.Status),
|
|
||||||
UserID: bet.UserID,
|
|
||||||
IsShopBet: bet.IsShopBet,
|
|
||||||
OutcomesHash: bet.OutcomesHash,
|
|
||||||
FastCode: bet.FastCode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
|
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
|
||||||
newBet, err := s.queries.CreateBet(ctx, convertCreateBet(bet))
|
newBet, err := s.queries.CreateBet(ctx, domain.ConvertCreateBet(bet))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("We are here")
|
fmt.Println("We are here")
|
||||||
logger.Error("Failed to create bet", slog.String("error", err.Error()), slog.Any("bet", bet))
|
logger.Error("Failed to create bet", slog.String("error", err.Error()), slog.Any("bet", bet))
|
||||||
return domain.Bet{}, err
|
return domain.Bet{}, err
|
||||||
}
|
}
|
||||||
return convertDBBet(newBet), err
|
return domain.ConvertDBBet(newBet), err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +34,7 @@ func (s *Store) CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBe
|
||||||
var dbParams []dbgen.CreateBetOutcomeParams = make([]dbgen.CreateBetOutcomeParams, 0, len(outcomes))
|
var dbParams []dbgen.CreateBetOutcomeParams = make([]dbgen.CreateBetOutcomeParams, 0, len(outcomes))
|
||||||
|
|
||||||
for _, outcome := range outcomes {
|
for _, outcome := range outcomes {
|
||||||
dbParams = append(dbParams, convertDBCreateBetOutcome(outcome))
|
dbParams = append(dbParams, domain.ConvertDBCreateBetOutcome(outcome))
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := s.queries.CreateBetOutcome(ctx, dbParams)
|
rows, err := s.queries.CreateBetOutcome(ctx, dbParams)
|
||||||
|
|
@ -157,7 +56,7 @@ func (s *Store) CreateFlag(ctx context.Context, flag domain.CreateFlagReq) (doma
|
||||||
Int64: flag.BetID,
|
Int64: flag.BetID,
|
||||||
Valid: flag.BetID != 0,
|
Valid: flag.BetID != 0,
|
||||||
},
|
},
|
||||||
OddID: pgtype.Int8{
|
OddsMarketID: pgtype.Int8{
|
||||||
Int64: flag.OddID,
|
Int64: flag.OddID,
|
||||||
Valid: flag.OddID != 0,
|
Valid: flag.OddID != 0,
|
||||||
},
|
},
|
||||||
|
|
@ -177,7 +76,7 @@ func (s *Store) CreateFlag(ctx context.Context, flag domain.CreateFlagReq) (doma
|
||||||
return domain.Flag{}, err
|
return domain.Flag{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBFlag(f), nil
|
return domain.ConvertDBFlag(f), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) {
|
func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) {
|
||||||
|
|
@ -190,35 +89,18 @@ func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error)
|
||||||
return domain.GetBet{}, err
|
return domain.GetBet{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBBetWithOutcomes(bet), nil
|
return domain.ConvertDBBetWithOutcomes(bet), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) {
|
func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]domain.GetBet, error) {
|
||||||
bets, err := s.queries.GetAllBets(ctx, dbgen.GetAllBetsParams{
|
bets, err := s.queries.GetAllBets(ctx, dbgen.GetAllBetsParams{
|
||||||
UserID: pgtype.Int8{
|
UserID: filter.UserID.ToPG(),
|
||||||
Int64: filter.UserID.Value,
|
CompanyID: filter.CompanyID.ToPG(),
|
||||||
Valid: filter.UserID.Valid,
|
CashedOut: filter.CashedOut.ToPG(),
|
||||||
},
|
IsShopBet: filter.IsShopBet.ToPG(),
|
||||||
CashedOut: pgtype.Bool{
|
Query: filter.Query.ToPG(),
|
||||||
Bool: filter.CashedOut.Value,
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
Valid: filter.CashedOut.Valid,
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
},
|
|
||||||
IsShopBet: pgtype.Bool{
|
|
||||||
Bool: filter.IsShopBet.Value,
|
|
||||||
Valid: filter.IsShopBet.Valid,
|
|
||||||
},
|
|
||||||
Query: pgtype.Text{
|
|
||||||
String: filter.Query.Value,
|
|
||||||
Valid: filter.Query.Valid,
|
|
||||||
},
|
|
||||||
CreatedBefore: pgtype.Timestamp{
|
|
||||||
Time: filter.CreatedBefore.Value,
|
|
||||||
Valid: filter.CreatedBefore.Valid,
|
|
||||||
},
|
|
||||||
CreatedAfter: pgtype.Timestamp{
|
|
||||||
Time: filter.CreatedAfter.Value,
|
|
||||||
Valid: filter.CreatedAfter.Valid,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to get all bets",
|
domain.MongoDBLogger.Error("failed to get all bets",
|
||||||
|
|
@ -230,7 +112,7 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma
|
||||||
|
|
||||||
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 {
|
||||||
result = append(result, convertDBBetWithOutcomes(bet))
|
result = append(result, domain.ConvertDBBetWithOutcomes(bet))
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
@ -245,7 +127,7 @@ func (s *Store) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetB
|
||||||
|
|
||||||
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 {
|
||||||
result = append(result, convertDBBetWithOutcomes(bet))
|
result = append(result, domain.ConvertDBBetWithOutcomes(bet))
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
@ -258,7 +140,7 @@ func (s *Store) GetBetByFastCode(ctx context.Context, fastcode string) (domain.G
|
||||||
return domain.GetBet{}, err
|
return domain.GetBet{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBBetWithOutcomes(bet), nil
|
return domain.ConvertDBBetWithOutcomes(bet), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error) {
|
func (s *Store) GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error) {
|
||||||
|
|
@ -270,7 +152,7 @@ func (s *Store) GetBetsForCashback(ctx context.Context) ([]domain.GetBet, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bet := range bets {
|
for _, bet := range bets {
|
||||||
cashbackBet := convertDBBetWithOutcomes(bet)
|
cashbackBet := domain.ConvertDBBetWithOutcomes(bet)
|
||||||
res = append(res, cashbackBet)
|
res = append(res, cashbackBet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +243,7 @@ func (s *Store) GetBetOutcomeByEventID(ctx context.Context, eventID int64, is_fi
|
||||||
|
|
||||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||||
for _, outcome := range outcomes {
|
for _, outcome := range outcomes {
|
||||||
result = append(result, convertDBBetOutcomes(outcome))
|
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +260,7 @@ func (s *Store) GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain
|
||||||
|
|
||||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||||
for _, outcome := range outcomes {
|
for _, outcome := range outcomes {
|
||||||
result = append(result, convertDBBetOutcomes(outcome))
|
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +279,7 @@ func (s *Store) UpdateBetOutcomeStatus(ctx context.Context, id int64, status dom
|
||||||
return domain.BetOutcome{}, err
|
return domain.BetOutcome{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := convertDBBetOutcomes(update)
|
res := domain.ConvertDBBetOutcomes(update)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,7 +297,7 @@ func (s *Store) UpdateBetOutcomeStatusByBetID(ctx context.Context, id int64, sta
|
||||||
return domain.BetOutcome{}, err
|
return domain.BetOutcome{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := convertDBBetOutcomes(update)
|
res := domain.ConvertDBBetOutcomes(update)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -436,7 +318,7 @@ func (s *Store) UpdateBetOutcomeStatusForEvent(ctx context.Context, eventID int6
|
||||||
|
|
||||||
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
var result []domain.BetOutcome = make([]domain.BetOutcome, 0, len(outcomes))
|
||||||
for _, outcome := range outcomes {
|
for _, outcome := range outcomes {
|
||||||
result = append(result, convertDBBetOutcomes(outcome))
|
result = append(result, domain.ConvertDBBetOutcomes(outcome))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
|
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
|
||||||
|
|
||||||
dbBranch, err := s.queries.CreateBranch(ctx, domain.ConvertCreateBranch(branch))
|
dbBranch, err := s.queries.CreateBranch(ctx, domain.ConvertCreateBranch(branch))
|
||||||
|
|
@ -53,26 +52,11 @@ func (s *Store) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]do
|
||||||
|
|
||||||
func (s *Store) GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error) {
|
func (s *Store) GetAllBranches(ctx context.Context, filter domain.BranchFilter) ([]domain.BranchDetail, error) {
|
||||||
dbBranches, err := s.queries.GetAllBranches(ctx, dbgen.GetAllBranchesParams{
|
dbBranches, err := s.queries.GetAllBranches(ctx, dbgen.GetAllBranchesParams{
|
||||||
CompanyID: pgtype.Int8{
|
CompanyID: filter.CompanyID.ToPG(),
|
||||||
Int64: filter.CompanyID.Value,
|
BranchManagerID: filter.BranchManagerID.ToPG(),
|
||||||
Valid: filter.CompanyID.Valid,
|
Query: filter.Query.ToPG(),
|
||||||
},
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
BranchManagerID: pgtype.Int8{
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
Int64: filter.BranchManagerID.Value,
|
|
||||||
Valid: filter.BranchManagerID.Valid,
|
|
||||||
},
|
|
||||||
Query: pgtype.Text{
|
|
||||||
String: filter.Query.Value,
|
|
||||||
Valid: filter.Query.Valid,
|
|
||||||
},
|
|
||||||
CreatedBefore: pgtype.Timestamp{
|
|
||||||
Time: filter.CreatedBefore.Value,
|
|
||||||
Valid: filter.CreatedBefore.Valid,
|
|
||||||
},
|
|
||||||
CreatedAfter: pgtype.Timestamp{
|
|
||||||
Time: filter.CreatedAfter.Value,
|
|
||||||
Valid: filter.CreatedAfter.Valid,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,36 @@ package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"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/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) {
|
||||||
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company))
|
baseSlug := helpers.GenerateSlug(company.Name)
|
||||||
|
uniqueSlug := baseSlug
|
||||||
|
i := 1
|
||||||
|
|
||||||
|
for {
|
||||||
|
_, err := s.queries.GetCompanyIDUsingSlug(ctx, uniqueSlug)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
// slug is unique
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
// real DB error
|
||||||
|
return domain.Company{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company, uniqueSlug))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Company{}, err
|
return domain.Company{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +78,15 @@ 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) {
|
||||||
|
dbCompanyID, err := s.queries.GetCompanyIDUsingSlug(ctx, slug)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return dbCompanyID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
|
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
|
||||||
dbCompany, err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company))
|
dbCompany, err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company))
|
||||||
|
|
||||||
|
|
|
||||||
105
internal/repository/custom_odds.go
Normal file
105
internal/repository/custom_odds.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "context"
|
||||||
|
|
||||||
|
// dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func (s *Store) InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error) {
|
||||||
|
// convertedCustomOdd, err := domain.ConvertCreateCustomOdd(odd)
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, err
|
||||||
|
// }
|
||||||
|
// dbCustomOdd, err := s.queries.InsertCustomOdd(ctx, convertedCustomOdd)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// convertDbCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return convertDbCustomOdd, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error) {
|
||||||
|
// dbCustomOdds, err := s.queries.GetAllCustomOdds(ctx, filter.CompanyID.ToPG())
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// convertDbCustomOdds, err := domain.ConvertDbCustomOdds(dbCustomOdds)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return convertDbCustomOdds, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error) {
|
||||||
|
// dbCustomOdd, err := s.queries.GetCustomOddByID(ctx, id)
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// convertedDBCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return convertedDBCustomOdd, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error) {
|
||||||
|
// dbCustomOdd, err := s.queries.GetCustomOddByOddID(ctx, dbgen.GetCustomOddByOddIDParams{
|
||||||
|
// OddID: oddId,
|
||||||
|
// CompanyID: companyID,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// convertedDBCustomOdd, err := domain.ConvertDBCustomOdd(dbCustomOdd)
|
||||||
|
// if err != nil {
|
||||||
|
// return domain.CustomOdd{}, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return convertedDBCustomOdd, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) DeleteCustomOddByID(ctx context.Context, id int64) error {
|
||||||
|
// err := s.queries.DeleteCustomOddsByID(ctx, id)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error {
|
||||||
|
// err := s.queries.DeleteCustomOddsByOddID(ctx, dbgen.DeleteCustomOddsByOddIDParams{
|
||||||
|
// OddID: oddId,
|
||||||
|
// CompanyID: companyID,
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *Store) DeleteCustomOddByEventID(ctx context.Context, eventID string) error {
|
||||||
|
// err := s.queries.DeleteCustomOddByEventID(ctx, eventID)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
68
internal/repository/disabled_odds.go
Normal file
68
internal/repository/disabled_odds.go
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Store) InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error) {
|
||||||
|
dbDisabledOdd, err := s.queries.InsertDisabledOdds(ctx, domain.ConvertCreateDisabledOdd(odd))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.DisabledOdd{}, fmt.Errorf("InsertDisabledOdd failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error) {
|
||||||
|
dbDisabledOdds, err := s.queries.GetAllDisabledOdds(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllDisabledOdds failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDisabledOdds(dbDisabledOdds), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error) {
|
||||||
|
dbDisabledOdd, err := s.queries.GetDisabledOddByRawOddID(ctx, rawOddID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.DisabledOdd{}, fmt.Errorf("GetDisabledOddByRawOddID failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error) {
|
||||||
|
dbDisabledOdd, err := s.queries.GetDisabledOddByID(ctx, id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.DisabledOdd{}, fmt.Errorf("GetDisabledOddByID failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBDisabledOdd(dbDisabledOdd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) DeleteDisabledOddsByID(ctx context.Context, id int64) error {
|
||||||
|
|
||||||
|
err := s.queries.DeleteDisabledOddsByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("DeleteDisabledOddsByID failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error {
|
||||||
|
|
||||||
|
err := s.queries.DeleteDisabledOddsByRawOddID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("DeleteDisabledOddsByRawOddID failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
|
||||||
|
|
||||||
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"
|
||||||
|
|
@ -13,90 +12,29 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) SaveEvent(ctx context.Context, e domain.Event) error {
|
func (s *Store) SaveEvent(ctx context.Context, e domain.CreateEvent) error {
|
||||||
parsedTime, err := time.Parse(time.RFC3339, e.StartTime)
|
return s.queries.InsertEvent(ctx, domain.ConvertCreateEvent(e))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.queries.InsertEvent(ctx, dbgen.InsertEventParams{
|
|
||||||
ID: e.ID,
|
|
||||||
SportID: pgtype.Int4{Int32: e.SportID, Valid: true},
|
|
||||||
MatchName: pgtype.Text{String: e.MatchName, Valid: true},
|
|
||||||
HomeTeam: pgtype.Text{String: e.HomeTeam, Valid: true},
|
|
||||||
AwayTeam: pgtype.Text{String: e.AwayTeam, Valid: true},
|
|
||||||
HomeTeamID: pgtype.Int4{Int32: e.HomeTeamID, Valid: true},
|
|
||||||
AwayTeamID: pgtype.Int4{Int32: e.AwayTeamID, Valid: true},
|
|
||||||
HomeKitImage: pgtype.Text{String: e.HomeKitImage, Valid: true},
|
|
||||||
AwayKitImage: pgtype.Text{String: e.AwayKitImage, Valid: true},
|
|
||||||
LeagueID: pgtype.Int4{Int32: e.LeagueID, Valid: true},
|
|
||||||
LeagueName: pgtype.Text{String: e.LeagueName, Valid: true},
|
|
||||||
LeagueCc: pgtype.Text{String: e.LeagueCC, Valid: true},
|
|
||||||
StartTime: pgtype.Timestamp{Time: parsedTime, Valid: true},
|
|
||||||
Score: pgtype.Text{String: e.Score, Valid: true},
|
|
||||||
MatchMinute: pgtype.Int4{Int32: int32(e.MatchMinute), Valid: true},
|
|
||||||
TimerStatus: pgtype.Text{String: e.TimerStatus, Valid: true},
|
|
||||||
AddedTime: pgtype.Int4{Int32: int32(e.AddedTime), Valid: true},
|
|
||||||
MatchPeriod: pgtype.Int4{Int32: int32(e.MatchPeriod), Valid: true},
|
|
||||||
IsLive: pgtype.Bool{Bool: e.IsLive, Valid: true},
|
|
||||||
Status: pgtype.Text{String: e.Status, Valid: true},
|
|
||||||
Source: pgtype.Text{String: e.Source, Valid: true},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
func (s *Store) SaveUpcomingEvent(ctx context.Context, e domain.UpcomingEvent) error {
|
|
||||||
return s.queries.InsertUpcomingEvent(ctx, dbgen.InsertUpcomingEventParams{
|
func (s *Store) InsertEventSettings(ctx context.Context, eventSetting domain.CreateEventSettings) error {
|
||||||
ID: e.ID,
|
return s.queries.InsertEventSettings(ctx, domain.ConvertCreateEventSettings(eventSetting))
|
||||||
SportID: pgtype.Int4{Int32: e.SportID, Valid: true},
|
|
||||||
MatchName: pgtype.Text{String: e.MatchName, Valid: true},
|
|
||||||
HomeTeam: pgtype.Text{String: e.HomeTeam, Valid: true},
|
|
||||||
AwayTeam: pgtype.Text{String: e.AwayTeam, Valid: true},
|
|
||||||
HomeTeamID: pgtype.Int4{Int32: e.HomeTeamID, Valid: true},
|
|
||||||
AwayTeamID: pgtype.Int4{Int32: e.AwayTeamID, Valid: true},
|
|
||||||
HomeKitImage: pgtype.Text{String: e.HomeKitImage, Valid: true},
|
|
||||||
AwayKitImage: pgtype.Text{String: e.AwayKitImage, Valid: true},
|
|
||||||
LeagueID: pgtype.Int4{Int32: e.LeagueID, Valid: true},
|
|
||||||
LeagueName: pgtype.Text{String: e.LeagueName, Valid: true},
|
|
||||||
LeagueCc: pgtype.Text{String: e.LeagueCC, Valid: true},
|
|
||||||
StartTime: pgtype.Timestamp{Time: e.StartTime, Valid: true},
|
|
||||||
Source: pgtype.Text{String: e.Source, Valid: true},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
func (s *Store) GetLiveEventIDs(ctx context.Context) ([]string, error) {
|
||||||
return s.queries.ListLiveEvents(ctx)
|
return s.queries.ListLiveEvents(ctx)
|
||||||
}
|
}
|
||||||
func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
|
||||||
|
func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error) {
|
||||||
events, err := s.queries.GetAllUpcomingEvents(ctx)
|
events, err := s.queries.GetAllUpcomingEvents(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
return domain.ConvertDBEvents(events), nil
|
||||||
for i, e := range events {
|
|
||||||
upcomingEvents[i] = domain.UpcomingEvent{
|
|
||||||
ID: e.ID,
|
|
||||||
SportID: e.SportID.Int32,
|
|
||||||
MatchName: e.MatchName.String,
|
|
||||||
HomeTeam: e.HomeTeam.String,
|
|
||||||
AwayTeam: e.AwayTeam.String,
|
|
||||||
HomeTeamID: e.HomeTeamID.Int32,
|
|
||||||
AwayTeamID: e.AwayTeamID.Int32,
|
|
||||||
HomeKitImage: e.HomeKitImage.String,
|
|
||||||
AwayKitImage: e.AwayKitImage.String,
|
|
||||||
LeagueID: e.LeagueID.Int32,
|
|
||||||
LeagueName: e.LeagueName.String,
|
|
||||||
LeagueCC: e.LeagueCc.String,
|
|
||||||
StartTime: e.StartTime.Time.UTC(),
|
|
||||||
Source: e.Source.String,
|
|
||||||
Status: domain.EventStatus(e.Status.String),
|
|
||||||
IsFeatured: e.IsFeatured,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return upcomingEvents, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error) {
|
func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error) {
|
||||||
events, err := s.queries.GetExpiredUpcomingEvents(ctx, pgtype.Text{
|
events, err := s.queries.GetExpiredEvents(ctx, pgtype.Text{
|
||||||
String: filter.MatchStatus.Value,
|
String: filter.MatchStatus.Value,
|
||||||
Valid: filter.MatchStatus.Valid,
|
Valid: filter.MatchStatus.Valid,
|
||||||
})
|
})
|
||||||
|
|
@ -104,163 +42,98 @@ func (s *Store) GetExpiredUpcomingEvents(ctx context.Context, filter domain.Even
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
return domain.ConvertDBEvents(events), nil
|
||||||
for i, e := range events {
|
|
||||||
upcomingEvents[i] = domain.UpcomingEvent{
|
|
||||||
ID: e.ID,
|
|
||||||
SportID: e.SportID.Int32,
|
|
||||||
MatchName: e.MatchName.String,
|
|
||||||
HomeTeam: e.HomeTeam.String,
|
|
||||||
AwayTeam: e.AwayTeam.String,
|
|
||||||
HomeTeamID: e.HomeTeamID.Int32,
|
|
||||||
AwayTeamID: e.AwayTeamID.Int32,
|
|
||||||
HomeKitImage: e.HomeKitImage.String,
|
|
||||||
AwayKitImage: e.AwayKitImage.String,
|
|
||||||
LeagueID: e.LeagueID.Int32,
|
|
||||||
LeagueName: e.LeagueName.String,
|
|
||||||
LeagueCC: e.LeagueCc.String,
|
|
||||||
StartTime: e.StartTime.Time.UTC(),
|
|
||||||
Source: e.Source.String,
|
|
||||||
Status: domain.EventStatus(e.Status.String),
|
|
||||||
IsFeatured: e.IsFeatured,
|
|
||||||
IsActive: e.IsActive,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return upcomingEvents, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error) {
|
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
||||||
|
|
||||||
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
|
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
|
||||||
LeagueID: pgtype.Int4{
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
Int32: int32(filter.LeagueID.Value),
|
SportID: filter.SportID.ToPG(),
|
||||||
Valid: filter.LeagueID.Valid,
|
Query: filter.Query.ToPG(),
|
||||||
},
|
Limit: filter.Limit.ToPG(),
|
||||||
SportID: pgtype.Int4{
|
Offset: filter.Offset.ToPG(),
|
||||||
Int32: int32(filter.SportID.Value),
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
Valid: filter.SportID.Valid,
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
},
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
Query: pgtype.Text{
|
|
||||||
String: filter.Query.Value,
|
|
||||||
Valid: filter.Query.Valid,
|
|
||||||
},
|
|
||||||
Limit: pgtype.Int4{
|
|
||||||
Int32: int32(filter.Limit.Value),
|
|
||||||
Valid: filter.Limit.Valid,
|
|
||||||
},
|
|
||||||
Offset: pgtype.Int4{
|
|
||||||
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
|
||||||
Valid: filter.Offset.Valid,
|
|
||||||
},
|
|
||||||
FirstStartTime: pgtype.Timestamp{
|
|
||||||
Time: filter.FirstStartTime.Value.UTC(),
|
|
||||||
Valid: filter.FirstStartTime.Valid,
|
|
||||||
},
|
|
||||||
LastStartTime: pgtype.Timestamp{
|
|
||||||
Time: filter.LastStartTime.Value.UTC(),
|
|
||||||
Valid: filter.LastStartTime.Valid,
|
|
||||||
},
|
|
||||||
CountryCode: pgtype.Text{
|
|
||||||
String: filter.CountryCode.Value,
|
|
||||||
Valid: filter.CountryCode.Valid,
|
|
||||||
},
|
|
||||||
IsFeatured: pgtype.Bool{
|
|
||||||
Bool: filter.Featured.Valid,
|
|
||||||
Valid: filter.Featured.Valid,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
upcomingEvents := make([]domain.UpcomingEvent, len(events))
|
|
||||||
for i, e := range events {
|
|
||||||
upcomingEvents[i] = domain.UpcomingEvent{
|
|
||||||
ID: e.ID,
|
|
||||||
SportID: e.SportID.Int32,
|
|
||||||
MatchName: e.MatchName.String,
|
|
||||||
HomeTeam: e.HomeTeam.String,
|
|
||||||
AwayTeam: e.AwayTeam.String,
|
|
||||||
HomeTeamID: e.HomeTeamID.Int32,
|
|
||||||
AwayTeamID: e.AwayTeamID.Int32,
|
|
||||||
HomeKitImage: e.HomeKitImage.String,
|
|
||||||
AwayKitImage: e.AwayKitImage.String,
|
|
||||||
LeagueID: e.LeagueID.Int32,
|
|
||||||
LeagueName: e.LeagueName.String,
|
|
||||||
LeagueCC: e.LeagueCc.String,
|
|
||||||
StartTime: e.StartTime.Time.UTC(),
|
|
||||||
Source: e.Source.String,
|
|
||||||
Status: domain.EventStatus(e.Status.String),
|
|
||||||
IsFeatured: e.IsFeatured,
|
|
||||||
IsActive: e.IsActive,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{
|
totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{
|
||||||
LeagueID: pgtype.Int4{
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
Int32: int32(filter.LeagueID.Value),
|
SportID: filter.SportID.ToPG(),
|
||||||
Valid: filter.LeagueID.Valid,
|
Query: filter.Query.ToPG(),
|
||||||
},
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
SportID: pgtype.Int4{
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
Int32: int32(filter.SportID.Value),
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
Valid: filter.SportID.Valid,
|
|
||||||
},
|
|
||||||
Query: pgtype.Text{
|
|
||||||
String: filter.Query.Value,
|
|
||||||
Valid: filter.Query.Valid,
|
|
||||||
},
|
|
||||||
FirstStartTime: pgtype.Timestamp{
|
|
||||||
Time: filter.FirstStartTime.Value.UTC(),
|
|
||||||
Valid: filter.FirstStartTime.Valid,
|
|
||||||
},
|
|
||||||
LastStartTime: pgtype.Timestamp{
|
|
||||||
Time: filter.LastStartTime.Value.UTC(),
|
|
||||||
Valid: filter.LastStartTime.Valid,
|
|
||||||
},
|
|
||||||
CountryCode: pgtype.Text{
|
|
||||||
String: filter.CountryCode.Value,
|
|
||||||
Valid: filter.CountryCode.Valid,
|
|
||||||
},
|
|
||||||
IsFeatured: pgtype.Bool{
|
|
||||||
Bool: filter.Featured.Valid,
|
|
||||||
Valid: filter.Featured.Valid,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
||||||
return upcomingEvents, int64(numberOfPages), nil
|
return domain.ConvertDBEvents(events), int64(numberOfPages), nil
|
||||||
}
|
}
|
||||||
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
|
||||||
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
func (s *Store) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
||||||
|
events, err := s.queries.GetEventsWithSettings(ctx, dbgen.GetEventsWithSettingsParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
|
SportID: filter.SportID.ToPG(),
|
||||||
|
Query: filter.Query.ToPG(),
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.UpcomingEvent{}, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.UpcomingEvent{
|
totalCount, err := s.queries.GetTotalCompanyEvents(ctx, dbgen.GetTotalCompanyEventsParams{
|
||||||
ID: event.ID,
|
CompanyID: companyID,
|
||||||
SportID: event.SportID.Int32,
|
LeagueID: filter.LeagueID.ToPG(),
|
||||||
MatchName: event.MatchName.String,
|
SportID: filter.SportID.ToPG(),
|
||||||
HomeTeam: event.HomeTeam.String,
|
Query: filter.Query.ToPG(),
|
||||||
AwayTeam: event.AwayTeam.String,
|
FirstStartTime: filter.FirstStartTime.ToPG(),
|
||||||
HomeTeamID: event.HomeTeamID.Int32,
|
LastStartTime: filter.LastStartTime.ToPG(),
|
||||||
AwayTeamID: event.AwayTeamID.Int32,
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
HomeKitImage: event.HomeKitImage.String,
|
})
|
||||||
AwayKitImage: event.AwayKitImage.String,
|
if err != nil {
|
||||||
LeagueID: event.LeagueID.Int32,
|
return nil, 0, err
|
||||||
LeagueName: event.LeagueName.String,
|
}
|
||||||
LeagueCC: event.LeagueCc.String,
|
|
||||||
StartTime: event.StartTime.Time.UTC(),
|
numberOfPages := math.Ceil(float64(totalCount) / float64(filter.Limit.Value))
|
||||||
Source: event.Source.String,
|
return domain.ConvertDBEventWithSettings(events), int64(numberOfPages), nil
|
||||||
Status: domain.EventStatus(event.Status.String),
|
}
|
||||||
IsFeatured: event.IsFeatured,
|
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error) {
|
||||||
}, nil
|
event, err := s.queries.GetUpcomingByID(ctx, ID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.BaseEvent{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBEvent(event), nil
|
||||||
|
}
|
||||||
|
func (s *Store) GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) {
|
||||||
|
event, err := s.queries.GetEventWithSettingByID(ctx, dbgen.GetEventWithSettingByIDParams{
|
||||||
|
ID: ID,
|
||||||
|
CompanyID: companyID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return domain.EventWithSettings{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBEventWithSetting(event), nil
|
||||||
}
|
}
|
||||||
func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error {
|
func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error {
|
||||||
params := dbgen.UpdateMatchResultParams{
|
params := dbgen.UpdateMatchResultParams{
|
||||||
Score: pgtype.Text{String: fullScore, Valid: true},
|
Score: pgtype.Text{String: fullScore, Valid: true},
|
||||||
Status: pgtype.Text{String: string(status), Valid: true},
|
Status: string(status),
|
||||||
ID: eventID,
|
ID: eventID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,11 +147,8 @@ func (s *Store) UpdateFinalScore(ctx context.Context, eventID, fullScore string,
|
||||||
|
|
||||||
func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error {
|
func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error {
|
||||||
params := dbgen.UpdateMatchResultParams{
|
params := dbgen.UpdateMatchResultParams{
|
||||||
Status: pgtype.Text{
|
Status: string(status),
|
||||||
String: string(status),
|
ID: eventID,
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
ID: eventID,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.queries.UpdateMatchResult(ctx, params)
|
err := s.queries.UpdateMatchResult(ctx, params)
|
||||||
|
|
@ -290,13 +160,25 @@ func (s *Store) UpdateEventStatus(ctx context.Context, eventID string, status do
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) UpdateFeatured(ctx context.Context, eventID string, isFeatured bool) error {
|
func (s *Store) IsEventMonitored(ctx context.Context, eventID string) (bool, error) {
|
||||||
return s.queries.UpdateFeatured(ctx, dbgen.UpdateFeaturedParams{
|
isMonitored, err := s.queries.IsEventMonitored(ctx, eventID)
|
||||||
ID: eventID,
|
|
||||||
IsFeatured: isFeatured,
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return isMonitored, err
|
||||||
|
}
|
||||||
|
func (s *Store) UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error {
|
||||||
|
return s.queries.UpdateEventMonitored(ctx, dbgen.UpdateEventMonitoredParams{
|
||||||
|
ID: eventID,
|
||||||
|
IsMonitored: IsMonitored,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
||||||
|
return s.queries.UpdateEventSettings(ctx, domain.ConvertUpdateEventSettings(event))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Store) DeleteEvent(ctx context.Context, eventID string) error {
|
func (s *Store) DeleteEvent(ctx context.Context, eventID string) error {
|
||||||
err := s.queries.DeleteEvent(ctx, eventID)
|
err := s.queries.DeleteEvent(ctx, eventID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
55
internal/repository/event_history.go
Normal file
55
internal/repository/event_history.go
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Store) InsertEventHistory(ctx context.Context, eventHistory domain.CreateEventHistory) (domain.EventHistory, error) {
|
||||||
|
dbEventHistory, err := s.queries.InsertEventHistory(ctx, domain.ConvertCreateEventHistory(eventHistory))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.EventHistory{}, fmt.Errorf("InsertEventHistory failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBEventHistory(dbEventHistory), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertEventHistory(list []dbgen.EventHistory) []domain.EventHistory {
|
||||||
|
result := make([]domain.EventHistory, 0, len(list))
|
||||||
|
for _, item := range list {
|
||||||
|
result = append(result, domain.ConvertDBEventHistory(item))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllEventHistory(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error) {
|
||||||
|
dbEventHistories, err := s.queries.GetAllEventHistory(ctx, dbgen.GetAllEventHistoryParams{
|
||||||
|
EventID: filter.EventID.ToPG(),
|
||||||
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllEventHistory failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertEventHistory(dbEventHistories), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInitialEventPerDay(ctx context.Context, filter domain.EventHistoryFilter) ([]domain.EventHistory, error) {
|
||||||
|
dbEventHistories, err := s.queries.GetInitialEventPerDay(ctx, dbgen.GetInitialEventPerDayParams{
|
||||||
|
EventID: filter.EventID.ToPG(),
|
||||||
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetInitialEventPerDay failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertEventHistory(dbEventHistories), nil
|
||||||
|
}
|
||||||
|
|
@ -8,36 +8,18 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) SaveLeague(ctx context.Context, l domain.League) error {
|
func (s *Store) SaveLeague(ctx context.Context, league domain.CreateLeague) error {
|
||||||
return s.queries.InsertLeague(ctx, dbgen.InsertLeagueParams{
|
return s.queries.InsertLeague(ctx, domain.ConvertCreateLeague(league))
|
||||||
ID: l.ID,
|
|
||||||
Name: l.Name,
|
|
||||||
CountryCode: pgtype.Text{String: l.CountryCode, Valid: true},
|
|
||||||
Bet365ID: pgtype.Int4{Int32: l.Bet365ID, Valid: true},
|
|
||||||
IsActive: pgtype.Bool{Bool: l.IsActive, Valid: true},
|
|
||||||
IsFeatured: pgtype.Bool{Bool: l.IsFeatured, Valid: true},
|
|
||||||
SportID: l.SportID,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
||||||
|
return s.queries.InsertLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
||||||
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{
|
||||||
CountryCode: pgtype.Text{
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
String: filter.CountryCode.Value,
|
SportID: filter.SportID.ToPG(),
|
||||||
Valid: filter.CountryCode.Valid,
|
|
||||||
},
|
|
||||||
SportID: pgtype.Int4{
|
|
||||||
Int32: filter.SportID.Value,
|
|
||||||
Valid: filter.SportID.Valid,
|
|
||||||
},
|
|
||||||
IsActive: pgtype.Bool{
|
|
||||||
Bool: filter.IsActive.Value,
|
|
||||||
Valid: filter.IsActive.Valid,
|
|
||||||
},
|
|
||||||
IsFeatured: pgtype.Bool{
|
|
||||||
Bool: filter.IsFeatured.Value,
|
|
||||||
Valid: filter.IsFeatured.Valid,
|
|
||||||
},
|
|
||||||
Limit: pgtype.Int4{
|
Limit: pgtype.Int4{
|
||||||
Int32: int32(filter.Limit.Value),
|
Int32: int32(filter.Limit.Value),
|
||||||
Valid: filter.Limit.Valid,
|
Valid: filter.Limit.Valid,
|
||||||
|
|
@ -51,85 +33,38 @@ func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) (
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
leagues := make([]domain.League, len(l))
|
return domain.ConvertDBBaseLeagues(l), nil
|
||||||
for i, league := range l {
|
|
||||||
leagues[i] = domain.League{
|
|
||||||
ID: league.ID,
|
|
||||||
Name: league.Name,
|
|
||||||
CountryCode: league.CountryCode.String,
|
|
||||||
Bet365ID: league.Bet365ID.Int32,
|
|
||||||
IsActive: league.IsActive.Bool,
|
|
||||||
IsFeatured: league.IsFeatured.Bool,
|
|
||||||
SportID: league.SportID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return leagues, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetFeaturedLeagues(ctx context.Context) ([]domain.League, error) {
|
func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, error) {
|
||||||
l, err := s.queries.GetFeaturedLeagues(ctx)
|
l, err := s.queries.GetAllLeaguesWithSettings(ctx, dbgen.GetAllLeaguesWithSettingsParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
CountryCode: filter.CountryCode.ToPG(),
|
||||||
|
SportID: filter.SportID.ToPG(),
|
||||||
|
Limit: pgtype.Int4{
|
||||||
|
Int32: int32(filter.Limit.Value),
|
||||||
|
Valid: filter.Limit.Valid,
|
||||||
|
},
|
||||||
|
Offset: pgtype.Int4{
|
||||||
|
Int32: int32(filter.Offset.Value * filter.Limit.Value),
|
||||||
|
Valid: filter.Offset.Valid,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
leagues := make([]domain.League, len(l))
|
return domain.ConvertDBLeagueWithSettings(l), nil
|
||||||
for i, league := range l {
|
|
||||||
leagues[i] = domain.League{
|
|
||||||
ID: league.ID,
|
|
||||||
Name: league.Name,
|
|
||||||
CountryCode: league.CountryCode.String,
|
|
||||||
Bet365ID: league.Bet365ID.Int32,
|
|
||||||
IsActive: league.IsActive.Bool,
|
|
||||||
|
|
||||||
SportID: league.SportID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return leagues, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64) (bool, error) {
|
func (s *Store) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) {
|
||||||
return s.queries.CheckLeagueSupport(ctx, leagueID)
|
return s.queries.CheckLeagueSupport(ctx, dbgen.CheckLeagueSupportParams{
|
||||||
}
|
LeagueID: leagueID,
|
||||||
|
CompanyID: companyID,
|
||||||
func (s *Store) SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error {
|
|
||||||
return s.queries.SetLeagueActive(ctx, dbgen.SetLeagueActiveParams{
|
|
||||||
ID: leagueId,
|
|
||||||
IsActive: pgtype.Bool{
|
|
||||||
Bool: isActive,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||||
err := s.queries.UpdateLeague(ctx, dbgen.UpdateLeagueParams{
|
return s.queries.UpdateLeague(ctx, domain.ConvertUpdateLeague(league))
|
||||||
ID: league.ID,
|
|
||||||
Name: pgtype.Text{
|
|
||||||
String: league.Name.Value,
|
|
||||||
Valid: league.Name.Valid,
|
|
||||||
},
|
|
||||||
CountryCode: pgtype.Text{
|
|
||||||
String: league.CountryCode.Value,
|
|
||||||
Valid: league.CountryCode.Valid,
|
|
||||||
},
|
|
||||||
Bet365ID: pgtype.Int4{
|
|
||||||
Int32: league.Bet365ID.Value,
|
|
||||||
Valid: league.Bet365ID.Valid,
|
|
||||||
},
|
|
||||||
IsActive: pgtype.Bool{
|
|
||||||
Bool: league.IsActive.Value,
|
|
||||||
Valid: league.IsActive.Valid,
|
|
||||||
},
|
|
||||||
IsFeatured: pgtype.Bool{
|
|
||||||
Bool: league.IsFeatured.Value,
|
|
||||||
Valid: league.IsFeatured.Valid,
|
|
||||||
},
|
|
||||||
SportID: pgtype.Int4{
|
|
||||||
Int32: league.SportID.Value,
|
|
||||||
Valid: league.SportID.Valid,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
internal/repository/odd_history.go
Normal file
53
internal/repository/odd_history.go
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Store) InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error) {
|
||||||
|
dbOddHistory, err := s.queries.InsertOddHistory(ctx, domain.ConvertCreateOddHistory(odd))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.OddHistory{}, fmt.Errorf("InsertOddHistory failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBOddHistory(dbOddHistory), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||||
|
dbOddHistories, err := s.queries.GetAllOddHistory(ctx, dbgen.GetAllOddHistoryParams{
|
||||||
|
OddID: filter.OddID.ToPG(),
|
||||||
|
MarketID: filter.MarketID.ToPG(),
|
||||||
|
RawOddID: filter.RawOddID.ToPG(),
|
||||||
|
EventID: filter.EventID.ToPG(),
|
||||||
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllOddHistory failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertOddHistories(dbOddHistories), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||||
|
dbOddHistories, err := s.queries.GetInitialOddPerDay(ctx, dbgen.GetInitialOddPerDayParams{
|
||||||
|
OddID: filter.OddID.ToPG(),
|
||||||
|
MarketID: filter.MarketID.ToPG(),
|
||||||
|
RawOddID: filter.RawOddID.ToPG(),
|
||||||
|
EventID: filter.EventID.ToPG(),
|
||||||
|
CreatedAfter: filter.CreatedAfter.ToPG(),
|
||||||
|
CreatedBefore: filter.CreatedBefore.ToPG(),
|
||||||
|
DateTrunc: "day",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetInitialOddPerDay failed: %w", err)
|
||||||
|
}
|
||||||
|
return domain.ConvertOddHistories(dbOddHistories), nil
|
||||||
|
}
|
||||||
|
|
@ -13,55 +13,26 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) SaveNonLiveMarket(ctx context.Context, m domain.Market) error {
|
func (s *Store) SaveOddMarket(ctx context.Context, m domain.CreateOddMarket) error {
|
||||||
if len(m.Odds) == 0 {
|
if len(m.Odds) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range m.Odds {
|
params, err := domain.ConvertCreateOddMarket(m)
|
||||||
var name string
|
|
||||||
var oddsVal float64
|
|
||||||
|
|
||||||
if m.Source == "bwin" {
|
if err != nil {
|
||||||
nameValue := getMap(item["name"])
|
return err
|
||||||
name = getString(nameValue["value"])
|
}
|
||||||
oddsVal = getFloat(item["odds"])
|
|
||||||
} else {
|
|
||||||
name = getString(item["name"])
|
|
||||||
oddsVal = getConvertedFloat(item["odds"])
|
|
||||||
}
|
|
||||||
handicap := getString(item["handicap"])
|
|
||||||
|
|
||||||
rawOddsBytes, _ := json.Marshal(m.Odds)
|
err = s.queries.InsertOddsMarket(ctx, params)
|
||||||
|
if err != nil {
|
||||||
params := dbgen.InsertNonLiveOddParams{
|
_ = writeFailedMarketLog(m, err)
|
||||||
EventID: pgtype.Text{String: m.EventID, Valid: m.EventID != ""},
|
return err
|
||||||
Fi: pgtype.Text{String: m.FI, Valid: m.FI != ""},
|
|
||||||
MarketType: m.MarketType,
|
|
||||||
MarketName: pgtype.Text{String: m.MarketName, Valid: m.MarketName != ""},
|
|
||||||
MarketCategory: pgtype.Text{String: m.MarketCategory, Valid: m.MarketCategory != ""},
|
|
||||||
MarketID: pgtype.Text{String: m.MarketID, Valid: m.MarketID != ""},
|
|
||||||
Name: pgtype.Text{String: name, Valid: name != ""},
|
|
||||||
Handicap: pgtype.Text{String: handicap, Valid: handicap != ""},
|
|
||||||
OddsValue: pgtype.Float8{Float64: oddsVal, Valid: oddsVal != 0},
|
|
||||||
Section: m.MarketCategory,
|
|
||||||
Category: pgtype.Text{Valid: false},
|
|
||||||
RawOdds: rawOddsBytes,
|
|
||||||
IsActive: pgtype.Bool{Bool: true, Valid: true},
|
|
||||||
Source: pgtype.Text{String: m.Source, Valid: true},
|
|
||||||
FetchedAt: pgtype.Timestamp{Time: time.Now(), Valid: true},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := s.queries.InsertNonLiveOdd(ctx, params)
|
|
||||||
if err != nil {
|
|
||||||
_ = writeFailedMarketLog(m, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFailedMarketLog(m domain.Market, err error) error {
|
func writeFailedMarketLog(m domain.CreateOddMarket, err error) error {
|
||||||
logDir := "logs"
|
logDir := "logs"
|
||||||
logFile := logDir + "/failed_markets.log"
|
logFile := logDir + "/failed_markets.log"
|
||||||
|
|
||||||
|
|
@ -76,9 +47,9 @@ func writeFailedMarketLog(m domain.Market, err error) error {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
entry := struct {
|
entry := struct {
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
Record domain.Market `json:"record"`
|
Record domain.CreateOddMarket `json:"record"`
|
||||||
}{
|
}{
|
||||||
Time: time.Now().Format(time.RFC3339),
|
Time: time.Now().Format(time.RFC3339),
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
|
@ -90,196 +61,130 @@ func writeFailedMarketLog(m domain.Market, err error) error {
|
||||||
return writeErr
|
return writeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error) {
|
func (s *Store) GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error) {
|
||||||
odds, err := s.queries.GetPrematchOdds(ctx)
|
rows, err := s.queries.GetAllOdds(ctx, dbgen.GetAllOddsParams{
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
domainOdds := make([]domain.Odd, len(odds))
|
domainOdds, err := domain.ConvertDBOddMarkets(rows)
|
||||||
for i, odd := range odds {
|
|
||||||
domainOdds[i] = domain.Odd{
|
if err != nil {
|
||||||
EventID: odd.EventID.String,
|
return nil, err
|
||||||
Fi: odd.Fi.String,
|
|
||||||
MarketType: odd.MarketType,
|
|
||||||
MarketName: odd.MarketName.String,
|
|
||||||
MarketCategory: odd.MarketCategory.String,
|
|
||||||
MarketID: odd.MarketID.String,
|
|
||||||
Name: odd.Name.String,
|
|
||||||
Handicap: odd.Handicap.String,
|
|
||||||
OddsValue: odd.OddsValue.Float64,
|
|
||||||
Section: odd.Section,
|
|
||||||
Category: odd.Category.String,
|
|
||||||
RawOdds: func() []domain.RawMessage {
|
|
||||||
var rawOdds []domain.RawMessage
|
|
||||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
|
||||||
rawOdds = nil
|
|
||||||
}
|
|
||||||
return rawOdds
|
|
||||||
}(),
|
|
||||||
FetchedAt: odd.FetchedAt.Time,
|
|
||||||
Source: odd.Source.String,
|
|
||||||
IsActive: odd.IsActive.Bool,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return domainOdds, nil
|
return domainOdds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error) {
|
func (s *Store) GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||||
rows, err := s.queries.GetALLPrematchOdds(ctx)
|
odds, err := s.queries.GetAllOddsWithSettings(ctx, dbgen.GetAllOddsWithSettingsParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
domainOdds := make([]domain.Odd, len(rows))
|
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||||
for i, row := range rows {
|
|
||||||
domainOdds[i] = domain.Odd{
|
if err != nil {
|
||||||
// ID: int64(row.ID),
|
return nil, err
|
||||||
EventID: row.EventID.String,
|
|
||||||
Fi: row.Fi.String,
|
|
||||||
MarketType: row.MarketType,
|
|
||||||
MarketName: row.MarketName.String,
|
|
||||||
MarketCategory: row.MarketCategory.String,
|
|
||||||
MarketID: row.MarketID.String,
|
|
||||||
Name: row.Name.String,
|
|
||||||
Handicap: row.Handicap.String,
|
|
||||||
OddsValue: row.OddsValue.Float64,
|
|
||||||
Section: row.Section,
|
|
||||||
Category: row.Category.String,
|
|
||||||
RawOdds: func() []domain.RawMessage {
|
|
||||||
var rawOdds []domain.RawMessage
|
|
||||||
if err := json.Unmarshal(row.RawOdds, &rawOdds); err != nil {
|
|
||||||
rawOdds = nil
|
|
||||||
}
|
|
||||||
return rawOdds
|
|
||||||
}(),
|
|
||||||
FetchedAt: row.FetchedAt.Time,
|
|
||||||
Source: row.Source.String,
|
|
||||||
IsActive: row.IsActive.Bool,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return domainOdds, nil
|
return domainOdds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetRawOddsByMarketID(ctx context.Context, rawOddsID string, upcomingID string) (domain.RawOddsByMarketID, error) {
|
func (s *Store) GetOddsByMarketID(ctx context.Context, marketID string, eventID string) (domain.OddMarket, error) {
|
||||||
params := dbgen.GetRawOddsByMarketIDParams{
|
|
||||||
MarketID: pgtype.Text{String: rawOddsID, Valid: true},
|
|
||||||
Fi: pgtype.Text{String: upcomingID, Valid: true},
|
|
||||||
}
|
|
||||||
|
|
||||||
odds, err := s.queries.GetRawOddsByMarketID(ctx, params)
|
odds, err := s.queries.GetOddsByMarketID(ctx, dbgen.GetOddsByMarketIDParams{
|
||||||
|
MarketID: marketID,
|
||||||
|
EventID: eventID,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.RawOddsByMarketID{}, err
|
return domain.OddMarket{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawOdds []json.RawMessage
|
convertedOdd, err := domain.ConvertDBOddMarket(odds)
|
||||||
if err := json.Unmarshal(odds.RawOdds, &rawOdds); err != nil {
|
|
||||||
return domain.RawOddsByMarketID{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain.RawOddsByMarketID{
|
if err != nil {
|
||||||
ID: int64(odds.ID),
|
return domain.OddMarket{}, err
|
||||||
MarketName: odds.MarketName.String,
|
}
|
||||||
Handicap: odds.Handicap.String,
|
return convertedOdd, nil
|
||||||
RawOdds: func() []domain.RawMessage {
|
|
||||||
converted := make([]domain.RawMessage, len(rawOdds))
|
|
||||||
for i, r := range rawOdds {
|
|
||||||
converted[i] = domain.RawMessage(r)
|
|
||||||
}
|
|
||||||
return converted
|
|
||||||
}(),
|
|
||||||
FetchedAt: odds.FetchedAt.Time,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
func (s *Store) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.Odd, error) {
|
|
||||||
odds, err := s.queries.GetPaginatedPrematchOddsByUpcomingID(ctx, dbgen.GetPaginatedPrematchOddsByUpcomingIDParams{
|
func (s *Store) GetOddsWithSettingsByMarketID(ctx context.Context, marketID string, eventID string, companyID int64) (domain.OddMarketWithSettings, error) {
|
||||||
ID: upcomingID,
|
|
||||||
Limit: pgtype.Int4{
|
odds, err := s.queries.GetOddsWithSettingsByMarketID(ctx, dbgen.GetOddsWithSettingsByMarketIDParams{
|
||||||
Int32: int32(limit.Value),
|
MarketID: marketID,
|
||||||
Valid: limit.Valid,
|
EventID: eventID,
|
||||||
|
CompanyID: companyID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return domain.OddMarketWithSettings{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedOdd, err := domain.ConvertDBOddMarketWithSetting(odds)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.OddMarketWithSettings{}, err
|
||||||
|
}
|
||||||
|
return convertedOdd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||||
|
odds, err := s.queries.GetOddsByEventID(ctx, dbgen.GetOddsByEventIDParams{
|
||||||
|
EventID: upcomingID,
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
IsLive: pgtype.Bool{
|
||||||
|
Bool: false,
|
||||||
|
Valid: true,
|
||||||
},
|
},
|
||||||
Offset: pgtype.Int4{
|
Status: pgtype.Text{
|
||||||
Int32: int32(offset.Value),
|
String: string(domain.STATUS_PENDING),
|
||||||
Valid: offset.Valid,
|
Valid: true,
|
||||||
},
|
},
|
||||||
|
Source: pgtype.Text{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Map the results to domain.Odd
|
// Map the results to domain.Odd
|
||||||
domainOdds := make([]domain.Odd, len(odds))
|
domainOdds, err := domain.ConvertDBOddMarkets(odds)
|
||||||
for i, odd := range odds {
|
if err != nil {
|
||||||
var rawOdds []domain.RawMessage
|
return nil, err
|
||||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
|
||||||
rawOdds = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
domainOdds[i] = domain.Odd{
|
|
||||||
EventID: odd.EventID.String,
|
|
||||||
Fi: odd.Fi.String,
|
|
||||||
MarketType: odd.MarketType,
|
|
||||||
MarketName: odd.MarketName.String,
|
|
||||||
MarketCategory: odd.MarketCategory.String,
|
|
||||||
MarketID: odd.MarketID.String,
|
|
||||||
Name: odd.Name.String,
|
|
||||||
Handicap: odd.Handicap.String,
|
|
||||||
OddsValue: odd.OddsValue.Float64,
|
|
||||||
Section: odd.Section,
|
|
||||||
Category: odd.Category.String,
|
|
||||||
RawOdds: rawOdds,
|
|
||||||
FetchedAt: odd.FetchedAt.Time,
|
|
||||||
Source: odd.Source.String,
|
|
||||||
IsActive: odd.IsActive.Bool,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return domainOdds, nil
|
return domainOdds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error) {
|
func (s *Store) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID string, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||||
|
|
||||||
odds, err := s.queries.GetPrematchOddsByUpcomingID(ctx, upcomingID)
|
odds, err := s.queries.GetOddsWithSettingsByEventID(ctx, dbgen.GetOddsWithSettingsByEventIDParams{
|
||||||
|
EventID: upcomingID,
|
||||||
|
CompanyID: companyID,
|
||||||
|
Offset: filter.Offset.ToPG(),
|
||||||
|
Limit: filter.Limit.ToPG(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map the results to domain.Odd
|
// Map the results to domain.Odd
|
||||||
domainOdds := make([]domain.Odd, len(odds))
|
domainOdds, err := domain.ConvertDBOddMarketWithSettings(odds)
|
||||||
for i, odd := range odds {
|
if err != nil {
|
||||||
var rawOdds []domain.RawMessage
|
return nil, err
|
||||||
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
|
|
||||||
rawOdds = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
domainOdds[i] = domain.Odd{
|
|
||||||
EventID: odd.EventID.String,
|
|
||||||
Fi: odd.Fi.String,
|
|
||||||
MarketType: odd.MarketType,
|
|
||||||
MarketName: odd.MarketName.String,
|
|
||||||
MarketCategory: odd.MarketCategory.String,
|
|
||||||
MarketID: odd.MarketID.String,
|
|
||||||
Name: odd.Name.String,
|
|
||||||
Handicap: odd.Handicap.String,
|
|
||||||
OddsValue: odd.OddsValue.Float64,
|
|
||||||
Section: odd.Section,
|
|
||||||
Category: odd.Category.String,
|
|
||||||
RawOdds: rawOdds,
|
|
||||||
FetchedAt: odd.FetchedAt.Time,
|
|
||||||
Source: odd.Source.String,
|
|
||||||
IsActive: odd.IsActive.Bool,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return domainOdds, nil
|
return domainOdds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
func (s *Store) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||||
return s.queries.DeleteOddsForEvent(ctx, pgtype.Text{
|
return s.queries.DeleteOddsForEvent(ctx, eventID)
|
||||||
String: eventID,
|
|
||||||
Valid: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getString(v interface{}) string {
|
func getString(v interface{}) string {
|
||||||
|
|
|
||||||
|
|
@ -8,93 +8,34 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertDBResult(result dbgen.Result) domain.Result {
|
|
||||||
scores := make(map[string]domain.Score)
|
|
||||||
return domain.Result{
|
|
||||||
ID: result.ID,
|
|
||||||
BetOutcomeID: result.BetOutcomeID,
|
|
||||||
EventID: result.EventID,
|
|
||||||
OddID: result.OddID,
|
|
||||||
MarketID: result.MarketID,
|
|
||||||
Status: domain.OutcomeStatus(result.Status),
|
|
||||||
Score: result.Score.String,
|
|
||||||
FullTimeScore: result.FullTimeScore.String,
|
|
||||||
HalfTimeScore: result.HalfTimeScore.String,
|
|
||||||
SS: result.Ss.String,
|
|
||||||
Scores: scores,
|
|
||||||
CreatedAt: result.CreatedAt.Time,
|
|
||||||
UpdatedAt: result.UpdatedAt.Time,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertCreateResult(result domain.CreateResult) dbgen.CreateResultParams {
|
|
||||||
return dbgen.CreateResultParams{
|
|
||||||
BetOutcomeID: result.BetOutcomeID,
|
|
||||||
EventID: result.EventID,
|
|
||||||
OddID: result.OddID,
|
|
||||||
MarketID: result.MarketID,
|
|
||||||
Status: int32(result.Status),
|
|
||||||
Score: pgtype.Text{String: result.Score},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertResult(result domain.Result) dbgen.InsertResultParams {
|
|
||||||
return dbgen.InsertResultParams{
|
|
||||||
BetOutcomeID: result.BetOutcomeID,
|
|
||||||
EventID: result.EventID,
|
|
||||||
OddID: result.OddID,
|
|
||||||
MarketID: result.MarketID,
|
|
||||||
Status: int32(result.Status),
|
|
||||||
Score: pgtype.Text{String: result.Score},
|
|
||||||
FullTimeScore: pgtype.Text{String: result.FullTimeScore},
|
|
||||||
HalfTimeScore: pgtype.Text{String: result.HalfTimeScore},
|
|
||||||
Ss: pgtype.Text{String: result.SS},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) CreateResult(ctx context.Context, result domain.CreateResult) (domain.Result, error) {
|
func (s *Store) CreateResultLog(ctx context.Context, result domain.CreateResultLog) (domain.ResultLog, error) {
|
||||||
dbResult, err := s.queries.CreateResult(ctx, convertCreateResult(result))
|
dbResult, err := s.queries.CreateResultLog(ctx, domain.ConvertCreateResultLog(result))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Result{}, err
|
return domain.ResultLog{}, err
|
||||||
}
|
}
|
||||||
return convertDBResult(dbResult), nil
|
return domain.ConvertDBResultLog(dbResult), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) InsertResult(ctx context.Context, result domain.Result) error {
|
func (s *Store) GetAllResultLog(ctx context.Context, filter domain.ResultFilter) ([]domain.ResultLog, error) {
|
||||||
return s.queries.InsertResult(ctx, convertResult(result))
|
dbResultLogs, err := s.queries.GetAllResultLog(ctx, dbgen.GetAllResultLogParams{
|
||||||
}
|
CreatedBefore: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedBefore.Value,
|
||||||
func (s *Store) GetResultByBetOutcomeID(ctx context.Context, betOutcomeID int64) (domain.Result, error) {
|
Valid: filter.CreatedBefore.Valid,
|
||||||
dbResult, err := s.queries.GetResultByBetOutcomeID(ctx, betOutcomeID)
|
},
|
||||||
if err != nil {
|
CreatedAfter: pgtype.Timestamp{
|
||||||
return domain.Result{}, err
|
Time: filter.CreatedAfter.Value,
|
||||||
}
|
Valid: filter.CreatedAfter.Valid,
|
||||||
return convertDBResult(dbResult), nil
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
func (s *Store) GetPendingBetOutcomes(ctx context.Context) ([]domain.BetOutcome, error) {
|
|
||||||
dbOutcomes, err := s.queries.GetPendingBetOutcomes(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
outcomes := make([]domain.BetOutcome, 0, len(dbOutcomes))
|
result := make([]domain.ResultLog, 0, len(dbResultLogs))
|
||||||
for _, dbOutcome := range dbOutcomes {
|
for _, dbResultLog := range dbResultLogs {
|
||||||
outcomes = append(outcomes, domain.BetOutcome{
|
result = append(result, domain.ConvertDBResultLog(dbResultLog))
|
||||||
ID: dbOutcome.ID,
|
|
||||||
BetID: dbOutcome.BetID,
|
|
||||||
EventID: dbOutcome.EventID,
|
|
||||||
OddID: dbOutcome.OddID,
|
|
||||||
HomeTeamName: dbOutcome.HomeTeamName,
|
|
||||||
AwayTeamName: dbOutcome.AwayTeamName,
|
|
||||||
MarketID: dbOutcome.MarketID,
|
|
||||||
MarketName: dbOutcome.MarketName,
|
|
||||||
Odd: dbOutcome.Odd,
|
|
||||||
OddName: dbOutcome.OddName,
|
|
||||||
OddHeader: dbOutcome.OddHeader,
|
|
||||||
OddHandicap: dbOutcome.OddHandicap,
|
|
||||||
Status: domain.OutcomeStatus(dbOutcome.Status),
|
|
||||||
Expires: dbOutcome.Expires.Time,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return outcomes, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,116 +2,24 @@ package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
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"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetDBSettingList(settings []dbgen.Setting) (domain.SettingList, error) {
|
func (s *Store) GetGlobalSettingList(ctx context.Context) (domain.SettingList, error) {
|
||||||
var dbSettingList domain.DBSettingList
|
settings, err := s.queries.GetGlobalSettings(ctx)
|
||||||
|
|
||||||
var int64SettingsMap = domain.ConvertInt64SettingsMap(&dbSettingList)
|
|
||||||
var stringSettingsMap = domain.ConvertStringSettingsMap(&dbSettingList)
|
|
||||||
var boolSettingsMap = domain.ConvertBoolSettingsMap(&dbSettingList)
|
|
||||||
var float32SettingsMap = domain.ConvertFloat32SettingsMap(&dbSettingList)
|
|
||||||
var timeSettingsMap = domain.ConvertTimeSettingsMap(&dbSettingList)
|
|
||||||
|
|
||||||
for _, setting := range settings {
|
|
||||||
is_setting_unknown := true
|
|
||||||
for key, dbSetting := range int64SettingsMap {
|
|
||||||
if setting.Key == key {
|
|
||||||
value, err := strconv.ParseInt(setting.Value, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return domain.SettingList{}, err
|
|
||||||
}
|
|
||||||
*dbSetting = domain.ValidInt64{
|
|
||||||
Value: value,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
is_setting_unknown = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, dbSetting := range stringSettingsMap {
|
|
||||||
if setting.Key == key {
|
|
||||||
*dbSetting = domain.ValidString{
|
|
||||||
Value: setting.Value,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
is_setting_unknown = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, dbSetting := range boolSettingsMap {
|
|
||||||
if setting.Key == key {
|
|
||||||
value, err := strconv.ParseBool(setting.Value)
|
|
||||||
if err != nil {
|
|
||||||
return domain.SettingList{}, err
|
|
||||||
}
|
|
||||||
*dbSetting = domain.ValidBool{
|
|
||||||
Value: value,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
is_setting_unknown = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, dbSetting := range float32SettingsMap {
|
|
||||||
if setting.Key == key {
|
|
||||||
value, err := strconv.ParseFloat(setting.Value, 32)
|
|
||||||
if err != nil {
|
|
||||||
return domain.SettingList{}, err
|
|
||||||
}
|
|
||||||
*dbSetting = domain.ValidFloat32{
|
|
||||||
Value: float32(value),
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
is_setting_unknown = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for key, dbSetting := range timeSettingsMap {
|
|
||||||
if setting.Key == key {
|
|
||||||
value, err := time.Parse(time.RFC3339, setting.Value)
|
|
||||||
if err != nil {
|
|
||||||
return domain.SettingList{}, err
|
|
||||||
}
|
|
||||||
*dbSetting = domain.ValidTime{
|
|
||||||
Value: value,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
is_setting_unknown = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_setting_unknown {
|
|
||||||
domain.MongoDBLogger.Warn("unknown setting found on database", zap.String("setting", setting.Key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, dbSetting := range int64SettingsMap {
|
|
||||||
if !dbSetting.Valid {
|
|
||||||
fmt.Printf("setting value not found on database: %v \n", key)
|
|
||||||
domain.MongoDBLogger.Warn("setting value not found on database", zap.String("setting", key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain.ConvertDBSetting(dbSettingList), nil
|
|
||||||
}
|
|
||||||
func (s *Store) GetSettingList(ctx context.Context) (domain.SettingList, error) {
|
|
||||||
settings, err := s.queries.GetSettings(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||||
|
return domain.SettingList{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetDBSettingList(settings)
|
return domain.ConvertDBGlobalSettingList(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetSettings(ctx context.Context) ([]domain.Setting, error) {
|
func (s *Store) GetGlobalSettings(ctx context.Context) ([]domain.Setting, error) {
|
||||||
settings, err := s.queries.GetSettings(ctx)
|
settings, err := s.queries.GetGlobalSettings(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||||
|
|
@ -129,8 +37,8 @@ func (s *Store) GetSettings(ctx context.Context) ([]domain.Setting, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetSetting(ctx context.Context, key string) (domain.Setting, error) {
|
func (s *Store) GetGlobalSetting(ctx context.Context, key string) (domain.Setting, error) {
|
||||||
dbSetting, err := s.queries.GetSetting(ctx, key)
|
dbSetting, err := s.queries.GetGlobalSetting(ctx, key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
domain.MongoDBLogger.Error("failed to get all settings", zap.Error(err))
|
||||||
|
|
@ -145,23 +53,121 @@ func (s *Store) GetSetting(ctx context.Context, key string) (domain.Setting, err
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) SaveSetting(ctx context.Context, key, value string) (domain.Setting, error) {
|
func (s *Store) UpdateGlobalSetting(ctx context.Context, key, value string) error {
|
||||||
dbSetting, err := s.queries.SaveSetting(ctx, dbgen.SaveSettingParams{
|
err := s.queries.UpdateGlobalSetting(ctx, dbgen.UpdateGlobalSettingParams{
|
||||||
Key: key,
|
Key: key,
|
||||||
Value: value,
|
Value: value,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain.MongoDBLogger.Error("failed to update setting", zap.String("key", key), zap.String("value", value), zap.Error(err))
|
domain.MongoDBLogger.Error("failed to update setting",
|
||||||
|
zap.String("key", key),
|
||||||
|
zap.String("value", value),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
|
||||||
return domain.Setting{}, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
setting := domain.Setting{
|
return err
|
||||||
Key: dbSetting.Key,
|
|
||||||
Value: dbSetting.Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
return setting, err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateGlobalSettingList(ctx context.Context, settingList domain.ValidSettingList) error {
|
||||||
|
convertedSettings := settingList.ConvertAllSettings()
|
||||||
|
|
||||||
|
for _, setting := range convertedSettings {
|
||||||
|
err := s.UpdateGlobalSetting(ctx, setting.Key, setting.Value)
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Warn("failed to update setting list", zap.String("key", setting.Key), zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) InsertCompanySetting(ctx context.Context, key, value string, companyID int64) error {
|
||||||
|
err := s.queries.InsertCompanySetting(ctx, dbgen.InsertCompanySettingParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) InsertCompanySettingList(ctx context.Context, settingList domain.ValidSettingList, companyID int64) error {
|
||||||
|
convertedSettings := settingList.ConvertAllSettings()
|
||||||
|
|
||||||
|
for _, setting := range convertedSettings {
|
||||||
|
err := s.InsertCompanySetting(ctx, setting.Key, setting.Value, companyID)
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Warn("failed to update setting list", zap.String("key", setting.Key), zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllCompanySettings(ctx context.Context) ([]domain.CompanySetting, error) {
|
||||||
|
settings, err := s.queries.GetAllCompanySettings(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertCompanySettings(settings), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetCompanySettingsByKey(ctx context.Context, key string) ([]domain.CompanySetting, error) {
|
||||||
|
settings, err := s.queries.GetCompanySettingsByKey(ctx, key)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertCompanySettings(settings), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetOverrideSettings(ctx context.Context, companyID int64) ([]domain.Setting, error) {
|
||||||
|
settings, err := s.queries.GetOverrideSettings(ctx, companyID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]domain.Setting, 0, len(settings))
|
||||||
|
for _, setting := range settings {
|
||||||
|
result = append(result, domain.Setting{
|
||||||
|
Key: setting.Key,
|
||||||
|
Value: setting.Value,
|
||||||
|
UpdatedAt: setting.UpdatedAt.Time,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetOverrideSettingsList(ctx context.Context, companyID int64) (domain.SettingList, error) {
|
||||||
|
settings, err := s.queries.GetOverrideSettings(ctx, companyID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.SettingList{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.ConvertDBOverrideSettingList(settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) DeleteCompanySetting(ctx context.Context, companyID int64, key string) error {
|
||||||
|
return s.queries.DeleteCompanySetting(ctx, dbgen.DeleteCompanySettingParams{
|
||||||
|
CompanyID: companyID,
|
||||||
|
Key: key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (s *Store) DeleteAllCompanySetting(ctx context.Context, companyID int64,) error {
|
||||||
|
return s.queries.DeleteAllCompanySetting(ctx, companyID)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func convertDBShopBetDetail(bet dbgen.ShopBetDetail) domain.ShopBetDetail {
|
||||||
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
||||||
|
|
||||||
for _, outcome := range bet.Outcomes {
|
for _, outcome := range bet.Outcomes {
|
||||||
outcomes = append(outcomes, convertDBBetOutcomes(outcome))
|
outcomes = append(outcomes, domain.ConvertDBBetOutcomes(outcome))
|
||||||
}
|
}
|
||||||
return domain.ShopBetDetail{
|
return domain.ShopBetDetail{
|
||||||
ID: bet.ID,
|
ID: bet.ID,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ func convertDBTicket(ticket dbgen.Ticket) domain.Ticket {
|
||||||
ID: ticket.ID,
|
ID: ticket.ID,
|
||||||
Amount: domain.Currency(ticket.Amount),
|
Amount: domain.Currency(ticket.Amount),
|
||||||
TotalOdds: ticket.TotalOdds,
|
TotalOdds: ticket.TotalOdds,
|
||||||
|
CompanyID: ticket.CompanyID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,6 +72,7 @@ func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams {
|
||||||
Amount: int64(ticket.Amount),
|
Amount: int64(ticket.Amount),
|
||||||
TotalOdds: ticket.TotalOdds,
|
TotalOdds: ticket.TotalOdds,
|
||||||
Ip: ticket.IP,
|
Ip: ticket.IP,
|
||||||
|
CompanyID: ticket.CompanyID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,8 +112,8 @@ func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket,
|
||||||
return convertDBTicketOutcomes(ticket), nil
|
return convertDBTicketOutcomes(ticket), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
|
func (s *Store) GetAllTickets(ctx context.Context, filter domain.TicketFilter) ([]domain.GetTicket, error) {
|
||||||
tickets, err := s.queries.GetAllTickets(ctx)
|
tickets, err := s.queries.GetAllTickets(ctx, filter.CompanyID.ToPG())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ func (s *Store) CreateUser(ctx context.Context, user domain.User, usedOtpId int6
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
|
CompanyID: user.CompanyID.ToPG(),
|
||||||
|
Suspended: user.Suspended,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.User{}, err
|
return domain.User{}, err
|
||||||
|
|
@ -57,6 +59,15 @@ func (s *Store) CreateUser(ctx context.Context, user domain.User, usedOtpId int6
|
||||||
Email: userRes.Email.String,
|
Email: userRes.Email.String,
|
||||||
PhoneNumber: userRes.PhoneNumber.String,
|
PhoneNumber: userRes.PhoneNumber.String,
|
||||||
Role: domain.Role(userRes.Role),
|
Role: domain.Role(userRes.Role),
|
||||||
|
CompanyID: domain.ValidInt64{
|
||||||
|
Value: userRes.CompanyID.Int64,
|
||||||
|
Valid: userRes.CompanyID.Valid,
|
||||||
|
},
|
||||||
|
EmailVerified: userRes.EmailVerified,
|
||||||
|
PhoneVerified: userRes.PhoneVerified,
|
||||||
|
CreatedAt: userRes.CreatedAt.Time,
|
||||||
|
UpdatedAt: userRes.UpdatedAt.Time,
|
||||||
|
Suspended: userRes.Suspended,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
func (s *Store) GetUserByID(ctx context.Context, id int64) (domain.User, error) {
|
func (s *Store) GetUserByID(ctx context.Context, id int64) (domain.User, error) {
|
||||||
|
|
@ -247,18 +258,14 @@ func (s *Store) GetCashiersByBranch(ctx context.Context, branchID int64) ([]doma
|
||||||
func (s *Store) SearchUserByNameOrPhone(ctx context.Context, searchString string, role *domain.Role, companyID domain.ValidInt64) ([]domain.User, error) {
|
func (s *Store) SearchUserByNameOrPhone(ctx context.Context, searchString string, role *domain.Role, companyID domain.ValidInt64) ([]domain.User, error) {
|
||||||
|
|
||||||
query := dbgen.SearchUserByNameOrPhoneParams{
|
query := dbgen.SearchUserByNameOrPhoneParams{
|
||||||
Column1: pgtype.Text{
|
CompanyID: companyID.ToPG(),
|
||||||
|
Column2: pgtype.Text{
|
||||||
String: searchString,
|
String: searchString,
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
CompanyID: pgtype.Int8{
|
|
||||||
Int64: companyID.Value,
|
|
||||||
Valid: companyID.Valid,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if role != nil {
|
if role != nil {
|
||||||
|
|
||||||
query.Role = pgtype.Text{
|
query.Role = pgtype.Text{
|
||||||
String: string(*role),
|
String: string(*role),
|
||||||
Valid: true,
|
Valid: true,
|
||||||
|
|
@ -340,7 +347,7 @@ func (s *Store) DeleteUser(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error) {
|
func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string, companyID domain.ValidInt64) (bool, bool, error) {
|
||||||
|
|
||||||
row, err := s.queries.CheckPhoneEmailExist(ctx, dbgen.CheckPhoneEmailExistParams{
|
row, err := s.queries.CheckPhoneEmailExist(ctx, dbgen.CheckPhoneEmailExistParams{
|
||||||
PhoneNumber: pgtype.Text{
|
PhoneNumber: pgtype.Text{
|
||||||
|
|
@ -352,6 +359,7 @@ func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string
|
||||||
|
|
||||||
Valid: email != "",
|
Valid: email != "",
|
||||||
},
|
},
|
||||||
|
CompanyID: companyID.ToPG(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -360,10 +368,13 @@ func (s *Store) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string
|
||||||
return row.EmailExists, row.PhoneExists, nil
|
return row.EmailExists, row.PhoneExists, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetUserByEmail(ctx context.Context, email string) (domain.User, error) {
|
func (s *Store) GetUserByEmail(ctx context.Context, email string, companyID domain.ValidInt64) (domain.User, error) {
|
||||||
user, err := s.queries.GetUserByEmail(ctx, pgtype.Text{
|
user, err := s.queries.GetUserByEmail(ctx, dbgen.GetUserByEmailParams{
|
||||||
String: email,
|
Email: pgtype.Text{
|
||||||
Valid: true,
|
String: email,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
CompanyID: companyID.ToPG(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
|
@ -386,10 +397,13 @@ func (s *Store) GetUserByEmail(ctx context.Context, email string) (domain.User,
|
||||||
SuspendedAt: user.SuspendedAt.Time,
|
SuspendedAt: user.SuspendedAt.Time,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
func (s *Store) GetUserByPhone(ctx context.Context, phoneNum string) (domain.User, error) {
|
func (s *Store) GetUserByPhone(ctx context.Context, phoneNum string, companyID domain.ValidInt64) (domain.User, error) {
|
||||||
user, err := s.queries.GetUserByPhone(ctx, pgtype.Text{
|
user, err := s.queries.GetUserByPhone(ctx, dbgen.GetUserByPhoneParams{
|
||||||
String: phoneNum,
|
PhoneNumber: pgtype.Text{
|
||||||
Valid: true,
|
String: phoneNum,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
CompanyID: companyID.ToPG(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ type LoginSuccess struct {
|
||||||
CompanyID domain.ValidInt64
|
CompanyID domain.ValidInt64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Login(ctx context.Context, email, phone string, password string) (LoginSuccess, error) {
|
func (s *Service) Login(ctx context.Context, email, phone string, password string, companyID domain.ValidInt64) (LoginSuccess, error) {
|
||||||
user, err := s.userStore.GetUserByEmailPhone(ctx, email, phone)
|
user, err := s.userStore.GetUserByEmailPhone(ctx, email, phone, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LoginSuccess{}, err
|
return LoginSuccess{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserStore interface {
|
type UserStore interface {
|
||||||
GetUserByEmailPhone(ctx context.Context, email, phone string) (domain.User, error)
|
GetUserByEmailPhone(ctx context.Context, email, phone string, companyID domain.ValidInt64) (domain.User, error)
|
||||||
}
|
}
|
||||||
type TokenStore interface {
|
type TokenStore interface {
|
||||||
CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error
|
CreateRefreshToken(ctx context.Context, rt domain.RefreshToken) error
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
||||||
return domain.CreateBetOutcome{}, ErrEventHasNotEnded
|
return domain.CreateBetOutcome{}, ErrEventHasNotEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
odds, err := s.prematchSvc.GetRawOddsByMarketID(ctx, marketIDStr, eventIDStr)
|
odds, err := s.prematchSvc.GetOddsByMarketID(ctx, marketIDStr, eventIDStr)
|
||||||
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),
|
||||||
|
|
@ -215,8 +215,8 @@ func (s *Service) GenerateBetOutcome(ctx context.Context, eventID int64, marketI
|
||||||
return newOutcome, nil
|
return newOutcome, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID int64, role domain.Role, companyID domain.ValidInt64) (domain.CreateBetRes, error) {
|
func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID int64, role domain.Role, companyID int64) (domain.CreateBetRes, error) {
|
||||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, companyID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.CreateBetRes{}, err
|
return domain.CreateBetRes{}, err
|
||||||
|
|
@ -297,6 +297,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
OutcomesHash: outcomesHash,
|
OutcomesHash: outcomesHash,
|
||||||
FastCode: fastCode,
|
FastCode: fastCode,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
CompanyID: companyID,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch role {
|
switch role {
|
||||||
|
|
@ -347,7 +348,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
return domain.CreateBetRes{}, err
|
return domain.CreateBetRes{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if companyID.Valid && branch.CompanyID == companyID.Value {
|
if branch.CompanyID == companyID {
|
||||||
s.mongoLogger.Warn("unauthorized company",
|
s.mongoLogger.Warn("unauthorized company",
|
||||||
zap.Int64("branch_id", *req.BranchID),
|
zap.Int64("branch_id", *req.BranchID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
|
|
@ -375,6 +376,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
)
|
)
|
||||||
return domain.CreateBetRes{}, err
|
return domain.CreateBetRes{}, err
|
||||||
}
|
}
|
||||||
|
//
|
||||||
default:
|
default:
|
||||||
s.mongoLogger.Error("unknown role type",
|
s.mongoLogger.Error("unknown role type",
|
||||||
zap.String("role", string(role)),
|
zap.String("role", string(role)),
|
||||||
|
|
@ -477,7 +479,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res := domain.ConvertCreateBet(bet, rows)
|
res := domain.ConvertCreateBetRes(bet, rows)
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
@ -581,7 +583,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
||||||
var newOdds []domain.CreateBetOutcome
|
var newOdds []domain.CreateBetOutcome
|
||||||
var totalOdds float32 = 1
|
var totalOdds float32 = 1
|
||||||
|
|
||||||
markets, err := s.prematchSvc.GetPrematchOddsByUpcomingID(ctx, eventID)
|
markets, err := s.prematchSvc.GetOddsByEventID(ctx, eventID, domain.OddMarketWithEventFilter{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to get odds for event", "event id", eventID, "error", err)
|
s.logger.Error("failed to get odds for event", "event id", eventID, "error", err)
|
||||||
s.mongoLogger.Error("failed to get odds for event",
|
s.mongoLogger.Error("failed to get odds for event",
|
||||||
|
|
@ -603,7 +605,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
||||||
return nil, 0, fmt.Errorf("empty odds or event %v", eventID)
|
return nil, 0, fmt.Errorf("empty odds or event %v", eventID)
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedMarkets []domain.Odd
|
var selectedMarkets []domain.OddMarket
|
||||||
numMarkets = min(numMarkets, len(markets))
|
numMarkets = min(numMarkets, len(markets))
|
||||||
for i := 0; i < numMarkets; i++ {
|
for i := 0; i < numMarkets; i++ {
|
||||||
randomIndex := random.Intn(len(markets))
|
randomIndex := random.Intn(len(markets))
|
||||||
|
|
@ -714,7 +716,7 @@ func (s *Service) GenerateRandomBetOutcomes(ctx context.Context, eventID string,
|
||||||
return newOdds, totalOdds, nil
|
return newOdds, totalOdds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, leagueID, sportID domain.ValidInt32, firstStartTime, lastStartTime domain.ValidTime) (domain.CreateBetRes, error) {
|
func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID, companyID int64, leagueID domain.ValidInt64, sportID domain.ValidInt32, firstStartTime, lastStartTime domain.ValidTime) (domain.CreateBetRes, error) {
|
||||||
|
|
||||||
// Get a unexpired event id
|
// Get a unexpired event id
|
||||||
|
|
||||||
|
|
@ -742,7 +744,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add the option of passing number of created events
|
// TODO: Add the option of passing number of created events
|
||||||
var selectedUpcomingEvents []domain.UpcomingEvent
|
var selectedUpcomingEvents []domain.BaseEvent
|
||||||
numEventsPerBet := min(random.Intn(4)+1, len(events)) //Eliminate the option of 0
|
numEventsPerBet := min(random.Intn(4)+1, len(events)) //Eliminate the option of 0
|
||||||
|
|
||||||
for i := 0; i < int(numEventsPerBet); i++ {
|
for i := 0; i < int(numEventsPerBet); i++ {
|
||||||
|
|
@ -816,6 +818,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
||||||
TotalOdds: totalOdds,
|
TotalOdds: totalOdds,
|
||||||
Status: domain.OUTCOME_STATUS_PENDING,
|
Status: domain.OUTCOME_STATUS_PENDING,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
CompanyID: companyID,
|
||||||
IsShopBet: true,
|
IsShopBet: true,
|
||||||
FastCode: fastCode,
|
FastCode: fastCode,
|
||||||
}
|
}
|
||||||
|
|
@ -842,7 +845,7 @@ func (s *Service) PlaceRandomBet(ctx context.Context, userID, branchID int64, le
|
||||||
return domain.CreateBetRes{}, err
|
return domain.CreateBetRes{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := domain.ConvertCreateBet(bet, rows)
|
res := domain.ConvertCreateBetRes(bet, rows)
|
||||||
|
|
||||||
s.mongoLogger.Info("Random bets placed successfully",
|
s.mongoLogger.Info("Random bets placed successfully",
|
||||||
zap.Int64("userID", userID),
|
zap.Int64("userID", userID),
|
||||||
|
|
@ -987,6 +990,8 @@ func (s *Service) SendWinningStatusNotification(ctx context.Context, status doma
|
||||||
|
|
||||||
betNotification := &domain.Notification{
|
betNotification := &domain.Notification{
|
||||||
RecipientID: userID,
|
RecipientID: userID,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||||
Level: domain.NotificationLevelSuccess,
|
Level: domain.NotificationLevelSuccess,
|
||||||
Reciever: domain.NotificationRecieverSideCustomer,
|
Reciever: domain.NotificationRecieverSideCustomer,
|
||||||
|
|
@ -1028,6 +1033,8 @@ func (s *Service) SendLosingStatusNotification(ctx context.Context, status domai
|
||||||
|
|
||||||
betNotification := &domain.Notification{
|
betNotification := &domain.Notification{
|
||||||
RecipientID: userID,
|
RecipientID: userID,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||||
Level: domain.NotificationLevelSuccess,
|
Level: domain.NotificationLevelSuccess,
|
||||||
Reciever: domain.NotificationRecieverSideCustomer,
|
Reciever: domain.NotificationRecieverSideCustomer,
|
||||||
|
|
@ -1070,6 +1077,8 @@ func (s *Service) SendErrorStatusNotification(ctx context.Context, status domain
|
||||||
|
|
||||||
betNotification := &domain.Notification{
|
betNotification := &domain.Notification{
|
||||||
RecipientID: userID,
|
RecipientID: userID,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||||
Level: domain.NotificationLevelSuccess,
|
Level: domain.NotificationLevelSuccess,
|
||||||
Reciever: domain.NotificationRecieverSideCustomer,
|
Reciever: domain.NotificationRecieverSideCustomer,
|
||||||
|
|
@ -1104,11 +1113,15 @@ func (s *Service) SendAdminErrorAlertNotification(ctx context.Context, status do
|
||||||
|
|
||||||
switch status {
|
switch status {
|
||||||
case domain.OUTCOME_STATUS_ERROR, domain.OUTCOME_STATUS_PENDING:
|
case domain.OUTCOME_STATUS_ERROR, domain.OUTCOME_STATUS_PENDING:
|
||||||
headline = "There was an error with your bet"
|
headline = "There was an error processing bet"
|
||||||
message = "We have encounter an error with your bet. We will fix it as soon as we can"
|
message = "We have encounter an error with bet. We will fix it as soon as we can"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorSeverity := domain.NotificationErrorSeverityHigh
|
||||||
betNotification := &domain.Notification{
|
betNotification := &domain.Notification{
|
||||||
|
ErrorSeverity: &errorSeverity,
|
||||||
|
DeliveryStatus: domain.DeliveryStatusPending,
|
||||||
|
IsRead: false,
|
||||||
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
Type: domain.NOTIFICATION_TYPE_BET_RESULT,
|
||||||
Level: domain.NotificationLevelSuccess,
|
Level: domain.NotificationLevelSuccess,
|
||||||
Reciever: domain.NotificationRecieverSideCustomer,
|
Reciever: domain.NotificationRecieverSideCustomer,
|
||||||
|
|
@ -1300,7 +1313,7 @@ func (s *Service) SetBetToRemoved(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
||||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
|
||||||
bets, err := s.betStore.GetBetsForCashback(ctx)
|
bets, err := s.betStore.GetBetsForCashback(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error("failed to fetch bets",
|
s.mongoLogger.Error("failed to fetch bets",
|
||||||
|
|
@ -1309,6 +1322,7 @@ func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for _, bet := range bets {
|
for _, bet := range bets {
|
||||||
shouldProcess := true
|
shouldProcess := true
|
||||||
loseCount := 0
|
loseCount := 0
|
||||||
|
|
@ -1349,6 +1363,8 @@ func (s *Service) ProcessBetCashback(ctx context.Context) error {
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, bet.CompanyID)
|
||||||
cashbackAmount := math.Min(float64(settingsList.CashbackAmountCap.Float32()), float64(calculateCashbackAmount(bet.Amount.Float32(), bet.TotalOdds)))
|
cashbackAmount := math.Min(float64(settingsList.CashbackAmountCap.Float32()), float64(calculateCashbackAmount(bet.Amount.Float32(), bet.TotalOdds)))
|
||||||
|
|
||||||
_, err = s.walletSvc.AddToWallet(ctx, wallets.StaticID, domain.ToCurrency(float32(cashbackAmount)), domain.ValidInt64{}, domain.TRANSFER_DIRECT,
|
_, err = s.walletSvc.AddToWallet(ctx, wallets.StaticID, domain.ToCurrency(float32(cashbackAmount)), domain.ValidInt64{}, domain.TRANSFER_DIRECT,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ 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)
|
||||||
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
|
||||||
DeleteCompany(ctx context.Context, id int64) error
|
DeleteCompany(ctx context.Context, id int64) error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ 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){
|
||||||
|
return s.companyStore.GetCompanyIDBySlug(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)
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
FetchLiveEvents(ctx context.Context) error
|
// FetchLiveEvents(ctx context.Context) error
|
||||||
FetchUpcomingEvents(ctx context.Context) error
|
FetchUpcomingEvents(ctx context.Context) error
|
||||||
GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
|
GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error)
|
||||||
GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error)
|
GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error)
|
||||||
GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error)
|
GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error)
|
||||||
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
|
GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error)
|
||||||
// GetAndStoreMatchResult(ctx context.Context, eventID string) error
|
// GetAndStoreMatchResult(ctx context.Context, eventID string) error
|
||||||
UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error
|
UpdateFinalScore(ctx context.Context, eventID, fullScore string, status domain.EventStatus) error
|
||||||
UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error
|
UpdateEventStatus(ctx context.Context, eventID string, status domain.EventStatus) error
|
||||||
UpdateFeatured(ctx context.Context, eventID string, flagged bool) error
|
IsEventMonitored(ctx context.Context, eventID string) (bool, error)
|
||||||
|
UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error
|
||||||
|
GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error)
|
||||||
|
GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error)
|
||||||
|
UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,162 +32,162 @@ func New(token string, store *repository.Store, mongoLogger *zap.Logger) Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) FetchLiveEvents(ctx context.Context) error {
|
// func (s *service) FetchLiveEvents(ctx context.Context) error {
|
||||||
var wg sync.WaitGroup
|
// var wg sync.WaitGroup
|
||||||
urls := []struct {
|
// urls := []struct {
|
||||||
name string
|
// name string
|
||||||
source string
|
// source string
|
||||||
}{
|
// }{
|
||||||
{"https://api.b365api.com/v1/bet365/inplay?sport_id=%d&token=%s", "bet365"},
|
// {"https://api.b365api.com/v1/bet365/inplay?sport_id=%d&token=%s", "bet365"},
|
||||||
{"https://api.b365api.com/v1/betfair/sb/inplay?sport_id=%d&token=%s", "betfair"},
|
// {"https://api.b365api.com/v1/betfair/sb/inplay?sport_id=%d&token=%s", "betfair"},
|
||||||
{"https://api.b365api.com/v1/1xbet/inplay?sport_id=%d&token=%s", "1xbet"},
|
// {"https://api.b365api.com/v1/1xbet/inplay?sport_id=%d&token=%s", "1xbet"},
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, url := range urls {
|
// for _, url := range urls {
|
||||||
wg.Add(1)
|
// wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
// go func() {
|
||||||
defer wg.Done()
|
// defer wg.Done()
|
||||||
s.fetchLiveEvents(ctx, url.name, url.source)
|
// s.fetchLiveEvents(ctx, url.name, url.source)
|
||||||
}()
|
// }()
|
||||||
}
|
// }
|
||||||
wg.Wait()
|
// wg.Wait()
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *service) fetchLiveEvents(ctx context.Context, url, source string) error {
|
// func (s *service) fetchLiveEvents(ctx context.Context, url, source string) error {
|
||||||
sportIDs := []int{1, 13, 78, 18, 91, 16, 17, 14, 12, 3, 2, 4, 83, 15, 92, 94, 8, 19, 36, 66, 9, 75, 90, 95, 110, 107, 151, 162, 148}
|
// sportIDs := []int{1, 13, 78, 18, 91, 16, 17, 14, 12, 3, 2, 4, 83, 15, 92, 94, 8, 19, 36, 66, 9, 75, 90, 95, 110, 107, 151, 162, 148}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
// var wg sync.WaitGroup
|
||||||
|
|
||||||
for _, sportID := range sportIDs {
|
// for _, sportID := range sportIDs {
|
||||||
wg.Add(1)
|
// wg.Add(1)
|
||||||
go func(sportID int) {
|
// go func(sportID int) {
|
||||||
defer wg.Done()
|
// defer wg.Done()
|
||||||
|
|
||||||
url := fmt.Sprintf(url, sportID, s.token)
|
// url := fmt.Sprintf(url, sportID, s.token)
|
||||||
resp, err := http.Get(url)
|
// resp, err := http.Get(url)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
fmt.Printf(" Failed request for sport_id=%d: %v\n", sportID, err)
|
// fmt.Printf(" Failed request for sport_id=%d: %v\n", sportID, err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
defer resp.Body.Close()
|
// defer resp.Body.Close()
|
||||||
|
|
||||||
body, _ := io.ReadAll(resp.Body)
|
// body, _ := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
events := []domain.Event{}
|
// events := []domain.Event{}
|
||||||
switch source {
|
// switch source {
|
||||||
case "bet365":
|
// case "bet365":
|
||||||
events = handleBet365prematch(body, sportID, source)
|
// events = handleBet365prematch(body, sportID, source)
|
||||||
case "betfair":
|
// case "betfair":
|
||||||
events = handleBetfairprematch(body, sportID, source)
|
// events = handleBetfairprematch(body, sportID, source)
|
||||||
case "1xbet":
|
// case "1xbet":
|
||||||
// betfair and 1xbet have the same result structure
|
// // betfair and 1xbet have the same result structure
|
||||||
events = handleBetfairprematch(body, sportID, source)
|
// events = handleBetfairprematch(body, sportID, source)
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, event := range events {
|
// for _, event := range events {
|
||||||
if err := s.store.SaveEvent(ctx, event); err != nil {
|
// if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||||
fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
// fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}(sportID)
|
// }(sportID)
|
||||||
}
|
// }
|
||||||
|
|
||||||
wg.Wait()
|
// wg.Wait()
|
||||||
fmt.Println("All live events fetched and stored.")
|
// fmt.Println("All live events fetched and stored.")
|
||||||
return nil
|
// return nil
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
func handleBet365prematch(body []byte, sportID int, source string) []domain.Event {
|
// func handleBet365prematch(body []byte, sportID int, source string) []domain.Event {
|
||||||
var data struct {
|
// var data struct {
|
||||||
Success int `json:"success"`
|
// Success int `json:"success"`
|
||||||
Results [][]map[string]interface{} `json:"results"`
|
// Results [][]map[string]interface{} `json:"results"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
events := []domain.Event{}
|
// events := []domain.Event{}
|
||||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||||
fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
// fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||||
return events
|
// return events
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, group := range data.Results {
|
// for _, group := range data.Results {
|
||||||
for _, ev := range group {
|
// for _, ev := range group {
|
||||||
if getString(ev["type"]) != "EV" {
|
// if getString(ev["type"]) != "EV" {
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
event := domain.Event{
|
// event := domain.Event{
|
||||||
ID: getString(ev["ID"]),
|
// ID: getString(ev["ID"]),
|
||||||
SportID: int32(sportID),
|
// SportID: int32(sportID),
|
||||||
MatchName: getString(ev["NA"]),
|
// MatchName: getString(ev["NA"]),
|
||||||
Score: getString(ev["SS"]),
|
// Score: getString(ev["SS"]),
|
||||||
MatchMinute: getInt(ev["TM"]),
|
// MatchMinute: getInt(ev["TM"]),
|
||||||
TimerStatus: getString(ev["TT"]),
|
// TimerStatus: getString(ev["TT"]),
|
||||||
HomeTeamID: getInt32(ev["HT"]),
|
// HomeTeamID: getInt32(ev["HT"]),
|
||||||
AwayTeamID: getInt32(ev["AT"]),
|
// AwayTeamID: getInt32(ev["AT"]),
|
||||||
HomeKitImage: getString(ev["K1"]),
|
// HomeKitImage: getString(ev["K1"]),
|
||||||
AwayKitImage: getString(ev["K2"]),
|
// AwayKitImage: getString(ev["K2"]),
|
||||||
LeagueName: getString(ev["CT"]),
|
// LeagueName: getString(ev["CT"]),
|
||||||
LeagueID: getInt32(ev["C2"]),
|
// LeagueID: getInt32(ev["C2"]),
|
||||||
LeagueCC: getString(ev["CB"]),
|
// LeagueCC: getString(ev["CB"]),
|
||||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
// StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||||
IsLive: true,
|
// IsLive: true,
|
||||||
Status: "live",
|
// Status: "live",
|
||||||
MatchPeriod: getInt(ev["MD"]),
|
// MatchPeriod: getInt(ev["MD"]),
|
||||||
AddedTime: getInt(ev["TA"]),
|
// AddedTime: getInt(ev["TA"]),
|
||||||
Source: source,
|
// Source: source,
|
||||||
}
|
// }
|
||||||
|
|
||||||
events = append(events, event)
|
// events = append(events, event)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return events
|
// return events
|
||||||
}
|
// }
|
||||||
|
|
||||||
func handleBetfairprematch(body []byte, sportID int, source string) []domain.Event {
|
// func handleBetfairprematch(body []byte, sportID int, source string) []domain.Event {
|
||||||
var data struct {
|
// var data struct {
|
||||||
Success int `json:"success"`
|
// Success int `json:"success"`
|
||||||
Results []map[string]interface{} `json:"results"`
|
// Results []map[string]interface{} `json:"results"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
events := []domain.Event{}
|
// events := []domain.Event{}
|
||||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||||
fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
// fmt.Printf("%s: Decode failed for sport_id=%d\nRaw: %s\n", source, sportID, string(body))
|
||||||
return events
|
// return events
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, ev := range data.Results {
|
// for _, ev := range data.Results {
|
||||||
homeRaw, _ := ev["home"].(map[string]interface{})
|
// homeRaw, _ := ev["home"].(map[string]interface{})
|
||||||
awayRaw, _ := ev["home"].(map[string]interface{})
|
// awayRaw, _ := ev["home"].(map[string]interface{})
|
||||||
|
|
||||||
event := domain.Event{
|
// event := domain.Event{
|
||||||
ID: getString(ev["id"]),
|
// ID: getString(ev["id"]),
|
||||||
SportID: int32(sportID),
|
// SportID: int32(sportID),
|
||||||
TimerStatus: getString(ev["time_status"]),
|
// TimerStatus: getString(ev["time_status"]),
|
||||||
HomeTeamID: getInt32(homeRaw["id"]),
|
// HomeTeamID: getInt32(homeRaw["id"]),
|
||||||
AwayTeamID: getInt32(awayRaw["id"]),
|
// AwayTeamID: getInt32(awayRaw["id"]),
|
||||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
// StartTime: time.Now().UTC().Format(time.RFC3339),
|
||||||
IsLive: true,
|
// IsLive: true,
|
||||||
Status: "live",
|
// Status: "live",
|
||||||
Source: source,
|
// Source: source,
|
||||||
}
|
// }
|
||||||
|
|
||||||
events = append(events, event)
|
// events = append(events, event)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return events
|
// return events
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
urls := []struct {
|
urls := []struct {
|
||||||
name string
|
name string
|
||||||
source string
|
source domain.EventSource
|
||||||
}{
|
}{
|
||||||
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", "bet365"},
|
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", domain.EVENT_SOURCE_BET365},
|
||||||
// {"https://api.b365api.com/v1/betfair/sb/upcoming?sport_id=%d&token=%s&page=%d", "betfair"},
|
// {"https://api.b365api.com/v1/betfair/sb/upcoming?sport_id=%d&token=%s&page=%d", "betfair"},
|
||||||
// {"https://api.b365api.com/v1/1xbet/upcoming?sport_id=%d&token=%s&page=%d", "1xbet"},
|
// {"https://api.b365api.com/v1/1xbet/upcoming?sport_id=%d&token=%s&page=%d", "1xbet"},
|
||||||
}
|
}
|
||||||
|
|
@ -205,83 +205,70 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_url, source string) {
|
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, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91}
|
||||||
// sportIDs := []int{1}
|
// sportIDs := []int{1}
|
||||||
// TODO: Add the league skipping again when we have dynamic leagues
|
|
||||||
|
|
||||||
// b, err := os.OpenFile("logs/skipped_leagues.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Printf("❌ Failed to open leagues file %v", err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
for sportIndex, sportID := range sportIDs {
|
for sportIndex, sportID := range sportIDs {
|
||||||
var totalPages int = 1
|
var totalPages int = 1
|
||||||
var page int = 0
|
var page int = 0
|
||||||
var limit int = 200
|
|
||||||
var count int = 0
|
var count int = 0
|
||||||
var skippedLeague []string
|
var skippedLeague []string
|
||||||
var totalEvents = 0
|
var totalEvents = 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("Skipped leagues", len(skippedLeague)),
|
||||||
|
)
|
||||||
for page <= totalPages {
|
for page <= totalPages {
|
||||||
page = page + 1
|
page = page + 1
|
||||||
url := fmt.Sprintf(source_url, sportID, s.token, page)
|
url := fmt.Sprintf(source_url, sportID, s.token, page)
|
||||||
log.Printf("📡 Fetching data from %s - sport %d (%d/%d), for event data page (%d/%d)",
|
log.Printf("📡 Fetching data from %s - sport %d (%d/%d), for event data page (%d/%d)",
|
||||||
source, sportID, sportIndex+1, len(sportIDs), page, totalPages)
|
source, sportID, sportIndex+1, len(sportIDs), page, totalPages)
|
||||||
|
|
||||||
|
eventLogger := logger.With(
|
||||||
|
zap.Int("page", page),
|
||||||
|
zap.Int("total_pages", totalPages),
|
||||||
|
)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
eventLogger.Error("Failed to fetch event data for page", zap.Error(err))
|
||||||
"Failed to fetch event data for page",
|
|
||||||
zap.String("source", source),
|
|
||||||
zap.Int("sport_id", sportID),
|
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, _ := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
var data domain.BetResult
|
|
||||||
|
if err != nil {
|
||||||
|
eventLogger.Error("Failed to read event response body", zap.Error(err))
|
||||||
|
continue
|
||||||
|
|
||||||
|
}
|
||||||
|
var data domain.B365UpcomingRes
|
||||||
|
|
||||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||||
s.mongoLogger.Error(
|
eventLogger.Error("Failed to parse event json data", zap.Error(err))
|
||||||
"Failed to parse event json data",
|
|
||||||
zap.String("source", source),
|
|
||||||
zap.Int("sport_id", sportID),
|
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ev := range data.Results {
|
for _, ev := range data.Results {
|
||||||
startUnix, err := strconv.ParseInt(ev.Time, 10, 64)
|
startUnix, err := strconv.ParseInt(ev.Time, 10, 64)
|
||||||
|
dataLogger := eventLogger.With(
|
||||||
|
zap.String("time", ev.Time),
|
||||||
|
zap.String("leagueID", ev.League.ID),
|
||||||
|
zap.String("leagueName", ev.League.Name),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
dataLogger.Error("Invalid time", zap.Error(err))
|
||||||
"Invalid time",
|
|
||||||
zap.String("time", ev.Time),
|
|
||||||
zap.String("source", source),
|
|
||||||
zap.Int("sport_id", sportID),
|
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
leagueID, err := strconv.ParseInt(ev.League.ID, 10, 64)
|
leagueID, err := strconv.ParseInt(ev.League.ID, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
dataLogger.Error("Invalid league id", zap.Error(err))
|
||||||
"Invalid league id",
|
|
||||||
zap.String("leagueID", ev.League.ID),
|
|
||||||
zap.String("source", source),
|
|
||||||
zap.Int("sport_id", sportID),
|
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,74 +276,67 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
||||||
// no this its fine to keep it here
|
// no this its fine to keep it here
|
||||||
// but change the league id to bet365 id later
|
// but change the league id to bet365 id later
|
||||||
//Automatically feature the league if its in the list
|
//Automatically feature the league if its in the list
|
||||||
err = s.store.SaveLeague(ctx, domain.League{
|
err = s.store.SaveLeague(ctx, domain.CreateLeague{
|
||||||
ID: leagueID,
|
ID: leagueID,
|
||||||
Name: ev.League.Name,
|
Name: ev.League.Name,
|
||||||
IsActive: true,
|
DefaultIsActive: true,
|
||||||
IsFeatured: slices.Contains(domain.FeaturedLeagues, leagueID),
|
DefaultIsFeatured: slices.Contains(domain.FeaturedLeagues, leagueID),
|
||||||
SportID: convertInt32(ev.SportID),
|
SportID: convertInt32(ev.SportID),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
dataLogger.Error("error while saving league", zap.Error(err))
|
||||||
"error while saving league",
|
|
||||||
zap.String("leagueID", ev.League.ID),
|
|
||||||
zap.String("leagueName", ev.League.Name),
|
|
||||||
zap.String("source", source),
|
|
||||||
zap.Int("sport_id", sportID),
|
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
|
||||||
zap.Error(err),
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if supported, err := s.store.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
|
// Since the system is multi-vendor now, no events are going to be skipped
|
||||||
s.mongoLogger.Warn(
|
// if supported, err := s.store.CheckLeagueSupport(ctx, leagueID); !supported || err != nil {
|
||||||
"Skipping league",
|
// dataLogger.Warn(
|
||||||
zap.String("league", ev.League.Name),
|
// "Skipping league",
|
||||||
zap.Bool("is_supported", supported),
|
// zap.Bool("is_supported", supported),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
skippedLeague = append(skippedLeague, ev.League.Name)
|
// skippedLeague = append(skippedLeague, ev.League.Name)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
event := domain.UpcomingEvent{
|
event := domain.CreateEvent{
|
||||||
ID: ev.ID,
|
ID: ev.ID,
|
||||||
SportID: convertInt32(ev.SportID),
|
SportID: convertInt32(ev.SportID),
|
||||||
MatchName: "",
|
MatchName: "",
|
||||||
HomeTeam: ev.Home.Name,
|
HomeTeam: ev.Home.Name,
|
||||||
AwayTeam: "", // handle nil safely
|
AwayTeam: "", // handle nil safely
|
||||||
HomeTeamID: convertInt32(ev.Home.ID),
|
HomeTeamID: convertInt64(ev.Home.ID),
|
||||||
AwayTeamID: 0,
|
AwayTeamID: 0,
|
||||||
HomeKitImage: "",
|
HomeTeamImage: "",
|
||||||
AwayKitImage: "",
|
AwayTeamImage: "",
|
||||||
LeagueID: convertInt32(ev.League.ID),
|
LeagueID: convertInt64(ev.League.ID),
|
||||||
LeagueName: ev.League.Name,
|
LeagueName: ev.League.Name,
|
||||||
LeagueCC: "",
|
StartTime: time.Unix(startUnix, 0).UTC(),
|
||||||
StartTime: time.Unix(startUnix, 0).UTC(),
|
Source: source,
|
||||||
Source: source,
|
IsLive: false,
|
||||||
|
Status: domain.STATUS_PENDING,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ev.Away != nil {
|
if ev.Away != nil {
|
||||||
|
dataLogger.Info("event away is empty")
|
||||||
event.AwayTeam = ev.Away.Name
|
event.AwayTeam = ev.Away.Name
|
||||||
event.AwayTeamID = convertInt32(ev.Away.ID)
|
event.AwayTeamID = convertInt64(ev.Away.ID)
|
||||||
event.MatchName = ev.Home.Name + " vs " + ev.Away.Name
|
event.MatchName = ev.Home.Name + " vs " + ev.Away.Name
|
||||||
}
|
}
|
||||||
|
ok, err := s.CheckAndInsertEventHistory(ctx, event)
|
||||||
|
|
||||||
err = s.store.SaveUpcomingEvent(ctx, event)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
dataLogger.Error("failed to check and insert event history", zap.Error(err))
|
||||||
"failed to save upcoming event",
|
}
|
||||||
zap.String("leagueID", ev.League.ID),
|
|
||||||
zap.String("leagueName", ev.League.Name),
|
if ok {
|
||||||
zap.String("source", source),
|
dataLogger.Info("event history has been recorded")
|
||||||
zap.Int("sport_id", sportID),
|
}
|
||||||
zap.Int("page", page),
|
|
||||||
zap.Int("total_pages", totalPages),
|
err = s.store.SaveEvent(ctx, event)
|
||||||
zap.Error(err),
|
if err != nil {
|
||||||
)
|
dataLogger.Error("failed to save upcoming event", zap.Error(err))
|
||||||
}
|
}
|
||||||
totalEvents += 1
|
totalEvents += 1
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +346,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
||||||
|
|
||||||
totalPages = data.Pager.Total / data.Pager.PerPage
|
totalPages = data.Pager.Total / data.Pager.PerPage
|
||||||
|
|
||||||
if count >= limit {
|
if count >= pageLimit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if page > totalPages {
|
if page > totalPages {
|
||||||
|
|
@ -376,7 +356,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
||||||
}
|
}
|
||||||
s.mongoLogger.Info(
|
s.mongoLogger.Info(
|
||||||
"Successfully fetched upcoming events",
|
"Successfully fetched upcoming events",
|
||||||
zap.String("source", source),
|
zap.String("source", string(source)),
|
||||||
zap.Int("totalEvents", totalEvents),
|
zap.Int("totalEvents", totalEvents),
|
||||||
zap.Int("sport_id", sportID),
|
zap.Int("sport_id", sportID),
|
||||||
zap.String("sport_name", domain.Sport(sportID).String()),
|
zap.String("sport_name", domain.Sport(sportID).String()),
|
||||||
|
|
@ -388,6 +368,49 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, source_ur
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) CheckAndInsertEventHistory(ctx context.Context, event domain.CreateEvent) (bool, error) {
|
||||||
|
isEventMonitored, err := s.store.IsEventMonitored(ctx, event.ID)
|
||||||
|
|
||||||
|
eventLogger := s.mongoLogger.With(
|
||||||
|
zap.String("eventID", event.ID),
|
||||||
|
zap.Int64("leagueID", event.LeagueID),
|
||||||
|
zap.String("leagueName", event.LeagueName),
|
||||||
|
zap.Int32("sport_id", event.SportID),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
eventLogger.Error("failed to get event is_monitored", zap.Error(err))
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isEventMonitored {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
oldEvent, err := s.GetUpcomingEventByID(ctx, event.ID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
eventLogger.Error("failed to get event by id", zap.Error(err))
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldEvent.Status != event.Status {
|
||||||
|
_, err := s.store.InsertEventHistory(ctx, domain.CreateEventHistory{
|
||||||
|
EventID: event.ID,
|
||||||
|
Status: string(event.Status),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
eventLogger.Error("failed to get event by id", zap.Error(err))
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -415,19 +438,25 @@ func convertInt32(num string) int32 {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
|
func convertInt64(num string) int64 {
|
||||||
|
if n, err := strconv.Atoi(num); err == nil {
|
||||||
|
return int64(n)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.BaseEvent, error) {
|
||||||
return s.store.GetAllUpcomingEvents(ctx)
|
return s.store.GetAllUpcomingEvents(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, error) {
|
func (s *service) GetExpiredUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, error) {
|
||||||
return s.store.GetExpiredUpcomingEvents(ctx, filter)
|
return s.store.GetExpiredUpcomingEvents(ctx, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.UpcomingEvent, int64, error) {
|
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) {
|
||||||
return s.store.GetPaginatedUpcomingEvents(ctx, filter)
|
return s.store.GetPaginatedUpcomingEvents(ctx, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
|
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.BaseEvent, error) {
|
||||||
return s.store.GetUpcomingEventByID(ctx, ID)
|
return s.store.GetUpcomingEventByID(ctx, ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,41 +467,20 @@ func (s *service) UpdateEventStatus(ctx context.Context, eventID string, status
|
||||||
return s.store.UpdateEventStatus(ctx, eventID, status)
|
return s.store.UpdateEventStatus(ctx, eventID, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) UpdateFeatured(ctx context.Context, eventID string, flagged bool) error {
|
func (s *service) IsEventMonitored(ctx context.Context, eventID string) (bool, error) {
|
||||||
return s.store.UpdateFeatured(ctx, eventID, flagged)
|
return s.store.IsEventMonitored(ctx, eventID)
|
||||||
|
}
|
||||||
|
func (s *service) UpdateEventMonitored(ctx context.Context, eventID string, IsMonitored bool) error {
|
||||||
|
return s.store.UpdateEventMonitored(ctx, eventID, IsMonitored)
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (s *service) GetAndStoreMatchResult(ctx context.Context, eventID string) error {
|
func (s *service) GetEventsWithSettings(ctx context.Context, companyID int64, filter domain.EventFilter) ([]domain.EventWithSettings, int64, error) {
|
||||||
// url := fmt.Sprintf("https://api.b365api.com/v1/bet365/result?token=%s&event_id=%s", s.token, eventID)
|
return s.store.GetEventsWithSettings(ctx, companyID, filter)
|
||||||
|
}
|
||||||
|
|
||||||
// resp, err := http.Get(url)
|
func (s *service) GetEventWithSettingByID(ctx context.Context, ID string, companyID int64) (domain.EventWithSettings, error) {
|
||||||
// if err != nil {
|
return s.store.GetEventWithSettingByID(ctx, ID, companyID)
|
||||||
// return fmt.Errorf("failed to fetch result: %w", err)
|
}
|
||||||
// }
|
func (s *service) UpdateEventSettings(ctx context.Context, event domain.CreateEventSettings) error {
|
||||||
// defer resp.Body.Close()
|
return s.store.UpdateEventSettings(ctx, event)
|
||||||
|
}
|
||||||
// body, _ := io.ReadAll(resp.Body)
|
|
||||||
|
|
||||||
// // Parse the API response
|
|
||||||
// var apiResp struct {
|
|
||||||
// Results []struct {
|
|
||||||
// ID string `json:"id"`
|
|
||||||
// Ss string `json:"ss"` // Full-time score
|
|
||||||
// Status string `json:"time_status"`
|
|
||||||
// } `json:"results"`
|
|
||||||
// }
|
|
||||||
|
|
||||||
// err = json.Unmarshal(body, &apiResp)
|
|
||||||
// if err != nil || len(apiResp.Results) == 0 {
|
|
||||||
// return fmt.Errorf("invalid response or no results found")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// result := apiResp.Results[0]
|
|
||||||
|
|
||||||
// err = s.store.UpdateFinalScore(ctx, result.ID, result.Ss, result.Status)
|
|
||||||
// if err != nil {
|
|
||||||
// return fmt.Errorf("failed to update final score in database: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
SaveLeague(ctx context.Context, l domain.League) error
|
SaveLeague(ctx context.Context, league domain.CreateLeague) error
|
||||||
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error)
|
SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error
|
||||||
GetFeaturedLeagues(ctx context.Context) ([]domain.League, error)
|
GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error)
|
||||||
SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error
|
GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, 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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,20 +17,24 @@ func New(store *repository.Store) Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) SaveLeague(ctx context.Context, l domain.League) error {
|
func (s *service) SaveLeague(ctx context.Context, league domain.CreateLeague) error {
|
||||||
return s.store.SaveLeague(ctx, l)
|
return s.store.SaveLeague(ctx, league)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.League, error) {
|
func (s *service) SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error {
|
||||||
|
return s.store.SaveLeagueSettings(ctx, leagueSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) {
|
||||||
return s.store.GetAllLeagues(ctx, filter)
|
return s.store.GetAllLeagues(ctx, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetFeaturedLeagues(ctx context.Context) ([]domain.League, error) {
|
func (s *service) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, error) {
|
||||||
return s.store.GetFeaturedLeagues(ctx)
|
return s.store.GetAllLeaguesByCompany(ctx, companyID, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) SetLeagueActive(ctx context.Context, leagueId int64, isActive bool) error {
|
func (s *service) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) {
|
||||||
return s.store.SetLeagueActive(ctx, leagueId, isActive)
|
return s.store.CheckLeagueSupport(ctx, leagueID, companyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error {
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,24 @@ var (
|
||||||
ErrSMSProviderNotFound = errors.New("SMS Provider Not Found")
|
ErrSMSProviderNotFound = errors.New("SMS Provider Not Found")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) SendSMS(ctx context.Context, receiverPhone, message string) error {
|
// If the company id is valid, it is a company based notification else its a global notification (by the super admin)
|
||||||
|
func (s *Service) SendSMS(ctx context.Context, receiverPhone, message string, companyID domain.ValidInt64) error {
|
||||||
|
|
||||||
settingsList, err := s.settingSvc.GetSettingList(ctx)
|
var settingsList domain.SettingList
|
||||||
|
var err error
|
||||||
|
|
||||||
if err != nil {
|
if companyID.Valid {
|
||||||
return err
|
settingsList, err = s.settingSvc.GetOverrideSettingsList(ctx, companyID.Value)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: Send a log about the error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
settingsList, err = s.settingSvc.GetGlobalSettingList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: Send a log about the error
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch settingsList.SMSProvider {
|
switch settingsList.SMSProvider {
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ func (s *Service) SendNotificationSMS(ctx context.Context, recipientID int64, me
|
||||||
if user.PhoneNumber == "" {
|
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)
|
err = s.messengerSvc.SendSMS(ctx, user.PhoneNumber, message, user.CompanyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
internal/services/odds/custom_odds.go
Normal file
29
internal/services/odds/custom_odds.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package odds
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "context"
|
||||||
|
|
||||||
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func (s *ServiceImpl) InsertCustomOdds(ctx context.Context, odd domain.CreateCustomOdd) (domain.CustomOdd, error) {
|
||||||
|
// return s.store.InsertCustomOdds(ctx, odd)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) GetAllCustomOdds(ctx context.Context, filter domain.CustomOddFilter) ([]domain.CustomOdd, error){
|
||||||
|
// return s.store.GetAllCustomOdds(ctx, filter)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) GetCustomOddByID(ctx context.Context, id int64) (domain.CustomOdd, error){
|
||||||
|
// return s.store.GetCustomOddByID(ctx, id)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) GetCustomOddByOddID(ctx context.Context, oddId int64, companyID int64) (domain.CustomOdd, error){
|
||||||
|
// return s.store.GetCustomOddByOddID(ctx, oddId, companyID)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) DeleteCustomOddByID(ctx context.Context, id int64) error{
|
||||||
|
// return s.store.DeleteCustomOddByID(ctx, id)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) DeleteCustomOddsByOddID(ctx context.Context, oddId int64, companyID int64) error{
|
||||||
|
// return s.store.DeleteCustomOddsByOddID(ctx, oddId, companyID)
|
||||||
|
// }
|
||||||
|
// func (s *ServiceImpl) DeleteCustomOddByEventID(ctx context.Context, eventID string) error{
|
||||||
|
// return s.store.DeleteCustomOddByEventID(ctx, eventID)
|
||||||
|
// }
|
||||||
28
internal/services/odds/disabled_odd.go
Normal file
28
internal/services/odds/disabled_odd.go
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
package odds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *ServiceImpl) InsertDisabledOdd(ctx context.Context, odd domain.CreateDisabledOdd) (domain.DisabledOdd, error) {
|
||||||
|
return s.store.InsertDisabledOdd(ctx, odd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetAllDisabledOdds(ctx context.Context) ([]domain.DisabledOdd, error) {
|
||||||
|
return s.store.GetAllDisabledOdds(ctx)
|
||||||
|
}
|
||||||
|
func (s *ServiceImpl) GetDisabledOddByRawOddID(ctx context.Context, rawOddID int64) (domain.DisabledOdd, error) {
|
||||||
|
return s.store.GetDisabledOddByRawOddID(ctx, rawOddID)
|
||||||
|
}
|
||||||
|
func (s *ServiceImpl) GetDisabledOddByID(ctx context.Context, id int64) (domain.DisabledOdd, error) {
|
||||||
|
return s.store.GetDisabledOddByID(ctx, id)
|
||||||
|
}
|
||||||
|
func (s *ServiceImpl) DeleteDisabledOddsByID(ctx context.Context, id int64) error {
|
||||||
|
return s.store.DeleteDisabledOddsByID(ctx, id)
|
||||||
|
}
|
||||||
|
func (s *ServiceImpl) DeleteDisabledOddsByRawOddID(ctx context.Context, id int64) error {
|
||||||
|
return s.store.DeleteDisabledOddsByRawOddID(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
15
internal/services/odds/odds_history.go
Normal file
15
internal/services/odds/odds_history.go
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package odds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetAllOddHistory(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||||
|
return s.store.GetAllOddHistory(ctx, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetInitialOddPerDay(ctx context.Context, filter domain.OddHistoryFilter) ([]domain.OddHistory, error) {
|
||||||
|
return s.store.GetInitialOddPerDay(ctx, filter)
|
||||||
|
}
|
||||||
|
|
@ -11,10 +11,32 @@ type Service interface {
|
||||||
FetchNonLiveOdds(ctx context.Context) error
|
FetchNonLiveOdds(ctx context.Context) error
|
||||||
FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error)
|
FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error)
|
||||||
ParseOddSections(ctx context.Context, res json.RawMessage, sportID int64) (domain.ParseOddSectionsRes, error)
|
ParseOddSections(ctx context.Context, res json.RawMessage, sportID int64) (domain.ParseOddSectionsRes, error)
|
||||||
GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error)
|
GetPrematchOdds(ctx context.Context, eventID string) ([]domain.OddMarket, error)
|
||||||
GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error)
|
GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.OddMarket, error)
|
||||||
GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.Odd, error)
|
GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit domain.ValidInt64, offset domain.ValidInt64) ([]domain.OddMarket, error)
|
||||||
GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error)
|
GetALLPrematchOdds(ctx context.Context) ([]domain.OddMarket, error)
|
||||||
GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.RawOddsByMarketID, 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
|
||||||
|
|
||||||
|
// Odd History
|
||||||
|
InsertOddHistory(ctx context.Context, odd domain.CreateOddHistory) (domain.OddHistory, error)
|
||||||
|
GetAllOddHistory(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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,24 @@ 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/repository"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceImpl struct {
|
type ServiceImpl struct {
|
||||||
store *repository.Store
|
store *repository.Store
|
||||||
config *config.Config
|
config *config.Config
|
||||||
|
eventSvc event.Service
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
mongoLogger *zap.Logger
|
mongoLogger *zap.Logger
|
||||||
client *http.Client
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(store *repository.Store, cfg *config.Config, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
|
func New(store *repository.Store, cfg *config.Config, eventSvc event.Service, logger *slog.Logger, mongoLogger *zap.Logger) *ServiceImpl {
|
||||||
return &ServiceImpl{
|
return &ServiceImpl{
|
||||||
store: store,
|
store: store,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
|
eventSvc: eventSvc,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
mongoLogger: mongoLogger,
|
mongoLogger: mongoLogger,
|
||||||
client: &http.Client{Timeout: 10 * time.Second},
|
client: &http.Client{Timeout: 10 * time.Second},
|
||||||
|
|
@ -76,7 +79,7 @@ func (s *ServiceImpl) FetchNonLiveOdds(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
||||||
eventIDs, err := s.store.GetAllUpcomingEvents(ctx)
|
eventIDs, err := s.eventSvc.GetAllUpcomingEvents(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
s.mongoLogger.Error(
|
||||||
"Failed to fetch upcoming event IDs",
|
"Failed to fetch upcoming event IDs",
|
||||||
|
|
@ -161,115 +164,117 @@ func (s *ServiceImpl) fetchBet365Odds(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
// func (s *ServiceImpl) fetchBwinOdds(ctx context.Context) error {
|
||||||
// getting odds for a specific event is not possible for bwin, most specific we can get is fetch odds on a single sport
|
// // getting odds for a specific event is not possible for bwin, most specific we can get is fetch odds on a single sport
|
||||||
// so instead of having event and odds fetched separetly event will also be fetched along with the odds
|
// // so instead of having event and odds fetched separetly event will also be fetched along with the odds
|
||||||
sportIds := []int{4, 12, 7}
|
// sportIds := []int{4, 12, 7}
|
||||||
for _, sportId := range sportIds {
|
// for _, sportId := range sportIds {
|
||||||
url := fmt.Sprintf("https://api.b365api.com/v1/bwin/prematch?sport_id=%d&token=%s", sportId, s.config.Bet365Token)
|
// url := fmt.Sprintf("https://api.b365api.com/v1/bwin/prematch?sport_id=%d&token=%s", sportId, s.config.Bet365Token)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
// req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
"Failed to create request for sportId",
|
// "Failed to create request for sportId",
|
||||||
zap.Int("sportID", sportId),
|
// zap.Int("sportID", sportId),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
resp, err := s.client.Do(req)
|
// resp, err := s.client.Do(req)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
"Failed to fetch request for sportId",
|
// "Failed to fetch request for sportId",
|
||||||
zap.Int("sportID", sportId),
|
// zap.Int("sportID", sportId),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
defer resp.Body.Close()
|
// defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
// body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
"Failed to read response body for sportId",
|
// "Failed to read response body for sportId",
|
||||||
zap.Int("sportID", sportId),
|
// zap.Int("sportID", sportId),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
var data struct {
|
// var data struct {
|
||||||
Success int `json:"success"`
|
// Success int `json:"success"`
|
||||||
Results []map[string]interface{} `json:"results"`
|
// Results []map[string]interface{} `json:"results"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
// if err := json.Unmarshal(body, &data); err != nil || data.Success != 1 {
|
||||||
fmt.Printf("Decode failed for sport_id=%d\nRaw: %s\n", sportId, string(body))
|
// fmt.Printf("Decode failed for sport_id=%d\nRaw: %s\n", sportId, string(body))
|
||||||
s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
"Failed to decode BWin response body",
|
// "Failed to decode BWin response body",
|
||||||
zap.Int("sportID", sportId),
|
// zap.Int("sportID", sportId),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, res := range data.Results {
|
// for _, res := range data.Results {
|
||||||
if getInt(res["Id"]) == -1 {
|
// if getInt(res["Id"]) == -1 {
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
event := domain.Event{
|
// event := domain.CreateEvent{
|
||||||
ID: strconv.Itoa(getInt(res["Id"])),
|
// ID: strconv.Itoa(getInt(res["Id"])),
|
||||||
SportID: int32(getInt(res["SportId"])),
|
// SportID: int32(getInt(res["SportId"])),
|
||||||
LeagueID: int32(getInt(res["LeagueId"])),
|
// LeagueID: int64(getInt(res["LeagueId"])),
|
||||||
LeagueName: getString(res["Leaguename"]),
|
// LeagueName: getString(res["Leaguename"]),
|
||||||
HomeTeam: getString(res["HomeTeam"]),
|
// HomeTeam: getString(res["HomeTeam"]),
|
||||||
HomeTeamID: int32(getInt(res["HomeTeamId"])),
|
// HomeTeamID: int64(getInt(res["HomeTeamId"])),
|
||||||
AwayTeam: getString(res["AwayTeam"]),
|
// AwayTeam: getString(res["AwayTeam"]),
|
||||||
AwayTeamID: int32(getInt(res["AwayTeamId"])),
|
// AwayTeamID: int64(getInt(res["AwayTeamId"])),
|
||||||
StartTime: time.Now().UTC().Format(time.RFC3339),
|
// StartTime: time.Now().UTC(),
|
||||||
TimerStatus: "1",
|
// IsLive: true,
|
||||||
IsLive: true,
|
// Status: domain.STATUS_IN_PLAY,
|
||||||
Status: "live",
|
// Source: domain.EVENT_SOURCE_BWIN,
|
||||||
Source: "bwin",
|
// MatchName: "",
|
||||||
}
|
// HomeTeamImage: "",
|
||||||
|
// AwayTeamImage: "",
|
||||||
|
// }
|
||||||
|
|
||||||
if err := s.store.SaveEvent(ctx, event); err != nil {
|
// if err := s.store.SaveEvent(ctx, event); err != nil {
|
||||||
fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
// fmt.Printf("Could not store live event [id=%s]: %v\n", event.ID, err)
|
||||||
s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
"Could not store live event",
|
// "Could not store live event",
|
||||||
zap.Int("sportID", sportId),
|
// zap.Int("sportID", sportId),
|
||||||
zap.String("eventID", event.ID),
|
// zap.String("eventID", event.ID),
|
||||||
zap.Error(err),
|
// zap.Error(err),
|
||||||
)
|
// )
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, market := range []string{"Markets, optionMarkets"} {
|
// for _, market := range []string{"Markets, optionMarkets"} {
|
||||||
for _, m := range getMapArray(res[market]) {
|
// for _, m := range getMapArray(res[market]) {
|
||||||
name := getMap(m["name"])
|
// name := getMap(m["name"])
|
||||||
marketName := getString(name["value"])
|
// marketName := getString(name["value"])
|
||||||
|
|
||||||
market := domain.Market{
|
// market := domain.CreateOddMarket{
|
||||||
EventID: event.ID,
|
// EventID: event.ID,
|
||||||
MarketID: getString(m["id"]),
|
// MarketID: getString(m["id"]),
|
||||||
MarketCategory: getString(m["category"]),
|
// MarketCategory: getString(m["category"]),
|
||||||
MarketName: marketName,
|
// MarketName: marketName,
|
||||||
Source: "bwin",
|
|
||||||
}
|
|
||||||
|
|
||||||
results := getMapArray(m["results"])
|
// }
|
||||||
market.Odds = results
|
|
||||||
|
|
||||||
s.store.SaveNonLiveMarket(ctx, market)
|
// results := getMapArray(m["results"])
|
||||||
|
// market.Odds = results
|
||||||
|
|
||||||
}
|
// s.store.SaveOddMarket(ctx, market)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
// }
|
||||||
return nil
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error) {
|
func (s *ServiceImpl) FetchNonLiveOddsByEventID(ctx context.Context, eventIDStr string) (domain.BaseNonLiveOddResponse, error) {
|
||||||
|
|
||||||
|
|
@ -542,7 +547,7 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the market id is a string
|
// Check if the market id is a string
|
||||||
marketIDint := market.ID.Int64
|
marketIDint := market.ID.Value
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// s.mongoLogger.Error(
|
// s.mongoLogger.Error(
|
||||||
// "Invalid market id",
|
// "Invalid market id",
|
||||||
|
|
@ -576,9 +581,8 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
marketRecord := domain.Market{
|
marketRecord := domain.CreateOddMarket{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
FI: fi,
|
|
||||||
MarketCategory: sectionName,
|
MarketCategory: sectionName,
|
||||||
MarketType: marketType,
|
MarketType: marketType,
|
||||||
MarketName: market.Name,
|
MarketName: market.Name,
|
||||||
|
|
@ -586,10 +590,20 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
||||||
UpdatedAt: updatedAt,
|
UpdatedAt: updatedAt,
|
||||||
Odds: marketOdds,
|
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
|
||||||
Source: "bet365",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.store.SaveNonLiveMarket(ctx, marketRecord)
|
if err := s.CheckAndInsertOddHistory(ctx, marketRecord); err != nil {
|
||||||
|
s.mongoLogger.Error(
|
||||||
|
"failed to check and insert odd history",
|
||||||
|
zap.String("market_id", marketIDstr),
|
||||||
|
zap.String("market_name", market.Name),
|
||||||
|
zap.String("eventID", eventID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.store.SaveOddMarket(ctx, marketRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mongoLogger.Error(
|
s.mongoLogger.Error(
|
||||||
"failed to save market",
|
"failed to save market",
|
||||||
|
|
@ -598,7 +612,7 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
||||||
zap.String("eventID", eventID),
|
zap.String("eventID", eventID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
errs = append(errs, fmt.Errorf("market %s: %w", market.ID, err))
|
errs = append(errs, fmt.Errorf("market %v: %w", market.ID, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -609,29 +623,111 @@ func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error) {
|
func (s *ServiceImpl) CheckAndInsertOddHistory(ctx context.Context, market domain.CreateOddMarket) error {
|
||||||
return s.store.GetPrematchOdds(ctx, eventID)
|
isEventMonitored, err := s.eventSvc.IsEventMonitored(ctx, market.EventID)
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ServiceImpl) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error) {
|
marketLogger := s.mongoLogger.With(
|
||||||
return s.store.GetALLPrematchOdds(ctx)
|
zap.String("market_id", market.MarketID),
|
||||||
}
|
zap.String("market_name", market.MarketName),
|
||||||
|
zap.String("eventID", market.EventID),
|
||||||
func (s *ServiceImpl) GetRawOddsByMarketID(ctx context.Context, marketID string, upcomingID string) (domain.RawOddsByMarketID, error) {
|
)
|
||||||
rows, err := s.store.GetRawOddsByMarketID(ctx, marketID, upcomingID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.RawOddsByMarketID{}, err
|
marketLogger.Error("failed to get is_monitored", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isEventMonitored {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
oldOdds, err := s.store.GetOddsByMarketID(ctx, market.MarketID, market.EventID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
marketLogger.Error("failed to get raw odds by market id", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(oldOdds.RawOdds) != len(market.Odds) {
|
||||||
|
marketLogger.Error("new odds data does not match old odds data", zap.Error(err))
|
||||||
|
return fmt.Errorf("new odds data does not match old odds data")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldRawOdds, err := convertRawMessage(oldOdds.RawOdds)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
marketLogger.Error("failed to convert raw odds to map", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, oddData := range market.Odds {
|
||||||
|
newRawOddID := getInt(oddData["id"])
|
||||||
|
newOddsVal := getFloat(oddData["odds"])
|
||||||
|
isFound := false
|
||||||
|
for _, oldOddData := range oldRawOdds {
|
||||||
|
oldRawOddID := getInt(oldOddData["id"])
|
||||||
|
oldOddsVal := getFloat(oldOddData["odds"])
|
||||||
|
if newRawOddID == oldRawOddID {
|
||||||
|
if newOddsVal != oldOddsVal {
|
||||||
|
_, err := s.store.InsertOddHistory(ctx, domain.CreateOddHistory{
|
||||||
|
OddID: oldOdds.ID,
|
||||||
|
MarketID: market.MarketID,
|
||||||
|
RawOddID: int64(newRawOddID),
|
||||||
|
EventID: market.EventID,
|
||||||
|
OddValue: newOddsVal,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
s.mongoLogger.Error(
|
||||||
|
"failed to insert odd history",
|
||||||
|
zap.String("market_id", market.MarketID),
|
||||||
|
zap.String("market_name", market.MarketName),
|
||||||
|
zap.String("eventID", market.EventID),
|
||||||
|
zap.Int64("odd_id", oldOdds.ID),
|
||||||
|
zap.Int("raw_odd_id", newRawOddID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !isFound {
|
||||||
|
fmt.Printf("raw odd id %d not found", newRawOddID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetAllOdds(ctx context.Context, filter domain.OddMarketFilter) ([]domain.OddMarket, error) {
|
||||||
|
return s.store.GetAllOdds(ctx, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetAllOddsWithSettings(ctx context.Context, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||||
|
return s.store.GetAllOddsWithSettings(ctx, companyID, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) GetOddsByMarketID(ctx context.Context, marketID string, eventID string) (domain.OddMarket, error) {
|
||||||
|
rows, err := s.store.GetOddsByMarketID(ctx, marketID, eventID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.OddMarket{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
func (s *ServiceImpl) GetOddsWithSettingsByMarketID(ctx context.Context, marketID string, eventID string, companyID int64) (domain.OddMarketWithSettings, error) {
|
||||||
|
rows, err := s.store.GetOddsWithSettingsByMarketID(ctx, marketID, eventID, companyID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.OddMarketWithSettings{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows, nil
|
return rows, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string) ([]domain.Odd, error) {
|
func (s *ServiceImpl) GetOddsByEventID(ctx context.Context, upcomingID string, filter domain.OddMarketWithEventFilter) ([]domain.OddMarket, error) {
|
||||||
return s.store.GetPrematchOddsByUpcomingID(ctx, upcomingID)
|
return s.store.GetOddsByEventID(ctx, upcomingID, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) GetPaginatedPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit, offset domain.ValidInt64) ([]domain.Odd, error) {
|
func (s *ServiceImpl) GetOddsWithSettingsByEventID(ctx context.Context, upcomingID string, companyID int64, filter domain.OddMarketFilter) ([]domain.OddMarketWithSettings, error) {
|
||||||
return s.store.GetPaginatedPrematchOddsByUpcomingID(ctx, upcomingID, limit, offset)
|
return s.store.GetOddsWithSettingsByEventID(ctx, upcomingID, companyID, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
func (s *ServiceImpl) DeleteOddsForEvent(ctx context.Context, eventID string) error {
|
||||||
|
|
@ -651,6 +747,12 @@ func getInt(v interface{}) int {
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
func getFloat(v interface{}) float64 {
|
||||||
|
if n, ok := v.(float64); ok {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func getMap(v interface{}) map[string]interface{} {
|
func getMap(v interface{}) map[string]interface{} {
|
||||||
if m, ok := v.(map[string]interface{}); ok {
|
if m, ok := v.(map[string]interface{}); ok {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
type ReferralStore interface {
|
type ReferralStore interface {
|
||||||
GenerateReferralCode() (string, error)
|
GenerateReferralCode() (string, error)
|
||||||
CreateReferral(ctx context.Context, userID int64) error
|
CreateReferral(ctx context.Context, userID int64) error
|
||||||
ProcessReferral(ctx context.Context, referredID, referralCode string) error
|
ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error
|
||||||
ProcessDepositBonus(ctx context.Context, userID string, amount float64) error
|
ProcessDepositBonus(ctx context.Context, userID string, amount float64) error
|
||||||
GetReferralStats(ctx context.Context, userID string) (*domain.ReferralStats, error)
|
GetReferralStats(ctx context.Context, userID string) (*domain.ReferralStats, error)
|
||||||
CreateReferralSettings(ctx context.Context, req domain.ReferralSettingsReq) error
|
CreateReferralSettings(ctx context.Context, req domain.ReferralSettingsReq) error
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ func (s *Service) CreateReferral(ctx context.Context, userID int64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCode string) error {
|
func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCode string, companyID int64) error {
|
||||||
s.logger.Info("Processing referral", "referredPhone", referredPhone, "referralCode", referralCode)
|
s.logger.Info("Processing referral", "referredPhone", referredPhone, "referralCode", referralCode)
|
||||||
|
|
||||||
referral, err := s.repo.GetReferralByCode(ctx, referralCode)
|
referral, err := s.repo.GetReferralByCode(ctx, referralCode)
|
||||||
|
|
@ -121,7 +121,10 @@ func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCo
|
||||||
return ErrInvalidReferral
|
return ErrInvalidReferral
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := s.store.GetUserByPhone(ctx, referredPhone)
|
user, err := s.store.GetUserByPhone(ctx, referredPhone, domain.ValidInt64{
|
||||||
|
Value: companyID,
|
||||||
|
Valid: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, domain.ErrUserNotFound) {
|
if errors.Is(err, domain.ErrUserNotFound) {
|
||||||
s.logger.Warn("User not found for referral", "referredPhone", referredPhone)
|
s.logger.Warn("User not found for referral", "referredPhone", referredPhone)
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,16 @@ package result
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResultService interface {
|
type ResultService interface {
|
||||||
FetchAndProcessResults(ctx context.Context) error
|
FetchAndProcessResults(ctx context.Context) error
|
||||||
FetchAndStoreResult(ctx context.Context, eventID string) error
|
FetchAndStoreResult(ctx context.Context, eventID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResultLogStore interface {
|
||||||
|
CreateResultLog(ctx context.Context, result domain.CreateResultLog) (domain.ResultLog, error)
|
||||||
|
GetAllResultLog(ctx context.Context, filter domain.ResultFilter) ([]domain.ResultLog, error)
|
||||||
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user