company management

This commit is contained in:
Samuel Tariku 2025-04-23 03:44:17 +03:00
parent 991199c3dc
commit 8c536a6d2f
45 changed files with 1681 additions and 362 deletions

View File

@ -16,11 +16,12 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
httpserver "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server" httpserver "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server"
@ -67,22 +68,23 @@ func main() {
eventSvc := event.New(cfg.Bet365Token, store) eventSvc := event.New(cfg.Bet365Token, store)
oddsSvc := odds.New(cfg.Bet365Token, store) oddsSvc := odds.New(cfg.Bet365Token, store)
ticketSvc := ticket.NewService(store) ticketSvc := ticket.NewService(store)
betSvc := bet.NewService(store) betSvc := bet.NewService(store)
walletSvc := wallet.NewService(store, store) walletSvc := wallet.NewService(store, store)
transactionSvc := transaction.NewService(store) transactionSvc := transaction.NewService(store)
branchSvc := branch.NewService(store) branchSvc := branch.NewService(store)
companySvc := company.NewService(store)
notificationRepo := repository.NewNotificationRepository(store) notificationRepo := repository.NewNotificationRepository(store)
notificationSvc := notificationservice.New(notificationRepo, logger, cfg) notificationSvc := notificationservice.New(notificationRepo, logger, cfg)
httpserver.StartDataFetchingCrons(eventSvc, oddsSvc) httpserver.StartDataFetchingCrons(eventSvc, oddsSvc)
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{ app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
JwtAccessKey: cfg.JwtKey, JwtAccessKey: cfg.JwtKey,
JwtAccessExpiry: cfg.AccessExpiry, JwtAccessExpiry: cfg.AccessExpiry,
}, userSvc, ticketSvc, betSvc, walletSvc, transactionSvc, branchSvc, notificationSvc, oddsSvc, eventSvc) }, userSvc,
ticketSvc, betSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc)
logger.Info("Starting server", "port", cfg.Port) logger.Info("Starting server", "port", cfg.Port)

View File

@ -1,22 +1,18 @@
-- Drop tables that depend on service_type_setting -- Drop tables that depend on service_type_setting
DROP TABLE IF EXISTS service_type_setting; DROP TABLE IF EXISTS service_type_setting;
-- Drop product-related tables and types -- Drop product-related tables and types
DROP TABLE IF EXISTS product; DROP TABLE IF EXISTS product;
DROP TYPE IF EXISTS tier_group; DROP TYPE IF EXISTS tier_group;
-- Drop onboarding-related tables and types -- Drop onboarding-related tables and types
DROP TABLE IF EXISTS verification_key; DROP TABLE IF EXISTS verification_key;
DROP TABLE IF EXISTS onboarding_user; DROP TABLE IF EXISTS onboarding_user;
DROP TYPE IF EXISTS verification_status; DROP TYPE IF EXISTS verification_status;
DROP TYPE IF EXISTS onboarding_status; DROP TYPE IF EXISTS onboarding_status;
-- Drop staff-related tables and types -- Drop staff-related tables and types
DROP TABLE IF EXISTS staff_session; DROP TABLE IF EXISTS staff_session;
DROP TABLE IF EXISTS user_agent; DROP TABLE IF EXISTS user_agent;
DROP TABLE IF EXISTS staff; DROP TABLE IF EXISTS staff;
DROP TYPE IF EXISTS password_status; DROP TYPE IF EXISTS password_status;
-- Drop mobile app-related tables and types -- Drop mobile app-related tables and types
DROP TABLE IF EXISTS user_devices; DROP TABLE IF EXISTS user_devices;
DROP TABLE IF EXISTS user_session; DROP TABLE IF EXISTS user_session;
@ -25,17 +21,14 @@ DROP TABLE IF EXISTS users;
DROP TYPE IF EXISTS device_type; DROP TYPE IF EXISTS device_type;
DROP TYPE IF EXISTS registeration_type; DROP TYPE IF EXISTS registeration_type;
DROP TYPE IF EXISTS customer_group; DROP TYPE IF EXISTS customer_group;
-- Drop linked accounts and beneficiary tables and types -- Drop linked accounts and beneficiary tables and types
DROP TABLE IF EXISTS beneficiary; DROP TABLE IF EXISTS beneficiary;
DROP TYPE IF EXISTS fund_destination; DROP TYPE IF EXISTS fund_destination;
-- Drop maker checker-related tables and types -- Drop maker checker-related tables and types
DROP TABLE IF EXISTS workflow; DROP TABLE IF EXISTS workflow;
DROP TYPE IF EXISTS approval_status; DROP TYPE IF EXISTS approval_status;
DROP TYPE IF EXISTS action_type; DROP TYPE IF EXISTS action_type;
DROP TYPE IF EXISTS context_type; DROP TYPE IF EXISTS context_type;
-- Drop authorization-related tables and types -- Drop authorization-related tables and types
DROP TRIGGER IF EXISTS enforce_unique_array ON policy; DROP TRIGGER IF EXISTS enforce_unique_array ON policy;
DROP FUNCTION IF EXISTS check_unique_array; DROP FUNCTION IF EXISTS check_unique_array;
@ -43,11 +36,9 @@ DROP TABLE IF EXISTS policy;
DROP TABLE IF EXISTS roles; DROP TABLE IF EXISTS roles;
DROP TYPE IF EXISTS policy_action; DROP TYPE IF EXISTS policy_action;
DROP TYPE IF EXISTS policy_object; DROP TYPE IF EXISTS policy_object;
-- Drop bank-related tables and types -- Drop bank-related tables and types
DROP TABLE IF EXISTS bank; DROP TABLE IF EXISTS bank;
DROP TABLE IF EXISTS flagged_users; DROP TABLE IF EXISTS flagged_users;
-- Drop transaction-related tables and types -- Drop transaction-related tables and types
DROP TABLE IF EXISTS transaction_daily; DROP TABLE IF EXISTS transaction_daily;
DROP TABLE IF EXISTS system_limits; DROP TABLE IF EXISTS system_limits;
@ -57,22 +48,18 @@ DROP TYPE IF EXISTS service_type;
DROP TYPE IF EXISTS channel; DROP TYPE IF EXISTS channel;
DROP TYPE IF EXISTS transaction_category; DROP TYPE IF EXISTS transaction_category;
DROP TYPE IF EXISTS registration_type; DROP TYPE IF EXISTS registration_type;
-- Drop branches and related tables -- Drop branches and related tables
DROP TABLE IF EXISTS branches; DROP TABLE IF EXISTS branches;
DROP TABLE IF EXISTS cities; DROP TABLE IF EXISTS cities;
DROP TABLE IF EXISTS districts; DROP TABLE IF EXISTS districts;
DROP TABLE IF EXISTS regions; DROP TABLE IF EXISTS regions;
-- Drop activity logs -- Drop activity logs
DROP TABLE IF EXISTS activity; DROP TABLE IF EXISTS activity;
-- Drop ussd account and related enums -- Drop ussd account and related enums
DROP TABLE IF EXISTS ussd_account; DROP TABLE IF EXISTS ussd_account;
DROP TYPE IF EXISTS ua_pin_status; DROP TYPE IF EXISTS ua_pin_status;
DROP TYPE IF EXISTS ua_status; DROP TYPE IF EXISTS ua_status;
DROP TYPE IF EXISTS ua_registaration_type; DROP TYPE IF EXISTS ua_registaration_type;
-- Drop FortuneBet -- Drop FortuneBet
DROP TABLE IF EXISTS tickets; DROP TABLE IF EXISTS tickets;
DROP TABLE IF EXISTS ticket_outcomes; DROP TABLE IF EXISTS ticket_outcomes;
@ -83,13 +70,9 @@ DROP TABLE IF EXISTS customer_wallets;
DROP TABLE IF EXISTS wallet_transfer; DROP TABLE IF EXISTS wallet_transfer;
DROP TABLE IF EXISTS transactions; DROP TABLE IF EXISTS transactions;
DROP TABLE IF EXISTS branches; DROP TABLE IF EXISTS branches;
DROP TABLE IF EXISTS companies;
DROP TABLE IF EXISTS supported_operations; DROP TABLE IF EXISTS supported_operations;
DROP TABLE IF EXISTS refresh_tokens; DROP TABLE IF EXISTS refresh_tokens;
DROP TABLE IF EXISTS otps; DROP TABLE IF EXISTS otps;
DROP TABLE IF EXISTS odds; DROP TABLE IF EXISTS odds;
DROP TABLE IF EXISTS events; DROP TABLE IF EXISTS events;

View File

@ -78,6 +78,7 @@ CREATE TABLE IF NOT EXISTS bet_outcomes (
odd_name VARCHAR(255) NOT NULL, odd_name VARCHAR(255) NOT NULL,
odd_header VARCHAR(255) NOT NULL, odd_header VARCHAR(255) NOT NULL,
odd_handicap VARCHAR(255) NOT NULL, odd_handicap VARCHAR(255) NOT NULL,
status INT NOT NULL DEFAULT 0,
expires TIMESTAMP NOT NULL expires TIMESTAMP NOT NULL
); );
CREATE TABLE IF NOT EXISTS ticket_outcomes ( CREATE TABLE IF NOT EXISTS ticket_outcomes (
@ -93,6 +94,7 @@ CREATE TABLE IF NOT EXISTS ticket_outcomes (
odd_name VARCHAR(255) NOT NULL, odd_name VARCHAR(255) NOT NULL,
odd_header VARCHAR(255) NOT NULL, odd_header VARCHAR(255) NOT NULL,
odd_handicap VARCHAR(255) NOT NULL, odd_handicap VARCHAR(255) NOT NULL,
status INT NOT NULL DEFAULT 0,
expires TIMESTAMP NOT NULL expires TIMESTAMP NOT NULL
); );
CREATE VIEW bet_with_outcomes AS CREATE VIEW bet_with_outcomes AS
@ -238,6 +240,12 @@ CREATE TABLE odds (
UNIQUE (event_id, market_id, name, handicap), UNIQUE (event_id, market_id, name, handicap),
UNIQUE (event_id, market_id) UNIQUE (event_id, market_id)
); );
CREATE TABLE companies (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
admin_id BIGINT NOT NULL,
wallet_id BIGINT NOT NULL
);
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

View File

@ -27,7 +27,20 @@ INSERT INTO bet_outcomes (
odd_handicap, odd_handicap,
expires expires
) )
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12
);
-- name: GetAllBets :many -- name: GetAllBets :many
SELECT * SELECT *
FROM bet_with_outcomes; FROM bet_with_outcomes;
@ -48,6 +61,10 @@ UPDATE bets
SET cashed_out = $2, SET cashed_out = $2,
updated_at = CURRENT_TIMESTAMP updated_at = CURRENT_TIMESTAMP
WHERE id = $1; WHERE id = $1;
-- name: UpdateBetOutcomeStatus :exec
UPDATE bet_outcomes
SET status = $1
WHERE id = $2;
-- name: UpdateStatus :exec -- name: UpdateStatus :exec
UPDATE bets UPDATE bets
SET status = $2, SET status = $2,

24
db/query/company.sql Normal file
View File

@ -0,0 +1,24 @@
-- name: CreateCompany :one
INSERT INTO companies (
name,
admin_id,
wallet_id
)
VALUES ($1, $2, $3)
RETURNING *;
-- name: GetAllCompanies :many
SELECT *
FROM companies;
-- name: GetCompanyByID :one
SELECT *
FROM companies
WHERE id = $1;
-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
RETURNING *;
-- name: DeleteCompany :exec
DELETE FROM companies
WHERE id = $1;

View File

@ -144,7 +144,15 @@ ORDER BY start_time ASC;
SELECT COUNT(*) SELECT COUNT(*)
FROM events FROM events
WHERE is_live = false WHERE is_live = false
AND status = 'upcoming'; AND status = 'upcoming'
AND (
league_id = $1
OR $1 IS NULL
)
AND (
sport_id = $2
OR $2 IS NULL
);
-- name: GetPaginatedUpcomingEvents :many -- name: GetPaginatedUpcomingEvents :many
SELECT id, SELECT id,
sport_id, sport_id,
@ -165,6 +173,14 @@ SELECT id,
FROM events FROM events
WHERE is_live = false WHERE is_live = false
AND status = 'upcoming' AND status = 'upcoming'
AND (
league_id = $3
OR $3 IS NULL
)
AND (
sport_id = $4
OR $4 IS NULL
)
ORDER BY start_time ASC ORDER BY start_time ASC
LIMIT $1 OFFSET $2; LIMIT $1 OFFSET $2;
-- name: GetUpcomingByID :one -- name: GetUpcomingByID :one

View File

@ -42,6 +42,10 @@ WHERE id = $1;
SELECT * SELECT *
FROM ticket_outcomes FROM ticket_outcomes
WHERE ticket_id = $1; WHERE ticket_id = $1;
-- name: UpdateTicketOutcomeStatus :exec
UPDATE ticket_outcomes
SET status = $1
WHERE id = $2;
-- name: DeleteTicket :exec -- name: DeleteTicket :exec
DELETE FROM tickets DELETE FROM tickets
WHERE id = $1; WHERE id = $1;

View File

@ -993,6 +993,225 @@ const docTemplate = `{
} }
} }
}, },
"/company": {
"get": {
"description": "Gets all companies",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets all companies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.CompanyRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"description": "Creates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Create a company",
"parameters": [
{
"description": "Creates company",
"name": "createCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}": {
"get": {
"description": "Gets a single company by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets company by id",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Updates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Updates a company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Company",
"name": "updateCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete the company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Delete the company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}/branch": { "/company/{id}/branch": {
"get": { "get": {
"description": "Gets branches by company id", "description": "Gets branches by company id",
@ -1315,6 +1534,18 @@ const docTemplate = `{
"description": "Page size", "description": "Page size",
"name": "page_size", "name": "page_size",
"in": "query" "in": "query"
},
{
"type": "string",
"description": "League ID Filter",
"name": "league_id",
"in": "query"
},
{
"type": "string",
"description": "Sport ID Filter",
"name": "sport_id",
"in": "query"
} }
], ],
"responses": { "responses": {
@ -2696,24 +2927,17 @@ const docTemplate = `{
"odd_name": { "odd_name": {
"type": "string", "type": "string",
"example": "1" "example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
} }
} }
}, },
"domain.BetStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"BET_STATUS_PENDING",
"BET_STATUS_WIN",
"BET_STATUS_LOSS",
"BET_STATUS_ERROR"
]
},
"domain.Odd": { "domain.Odd": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2765,6 +2989,21 @@ const docTemplate = `{
} }
} }
}, },
"domain.OutcomeStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"OUTCOME_STATUS_PENDING",
"OUTCOME_STATUS_WIN",
"OUTCOME_STATUS_LOSS",
"OUTCOME_STATUS_ERROR"
]
},
"domain.PaymentOption": { "domain.PaymentOption": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2869,6 +3108,14 @@ const docTemplate = `{
"type": "string", "type": "string",
"example": "1" "example": "1"
}, },
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
},
"ticket_id": { "ticket_id": {
"type": "integer", "type": "integer",
"example": 1 "example": 1
@ -2976,7 +3223,7 @@ const docTemplate = `{
"status": { "status": {
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/domain.BetStatus" "$ref": "#/definitions/domain.OutcomeStatus"
} }
], ],
"example": 1 "example": 1
@ -3102,6 +3349,27 @@ const docTemplate = `{
} }
} }
}, },
"handlers.CompanyRes": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
},
"wallet_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.CreateBetOutcomeReq": { "handlers.CreateBetOutcomeReq": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3148,7 +3416,7 @@ const docTemplate = `{
"status": { "status": {
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/domain.BetStatus" "$ref": "#/definitions/domain.OutcomeStatus"
} }
], ],
"example": 1 "example": 1
@ -3232,6 +3500,19 @@ const docTemplate = `{
} }
} }
}, },
"handlers.CreateCompanyReq": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
}
}
},
"handlers.CreateManagerReq": { "handlers.CreateManagerReq": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -985,6 +985,225 @@
} }
} }
}, },
"/company": {
"get": {
"description": "Gets all companies",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets all companies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.CompanyRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"description": "Creates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Create a company",
"parameters": [
{
"description": "Creates company",
"name": "createCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}": {
"get": {
"description": "Gets a single company by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets company by id",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Updates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Updates a company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Company",
"name": "updateCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete the company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Delete the company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}/branch": { "/company/{id}/branch": {
"get": { "get": {
"description": "Gets branches by company id", "description": "Gets branches by company id",
@ -1307,6 +1526,18 @@
"description": "Page size", "description": "Page size",
"name": "page_size", "name": "page_size",
"in": "query" "in": "query"
},
{
"type": "string",
"description": "League ID Filter",
"name": "league_id",
"in": "query"
},
{
"type": "string",
"description": "Sport ID Filter",
"name": "sport_id",
"in": "query"
} }
], ],
"responses": { "responses": {
@ -2688,24 +2919,17 @@
"odd_name": { "odd_name": {
"type": "string", "type": "string",
"example": "1" "example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
} }
} }
}, },
"domain.BetStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"BET_STATUS_PENDING",
"BET_STATUS_WIN",
"BET_STATUS_LOSS",
"BET_STATUS_ERROR"
]
},
"domain.Odd": { "domain.Odd": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2757,6 +2981,21 @@
} }
} }
}, },
"domain.OutcomeStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"OUTCOME_STATUS_PENDING",
"OUTCOME_STATUS_WIN",
"OUTCOME_STATUS_LOSS",
"OUTCOME_STATUS_ERROR"
]
},
"domain.PaymentOption": { "domain.PaymentOption": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2861,6 +3100,14 @@
"type": "string", "type": "string",
"example": "1" "example": "1"
}, },
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
},
"ticket_id": { "ticket_id": {
"type": "integer", "type": "integer",
"example": 1 "example": 1
@ -2968,7 +3215,7 @@
"status": { "status": {
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/domain.BetStatus" "$ref": "#/definitions/domain.OutcomeStatus"
} }
], ],
"example": 1 "example": 1
@ -3094,6 +3341,27 @@
} }
} }
}, },
"handlers.CompanyRes": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
},
"wallet_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.CreateBetOutcomeReq": { "handlers.CreateBetOutcomeReq": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3140,7 +3408,7 @@
"status": { "status": {
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/domain.BetStatus" "$ref": "#/definitions/domain.OutcomeStatus"
} }
], ],
"example": 1 "example": 1
@ -3224,6 +3492,19 @@
} }
} }
}, },
"handlers.CreateCompanyReq": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
}
}
},
"handlers.CreateManagerReq": { "handlers.CreateManagerReq": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -40,19 +40,11 @@ definitions:
odd_name: odd_name:
example: "1" example: "1"
type: string type: string
status:
allOf:
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
type: object type: object
domain.BetStatus:
enum:
- 0
- 1
- 2
- 3
type: integer
x-enum-varnames:
- BET_STATUS_PENDING
- BET_STATUS_WIN
- BET_STATUS_LOSS
- BET_STATUS_ERROR
domain.Odd: domain.Odd:
properties: properties:
category: category:
@ -87,6 +79,18 @@ definitions:
source: source:
type: string type: string
type: object type: object
domain.OutcomeStatus:
enum:
- 0
- 1
- 2
- 3
type: integer
x-enum-varnames:
- OUTCOME_STATUS_PENDING
- OUTCOME_STATUS_WIN
- OUTCOME_STATUS_LOSS
- OUTCOME_STATUS_ERROR
domain.PaymentOption: domain.PaymentOption:
enum: enum:
- 0 - 0
@ -165,6 +169,10 @@ definitions:
odd_name: odd_name:
example: "1" example: "1"
type: string type: string
status:
allOf:
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
ticket_id: ticket_id:
example: 1 example: 1
type: integer type: integer
@ -243,7 +251,7 @@ definitions:
type: string type: string
status: status:
allOf: allOf:
- $ref: '#/definitions/domain.BetStatus' - $ref: '#/definitions/domain.OutcomeStatus'
example: 1 example: 1
total_odds: total_odds:
example: 4.22 example: 4.22
@ -331,6 +339,21 @@ definitions:
phone_number_exist: phone_number_exist:
type: boolean type: boolean
type: object type: object
handlers.CompanyRes:
properties:
admin_id:
example: 1
type: integer
id:
example: 1
type: integer
name:
example: CompanyName
type: string
wallet_id:
example: 1
type: integer
type: object
handlers.CreateBetOutcomeReq: handlers.CreateBetOutcomeReq:
properties: properties:
event_id: event_id:
@ -364,7 +387,7 @@ definitions:
type: string type: string
status: status:
allOf: allOf:
- $ref: '#/definitions/domain.BetStatus' - $ref: '#/definitions/domain.OutcomeStatus'
example: 1 example: 1
total_odds: total_odds:
example: 4.22 example: 4.22
@ -422,6 +445,15 @@ definitions:
example: "1234567890" example: "1234567890"
type: string type: string
type: object type: object
handlers.CreateCompanyReq:
properties:
admin_id:
example: 1
type: integer
name:
example: CompanyName
type: string
type: object
handlers.CreateManagerReq: handlers.CreateManagerReq:
properties: properties:
email: email:
@ -1512,6 +1544,151 @@ paths:
summary: Update cashier summary: Update cashier
tags: tags:
- cashier - cashier
/company:
get:
consumes:
- application/json
description: Gets all companies
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/handlers.CompanyRes'
type: array
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Gets all companies
tags:
- company
post:
consumes:
- application/json
description: Creates a company
parameters:
- description: Creates company
in: body
name: createCompany
required: true
schema:
$ref: '#/definitions/handlers.CreateCompanyReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Create a company
tags:
- company
/company/{id}:
delete:
consumes:
- application/json
description: Delete the company
parameters:
- description: Company ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.APIResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Delete the company
tags:
- company
get:
consumes:
- application/json
description: Gets a single company by id
parameters:
- description: Company ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Gets company by id
tags:
- company
put:
consumes:
- application/json
description: Updates a company
parameters:
- description: Company ID
in: path
name: id
required: true
type: integer
- description: Update Company
in: body
name: updateCompany
required: true
schema:
$ref: '#/definitions/handlers.CreateCompanyReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Updates a company
tags:
- company
/company/{id}/branch: /company/{id}/branch:
get: get:
consumes: consumes:
@ -1721,6 +1898,14 @@ paths:
in: query in: query
name: page_size name: page_size
type: integer type: integer
- description: League ID Filter
in: query
name: league_id
type: string
- description: Sport ID Filter
in: query
name: sport_id
type: string
produces: produces:
- application/json - application/json
responses: responses:

View File

@ -242,6 +242,22 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
return i, err return i, err
} }
const UpdateBetOutcomeStatus = `-- name: UpdateBetOutcomeStatus :exec
UPDATE bet_outcomes
SET status = $1
WHERE id = $2
`
type UpdateBetOutcomeStatusParams struct {
Status int32 `json:"status"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateBetOutcomeStatus(ctx context.Context, arg UpdateBetOutcomeStatusParams) error {
_, err := q.db.Exec(ctx, UpdateBetOutcomeStatus, arg.Status, arg.ID)
return err
}
const UpdateCashOut = `-- name: UpdateCashOut :exec const UpdateCashOut = `-- name: UpdateCashOut :exec
UPDATE bets UPDATE bets
SET cashed_out = $2, SET cashed_out = $2,

122
gen/db/company.sql.go Normal file
View File

@ -0,0 +1,122 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
// source: company.sql
package dbgen
import (
"context"
)
const CreateCompany = `-- name: CreateCompany :one
INSERT INTO companies (
name,
admin_id,
wallet_id
)
VALUES ($1, $2, $3)
RETURNING id, name, admin_id, wallet_id
`
type CreateCompanyParams struct {
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
WalletID int64 `json:"wallet_id"`
}
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
row := q.db.QueryRow(ctx, CreateCompany, arg.Name, arg.AdminID, arg.WalletID)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}
const DeleteCompany = `-- name: DeleteCompany :exec
DELETE FROM companies
WHERE id = $1
`
func (q *Queries) DeleteCompany(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, DeleteCompany, id)
return err
}
const GetAllCompanies = `-- name: GetAllCompanies :many
SELECT id, name, admin_id, wallet_id
FROM companies
`
func (q *Queries) GetAllCompanies(ctx context.Context) ([]Company, error) {
rows, err := q.db.Query(ctx, GetAllCompanies)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Company
for rows.Next() {
var i Company
if err := rows.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetCompanyByID = `-- name: GetCompanyByID :one
SELECT id, name, admin_id, wallet_id
FROM companies
WHERE id = $1
`
func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (Company, error) {
row := q.db.QueryRow(ctx, GetCompanyByID, id)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}
const UpdateCompany = `-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
RETURNING id, name, admin_id, wallet_id
`
type UpdateCompanyParams struct {
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (Company, error) {
row := q.db.QueryRow(ctx, UpdateCompany, arg.Name, arg.AdminID, arg.ID)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}

View File

@ -110,13 +110,23 @@ SELECT id,
FROM events FROM events
WHERE is_live = false WHERE is_live = false
AND status = 'upcoming' AND status = 'upcoming'
AND (
league_id = $3
OR $3 IS NULL
)
AND (
sport_id = $4
OR $4 IS NULL
)
ORDER BY start_time ASC ORDER BY start_time ASC
LIMIT $1 OFFSET $2 LIMIT $1 OFFSET $2
` `
type GetPaginatedUpcomingEventsParams struct { type GetPaginatedUpcomingEventsParams struct {
Limit int32 `json:"limit"` Limit int32 `json:"limit"`
Offset int32 `json:"offset"` Offset int32 `json:"offset"`
LeagueID pgtype.Text `json:"league_id"`
SportID pgtype.Text `json:"sport_id"`
} }
type GetPaginatedUpcomingEventsRow struct { type GetPaginatedUpcomingEventsRow struct {
@ -139,7 +149,12 @@ type GetPaginatedUpcomingEventsRow struct {
} }
func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginatedUpcomingEventsParams) ([]GetPaginatedUpcomingEventsRow, error) { func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginatedUpcomingEventsParams) ([]GetPaginatedUpcomingEventsRow, error) {
rows, err := q.db.Query(ctx, GetPaginatedUpcomingEvents, arg.Limit, arg.Offset) rows, err := q.db.Query(ctx, GetPaginatedUpcomingEvents,
arg.Limit,
arg.Offset,
arg.LeagueID,
arg.SportID,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -180,10 +195,23 @@ SELECT COUNT(*)
FROM events FROM events
WHERE is_live = false WHERE is_live = false
AND status = 'upcoming' AND status = 'upcoming'
AND (
league_id = $1
OR $1 IS NULL
)
AND (
sport_id = $2
OR $2 IS NULL
)
` `
func (q *Queries) GetTotalEvents(ctx context.Context) (int64, error) { type GetTotalEventsParams struct {
row := q.db.QueryRow(ctx, GetTotalEvents) LeagueID pgtype.Text `json:"league_id"`
SportID pgtype.Text `json:"sport_id"`
}
func (q *Queries) GetTotalEvents(ctx context.Context, arg GetTotalEventsParams) (int64, error) {
row := q.db.QueryRow(ctx, GetTotalEvents, arg.LeagueID, arg.SportID)
var count int64 var count int64
err := row.Scan(&count) err := row.Scan(&count)
return count, err return count, err

View File

@ -37,6 +37,7 @@ type BetOutcome struct {
OddName string `json:"odd_name"` OddName string `json:"odd_name"`
OddHeader string `json:"odd_header"` OddHeader string `json:"odd_header"`
OddHandicap string `json:"odd_handicap"` OddHandicap string `json:"odd_handicap"`
Status int32 `json:"status"`
Expires pgtype.Timestamp `json:"expires"` Expires pgtype.Timestamp `json:"expires"`
} }
@ -97,6 +98,13 @@ type BranchOperation struct {
UpdatedAt pgtype.Timestamp `json:"updated_at"` UpdatedAt pgtype.Timestamp `json:"updated_at"`
} }
type Company struct {
ID int64 `json:"id"`
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
WalletID int64 `json:"wallet_id"`
}
type CustomerWallet struct { type CustomerWallet struct {
ID int64 `json:"id"` ID int64 `json:"id"`
CustomerID int64 `json:"customer_id"` CustomerID int64 `json:"customer_id"`
@ -215,6 +223,7 @@ type TicketOutcome struct {
OddName string `json:"odd_name"` OddName string `json:"odd_name"`
OddHeader string `json:"odd_header"` OddHeader string `json:"odd_header"`
OddHandicap string `json:"odd_handicap"` OddHandicap string `json:"odd_handicap"`
Status int32 `json:"status"`
Expires pgtype.Timestamp `json:"expires"` Expires pgtype.Timestamp `json:"expires"`
} }

View File

@ -133,7 +133,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int64) (TicketWithOutcom
} }
const GetTicketOutcome = `-- name: GetTicketOutcome :many const GetTicketOutcome = `-- name: GetTicketOutcome :many
SELECT id, ticket_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, expires SELECT id, ticket_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, status, expires
FROM ticket_outcomes FROM ticket_outcomes
WHERE ticket_id = $1 WHERE ticket_id = $1
` `
@ -160,6 +160,7 @@ func (q *Queries) GetTicketOutcome(ctx context.Context, ticketID int64) ([]Ticke
&i.OddName, &i.OddName,
&i.OddHeader, &i.OddHeader,
&i.OddHandicap, &i.OddHandicap,
&i.Status,
&i.Expires, &i.Expires,
); err != nil { ); err != nil {
return nil, err return nil, err
@ -171,3 +172,19 @@ func (q *Queries) GetTicketOutcome(ctx context.Context, ticketID int64) ([]Ticke
} }
return items, nil return items, nil
} }
const UpdateTicketOutcomeStatus = `-- name: UpdateTicketOutcomeStatus :exec
UPDATE ticket_outcomes
SET status = $1
WHERE id = $2
`
type UpdateTicketOutcomeStatusParams struct {
Status int32 `json:"status"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateTicketOutcomeStatus(ctx context.Context, arg UpdateTicketOutcomeStatusParams) error {
_, err := q.db.Exec(ctx, UpdateTicketOutcomeStatus, arg.Status, arg.ID)
return err
}

View File

@ -1,22 +1,24 @@
package domain package domain
import "time" import (
"time"
)
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"`
EventID int64 `json:"event_id" example:"1"` EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"` OddID int64 `json:"odd_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"` HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"` AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"` MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"` MarketName string `json:"market_name" example:"Fulltime Result"`
Odd float32 `json:"odd" example:"1.5"` Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"` OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"` OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"` OddHandicap string `json:"odd_handicap" example:"1"`
Status OutcomeStatus `json:"status" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"` Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
} }
type CreateBetOutcome struct { type CreateBetOutcome struct {
@ -34,22 +36,13 @@ type CreateBetOutcome struct {
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"` Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
} }
type BetStatus int
const (
BET_STATUS_PENDING BetStatus = iota
BET_STATUS_WIN
BET_STATUS_LOSS
BET_STATUS_ERROR
)
// If it is a ShopBet then UserID will be the cashier // If it is a ShopBet then UserID will be the cashier
// If it is a DigitalBet then UserID will be the user and the branchID will be 0 or nil // If it is a DigitalBet then UserID will be the user and the branchID will be 0 or nil
type Bet struct { type Bet struct {
ID int64 ID int64
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
Status BetStatus Status OutcomeStatus
FullName string FullName string
PhoneNumber string PhoneNumber string
BranchID ValidInt64 // Can Be Nullable BranchID ValidInt64 // Can Be Nullable
@ -63,7 +56,7 @@ type GetBet struct {
ID int64 ID int64
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
Status BetStatus Status OutcomeStatus
FullName string FullName string
PhoneNumber string PhoneNumber string
BranchID ValidInt64 // Can Be Nullable BranchID ValidInt64 // Can Be Nullable
@ -77,7 +70,7 @@ type GetBet struct {
type CreateBet struct { type CreateBet struct {
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
Status BetStatus Status OutcomeStatus
FullName string FullName string
PhoneNumber string PhoneNumber string
BranchID ValidInt64 // Can Be Nullable BranchID ValidInt64 // Can Be Nullable
@ -86,8 +79,3 @@ type CreateBet struct {
CashoutID string CashoutID string
} }
func (b BetStatus) String() string {
return []string{"Pending", "Win", "Loss", "Error"}[b]
}
// func isBetStatusValid()

View File

@ -35,7 +35,17 @@ func (m Currency) String() string {
x := float32(m) x := float32(m)
x = x / 100 x = x / 100
return fmt.Sprintf("$%.2f", x) return fmt.Sprintf("$%.2f", x)
} }
type OutcomeStatus int
const (
OUTCOME_STATUS_PENDING OutcomeStatus = iota
OUTCOME_STATUS_WIN
OUTCOME_STATUS_LOSS
OUTCOME_STATUS_ERROR
)
func (b OutcomeStatus) String() string {
return []string{"Pending", "Win", "Loss", "Error"}[b]
}

View File

@ -4,7 +4,18 @@ package domain
// they are the ones that manage the branches and branch managers // they are the ones that manage the branches and branch managers
// they will have their own wallet that they will use to distribute to the branch wallets // they will have their own wallet that they will use to distribute to the branch wallets
type Company struct { type Company struct {
ID int64 ID int64
Name string Name string
AdminID int64
} WalletID int64
}
type CreateCompany struct {
Name string
AdminID int64
WalletID int64
}
type UpdateCompany struct {
Name string
AdminID int64
}

View File

@ -3,19 +3,20 @@ package domain
import "time" import "time"
type TicketOutcome struct { type TicketOutcome struct {
ID int64 `json:"id" example:"1"` ID int64 `json:"id" example:"1"`
TicketID int64 `json:"ticket_id" example:"1"` TicketID int64 `json:"ticket_id" example:"1"`
EventID int64 `json:"event_id" example:"1"` EventID int64 `json:"event_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"` HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"` AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"` MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"` MarketName string `json:"market_name" example:"Fulltime Result"`
OddID int64 `json:"odd_id" example:"1"` OddID int64 `json:"odd_id" example:"1"`
Odd float32 `json:"odd" example:"1.5"` Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"` OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"` OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"` OddHandicap string `json:"odd_handicap" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"` Status OutcomeStatus `json:"status" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
} }
type CreateTicketOutcome struct { type CreateTicketOutcome struct {

View File

@ -14,7 +14,7 @@ func convertDBBet(bet dbgen.Bet) domain.Bet {
ID: bet.ID, ID: bet.ID,
Amount: domain.Currency(bet.Amount), Amount: domain.Currency(bet.Amount),
TotalOdds: bet.TotalOdds, TotalOdds: bet.TotalOdds,
Status: domain.BetStatus(bet.Status), Status: domain.OutcomeStatus(bet.Status),
FullName: bet.FullName, FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber, PhoneNumber: bet.PhoneNumber,
BranchID: domain.ValidInt64{ BranchID: domain.ValidInt64{
@ -48,6 +48,7 @@ func convertDBBetOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
OddName: outcome.OddName, OddName: outcome.OddName,
OddHeader: outcome.OddHeader, OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap, OddHandicap: outcome.OddHandicap,
Status: domain.OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time, Expires: outcome.Expires.Time,
}) })
} }
@ -55,7 +56,7 @@ func convertDBBetOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
ID: bet.ID, ID: bet.ID,
Amount: domain.Currency(bet.Amount), Amount: domain.Currency(bet.Amount),
TotalOdds: bet.TotalOdds, TotalOdds: bet.TotalOdds,
Status: domain.BetStatus(bet.Status), Status: domain.OutcomeStatus(bet.Status),
FullName: bet.FullName, FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber, PhoneNumber: bet.PhoneNumber,
BranchID: domain.ValidInt64{ BranchID: domain.ValidInt64{
@ -197,7 +198,7 @@ func (s *Store) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) err
return err return err
} }
func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error { func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateStatus(ctx, dbgen.UpdateStatusParams{ err := s.queries.UpdateStatus(ctx, dbgen.UpdateStatusParams{
ID: id, ID: id,
Status: int32(status), Status: int32(status),
@ -205,6 +206,14 @@ func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.BetSta
return err return err
} }
func (s *Store) UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateBetOutcomeStatus(ctx, dbgen.UpdateBetOutcomeStatusParams{
Status: int32(status),
ID: id,
})
return err
}
func (s *Store) DeleteBet(ctx context.Context, id int64) error { func (s *Store) DeleteBet(ctx context.Context, id int64) error {
return s.queries.DeleteBet(ctx, id) return s.queries.DeleteBet(ctx, id)
} }

View File

@ -0,0 +1,74 @@
package repository
import (
"context"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func convertCreateCompany(company domain.CreateCompany) dbgen.CreateCompanyParams {
return dbgen.CreateCompanyParams{
Name: company.Name,
AdminID: company.AdminID,
WalletID: company.WalletID,
}
}
func convertDBCompany(dbCompany dbgen.Company) domain.Company {
return domain.Company{
ID: dbCompany.ID,
Name: dbCompany.Name,
AdminID: dbCompany.AdminID,
WalletID: dbCompany.WalletID,
}
}
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
dbCompany, err := s.queries.CreateCompany(ctx, convertCreateCompany(company))
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) GetAllCompanies(ctx context.Context) ([]domain.Company, error) {
dbCompanies, err := s.queries.GetAllCompanies(ctx)
if err != nil {
return nil, err
}
var companies []domain.Company = make([]domain.Company, 0, len(dbCompanies))
for _, dbCompany := range dbCompanies {
companies = append(companies, convertDBCompany(dbCompany))
}
return companies, nil
}
func (s *Store) GetCompanyByID(ctx context.Context, id int64) (domain.Company, error) {
dbCompany, err := s.queries.GetCompanyByID(ctx, id)
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
dbCompany, err := s.queries.UpdateCompany(ctx, dbgen.UpdateCompanyParams{
ID: id,
Name: company.Name,
AdminID: company.AdminID,
})
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) DeleteCompany(ctx context.Context, id int64) error {
return s.queries.DeleteCompany(ctx, id)
}

View File

@ -2,6 +2,7 @@ package repository
import ( import (
"context" "context"
"math"
"time" "time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
@ -87,8 +88,16 @@ func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEven
} }
return upcomingEvents, nil return upcomingEvents, nil
} }
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error) { func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{ events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
LeagueID: pgtype.Text{
String: leagueID.Value,
Valid: leagueID.Valid,
},
SportID: pgtype.Text{
String: sportID.Value,
Valid: sportID.Valid,
},
Limit: limit, Limit: limit,
Offset: offset * limit, Offset: offset * limit,
}) })
@ -115,13 +124,22 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, off
StartTime: e.StartTime.Time.UTC(), StartTime: e.StartTime.Time.UTC(),
} }
} }
totalCount, err := s.queries.GetTotalEvents(ctx) totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{
LeagueID: pgtype.Text{
String: leagueID.Value,
Valid: leagueID.Valid,
},
SportID: pgtype.Text{
String: sportID.Value,
Valid: sportID.Valid,
},
})
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
numberOfPages := (totalCount) / int64(limit) numberOfPages := math.Ceil(float64(totalCount) / float64(limit))
return upcomingEvents, numberOfPages, nil return upcomingEvents, int64(numberOfPages), nil
} }
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) { func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
event, err := s.queries.GetUpcomingByID(ctx, ID) event, err := s.queries.GetUpcomingByID(ctx, ID)

View File

@ -34,6 +34,7 @@ func convertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) domain.GetTicket {
OddName: outcome.OddName, OddName: outcome.OddName,
OddHeader: outcome.OddHeader, OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap, OddHandicap: outcome.OddHandicap,
Status: domain.OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time, Expires: outcome.Expires.Time,
}) })
} }
@ -122,6 +123,14 @@ func (s *Store) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
return result, nil return result, nil
} }
func (s *Store) UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateTicketOutcomeStatus(ctx, dbgen.UpdateTicketOutcomeStatusParams{
Status: int32(status),
ID: id,
})
return err
}
func (s *Store) DeleteOldTickets(ctx context.Context) error { func (s *Store) DeleteOldTickets(ctx context.Context) error {
return s.queries.DeleteOldTickets(ctx) return s.queries.DeleteOldTickets(ctx)
} }

View File

@ -14,6 +14,7 @@ type BetStore interface {
GetAllBets(ctx context.Context) ([]domain.GetBet, error) GetAllBets(ctx context.Context) ([]domain.GetBet, error)
GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error) GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error)
UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error
UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
DeleteBet(ctx context.Context, id int64) error DeleteBet(ctx context.Context, id int64) error
} }

View File

@ -17,6 +17,7 @@ func NewService(betStore BetStore) *Service {
} }
func (s *Service) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) { func (s *Service) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
return s.betStore.CreateBet(ctx, bet) return s.betStore.CreateBet(ctx, bet)
} }
@ -42,10 +43,14 @@ func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) e
return s.betStore.UpdateCashOut(ctx, id, cashedOut) return s.betStore.UpdateCashOut(ctx, id, cashedOut)
} }
func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error { func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.betStore.UpdateStatus(ctx, id, status) return s.betStore.UpdateStatus(ctx, id, status)
} }
func (s *Service) UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.betStore.UpdateBetOutcomeStatus(ctx, id, status)
}
func (s *Service) DeleteBet(ctx context.Context, id int64) error { func (s *Service) DeleteBet(ctx context.Context, id int64) error {
return s.betStore.DeleteBet(ctx, id) return s.betStore.DeleteBet(ctx, id)
} }

View File

@ -0,0 +1,15 @@
package company
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type CompanyStore interface {
CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error)
GetAllCompanies(ctx context.Context) ([]domain.Company, error)
GetCompanyByID(ctx context.Context, id int64) (domain.Company, error)
UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error)
DeleteCompany(ctx context.Context, id int64) error
}

View File

@ -0,0 +1,35 @@
package company
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type Service struct {
companyStore CompanyStore
}
func NewService(companyStore CompanyStore) *Service {
return &Service{
companyStore: companyStore,
}
}
func (s *Service) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
return s.companyStore.CreateCompany(ctx, company)
}
func (s *Service) GetAllCompanies(ctx context.Context) ([]domain.Company, error) {
return s.companyStore.GetAllCompanies(ctx)
}
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.Company, error) {
return s.companyStore.GetCompanyByID(ctx, id)
}
func (s *Service) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
return s.companyStore.UpdateCompany(ctx, id, company)
}
func (s *Service) DeleteCompany(ctx context.Context, id int64) error {
return s.companyStore.DeleteCompany(ctx, id)
}

View File

@ -10,6 +10,6 @@ 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.UpcomingEvent, error)
GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error)
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
} }

View File

@ -178,8 +178,8 @@ func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEv
return s.store.GetAllUpcomingEvents(ctx) return s.store.GetAllUpcomingEvents(ctx)
} }
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error) { func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
return s.store.GetPaginatedUpcomingEvents(ctx, limit, offset) return s.store.GetPaginatedUpcomingEvents(ctx, limit, offset, leagueID, sportID)
} }
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) { func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {

View File

@ -11,6 +11,7 @@ type TicketStore interface {
CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error) CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error)
GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error)
GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error)
UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
DeleteOldTickets(ctx context.Context) error DeleteOldTickets(ctx context.Context) error
DeleteTicket(ctx context.Context, id int64) error DeleteTicket(ctx context.Context, id int64) error
} }

View File

@ -30,6 +30,10 @@ func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket
func (s *Service) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) { func (s *Service) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
return s.ticketStore.GetAllTickets(ctx) return s.ticketStore.GetAllTickets(ctx)
} }
func (s *Service) UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.ticketStore.UpdateTicketOutcomeStatus(ctx, id, status)
}
func (s *Service) DeleteTicket(ctx context.Context, id int64) error { func (s *Service) DeleteTicket(ctx context.Context, id int64) error {
return s.ticketStore.DeleteTicket(ctx, id) return s.ticketStore.DeleteTicket(ctx, id)
} }

View File

@ -91,6 +91,8 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
return s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount) return s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount)
} }
func (s *Service) UpdateWalletActive(ctx context.Context, id int64, isActive bool) error { func (s *Service) UpdateWalletActive(ctx context.Context, id int64, isActive bool) error {
return s.walletStore.UpdateWalletActive(ctx, id, isActive) return s.walletStore.UpdateWalletActive(ctx, id, isActive)
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
@ -34,6 +35,7 @@ type App struct {
walletSvc *wallet.Service walletSvc *wallet.Service
transactionSvc *transaction.Service transactionSvc *transaction.Service
branchSvc *branch.Service branchSvc *branch.Service
companySvc *company.Service
validator *customvalidator.CustomValidator validator *customvalidator.CustomValidator
JwtConfig jwtutil.JwtConfig JwtConfig jwtutil.JwtConfig
Logger *slog.Logger Logger *slog.Logger
@ -52,6 +54,7 @@ func NewApp(
walletSvc *wallet.Service, walletSvc *wallet.Service,
transactionSvc *transaction.Service, transactionSvc *transaction.Service,
branchSvc *branch.Service, branchSvc *branch.Service,
companySvc *company.Service,
notidicationStore notificationservice.NotificationStore, notidicationStore notificationservice.NotificationStore,
prematchSvc *odds.ServiceImpl, prematchSvc *odds.ServiceImpl,
eventSvc event.Service, eventSvc event.Service,
@ -83,6 +86,7 @@ func NewApp(
walletSvc: walletSvc, walletSvc: walletSvc,
transactionSvc: transactionSvc, transactionSvc: transactionSvc,
branchSvc: branchSvc, branchSvc: branchSvc,
companySvc: companySvc,
NotidicationStore: notidicationStore, NotidicationStore: notidicationStore,
Logger: logger, Logger: logger,
prematchSvc: prematchSvc, prematchSvc: prematchSvc,

View File

@ -21,82 +21,47 @@ import (
) )
type CreateBetOutcomeReq struct { type CreateBetOutcomeReq struct {
// BetID int64 `json:"bet_id" example:"1"`
EventID int64 `json:"event_id" example:"1"` EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"` OddID int64 `json:"odd_id" example:"1"`
MarketID int64 `json:"market_id" example:"1"` MarketID int64 `json:"market_id" example:"1"`
// HomeTeamName string `json:"home_team_name" example:"Manchester"`
// AwayTeamName string `json:"away_team_name" example:"Liverpool"`
// MarketName string `json:"market_name" example:"Fulltime Result"`
// Odd float32 `json:"odd" example:"1.5"`
// OddName string `json:"odd_name" example:"1"`
// Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
}
type NullableInt64 struct {
Value int64
Valid bool
}
func (n *NullableInt64) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
n.Valid = false
return nil
}
var value int64
if err := json.Unmarshal(data, &value); err != nil {
return err
}
n.Value = value
n.Valid = true
return nil
}
func (n NullableInt64) MarshalJSON() ([]byte, error) {
if !n.Valid {
return []byte("null"), nil
}
return json.Marshal(n.Value)
} }
type CreateBetReq struct { type CreateBetReq struct {
Outcomes []CreateBetOutcomeReq `json:"outcomes"` Outcomes []CreateBetOutcomeReq `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"` Status domain.OutcomeStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"` FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"` PhoneNumber string `json:"phone_number" example:"1234567890"`
IsShopBet bool `json:"is_shop_bet" example:"false"` IsShopBet bool `json:"is_shop_bet" example:"false"`
} }
type CreateBetRes struct { type CreateBetRes struct {
ID int64 `json:"id" example:"1"` ID int64 `json:"id" example:"1"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"` Status domain.OutcomeStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"` FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"` PhoneNumber string `json:"phone_number" example:"1234567890"`
BranchID int64 `json:"branch_id" example:"2"` BranchID int64 `json:"branch_id" example:"2"`
UserID int64 `json:"user_id" example:"2"` UserID int64 `json:"user_id" example:"2"`
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"`
CashedID string `json:"cashed_id" example:"21234"` CashedID string `json:"cashed_id" example:"21234"`
} }
type BetRes struct { type BetRes struct {
ID int64 `json:"id" example:"1"` ID int64 `json:"id" example:"1"`
Outcomes []domain.BetOutcome `json:"outcomes"` Outcomes []domain.BetOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"` Status domain.OutcomeStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"` FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"` PhoneNumber string `json:"phone_number" example:"1234567890"`
BranchID int64 `json:"branch_id" example:"2"` BranchID int64 `json:"branch_id" example:"2"`
UserID int64 `json:"user_id" example:"2"` UserID int64 `json:"user_id" example:"2"`
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"`
CashedID string `json:"cashed_id" example:"21234"` CashedID string `json:"cashed_id" example:"21234"`
} }
func convertCreateBet(bet domain.Bet, createdNumber int64) CreateBetRes { func convertCreateBet(bet domain.Bet, createdNumber int64) CreateBetRes {
@ -152,15 +117,12 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBetReq failed", "error", err) logger.Error("CreateBetReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
// Validating user by role // Validating user by role
@ -174,9 +136,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID) branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID)
if err != nil { if err != nil {
logger.Error("CreateBetReq failed, branch id invalid") logger.Error("CreateBetReq failed, branch id invalid")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Branch ID invalid",
})
} }
// Deduct a percentage of the amount // Deduct a percentage of the amount
@ -186,9 +146,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
if err != nil { if err != nil {
logger.Error("CreateBetReq failed, unable to deduct from WalletID") logger.Error("CreateBetReq failed, unable to deduct from WalletID")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Unable to deduct from branch wallet",
})
} }
bet, err = betSvc.CreateBet(c.Context(), domain.CreateBet{ bet, err = betSvc.CreateBet(c.Context(), domain.CreateBet{
@ -240,8 +198,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
// TODO Validate Outcomes Here and make sure they didn't expire // TODO Validate Outcomes Here and make sure they didn't expire
// Validation for creating tickets // Validation for creating tickets
if len(req.Outcomes) > 30 { if len(req.Outcomes) > 30 {
response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
return nil
} }
var outcomes []domain.CreateBetOutcome = make([]domain.CreateBetOutcome, 0, len(req.Outcomes)) var outcomes []domain.CreateBetOutcome = make([]domain.CreateBetOutcome, 0, len(req.Outcomes))
for _, outcome := range req.Outcomes { for _, outcome := range req.Outcomes {
@ -250,22 +207,19 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
oddIDStr := strconv.FormatInt(outcome.OddID, 10) oddIDStr := strconv.FormatInt(outcome.OddID, 10)
event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr) event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr)
if err != nil { if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
return nil
} }
// Checking to make sure the event hasn't already started // Checking to make sure the event hasn't already started
currentTime := time.Now() currentTime := time.Now()
if event.StartTime.Before(currentTime) { if event.StartTime.Before(currentTime) {
response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
return nil
} }
odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr) odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr)
if err != nil { if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
return nil
} }
type rawOddType struct { type rawOddType struct {
ID string ID string
@ -291,8 +245,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
} }
if !isOddFound { if !isOddFound {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
return nil
} }
parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32) parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32)
@ -454,15 +407,12 @@ func UpdateCashOut(logger *slog.Logger, betSvc *bet.Service,
var req UpdateCashOutReq var req UpdateCashOutReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateCashOutReq failed", "error", err) logger.Error("UpdateCashOutReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
err = betSvc.UpdateCashOut(c.Context(), id, req.CashedOut) err = betSvc.UpdateCashOut(c.Context(), id, req.CashedOut)

View File

@ -116,15 +116,12 @@ func CreateBranch(logger *slog.Logger, branchSvc *branch.Service, walletSvc *wal
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchReq failed", "error", err) logger.Error("CreateBranchReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
// Create Branch Wallet // Create Branch Wallet
@ -194,14 +191,12 @@ func CreateSupportedOperation(logger *slog.Logger, branchSvc *branch.Service, va
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateSupportedOperationReq failed", "error", err) logger.Error("CreateSupportedOperationReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
} }
operation, err := branchSvc.CreateSupportedOperation(c.Context(), domain.CreateSupportedOperation{ operation, err := branchSvc.CreateSupportedOperation(c.Context(), domain.CreateSupportedOperation{
Name: req.Name, Name: req.Name,
@ -241,15 +236,12 @@ func CreateBranchOperation(logger *slog.Logger, branchSvc *branch.Service, valid
var req CreateBranchOperationReq var req CreateBranchOperationReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchOperationReq failed", "error", err) logger.Error("CreateBranchOperationReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
err := branchSvc.CreateBranchOperation(c.Context(), domain.CreateBranchOperation{ err := branchSvc.CreateBranchOperation(c.Context(), domain.CreateBranchOperation{
@ -383,6 +375,7 @@ func GetBranchByCompanyID(logger *slog.Logger, branchSvc *branch.Service, valida
// @Router /branch [get] // @Router /branch [get]
func GetAllBranches(logger *slog.Logger, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler { func GetAllBranches(logger *slog.Logger, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
// TODO: Limit the get all branches to only the companies for branch manager and cashiers
branches, err := branchSvc.GetAllBranches(c.Context()) branches, err := branchSvc.GetAllBranches(c.Context())
if err != nil { if err != nil {
logger.Error("Failed to get branches", "error", err) logger.Error("Failed to get branches", "error", err)
@ -566,14 +559,11 @@ func UpdateBranch(logger *slog.Logger, branchSvc *branch.Service, validator *cus
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchReq failed", "error", err) logger.Error("CreateBranchReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
branch, err := branchSvc.UpdateBranch(c.Context(), id, domain.UpdateBranch{ branch, err := branchSvc.UpdateBranch(c.Context(), id, domain.UpdateBranch{

View File

@ -40,14 +40,11 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, branchSvc *branch
var req CreateCashierReq var req CreateCashierReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("RegisterUser failed", "error", err) logger.Error("RegisterUser failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
userRequest := domain.CreateUserReq{ userRequest := domain.CreateUserReq{
FirstName: req.FirstName, FirstName: req.FirstName,
@ -60,19 +57,15 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, branchSvc *branch
newUser, err := userSvc.CreateUser(c.Context(), userRequest) newUser, err := userSvc.CreateUser(c.Context(), userRequest)
if err != nil { if err != nil {
logger.Error("CreateCashier failed", "error", err) logger.Error("CreateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil
} }
err = branchSvc.CreateBranchCashier(c.Context(), req.BranchID, newUser.ID) err = branchSvc.CreateBranchCashier(c.Context(), req.BranchID, newUser.ID)
if err != nil { if err != nil {
logger.Error("CreateCashier failed", "error", err) logger.Error("CreateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil
} }
return response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil)
response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil)
return nil
} }
} }
@ -119,15 +112,13 @@ func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *custo
// } // }
// valErrs, ok := validator.Validate(c, filter) // valErrs, ok := validator.Validate(c, filter)
// if !ok { // if !ok {
// response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) // return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
// return nil
// } // }
cashiers, err := userSvc.GetAllCashiers(c.Context()) cashiers, err := userSvc.GetAllCashiers(c.Context())
if err != nil { if err != nil {
logger.Error("GetAllCashiers failed", "error", err) logger.Error("GetAllCashiers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil)
return nil
} }
var result []GetCashierRes var result []GetCashierRes
@ -148,8 +139,8 @@ func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *custo
Suspended: cashier.Suspended, Suspended: cashier.Suspended,
}) })
} }
response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", result, nil)
return nil return response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", result, nil)
} }
} }
@ -177,22 +168,19 @@ func UpdateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
var req updateUserReq var req updateUserReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateCashier failed", "error", err) logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
return nil
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
cashierIdStr := c.Params("id") cashierIdStr := c.Params("id")
cashierId, err := strconv.ParseInt(cashierIdStr, 10, 64) cashierId, err := strconv.ParseInt(cashierIdStr, 10, 64)
if err != nil { if err != nil {
logger.Error("UpdateCashier failed", "error", err) logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashier ID", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashier ID", nil, nil)
return nil
} }
err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{ err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
UserId: cashierId, UserId: cashierId,
@ -212,11 +200,9 @@ func UpdateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
) )
if err != nil { if err != nil {
logger.Error("UpdateCashier failed", "error", err) logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cashier", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cashier", nil, nil)
return nil
} }
response.WriteJSON(c, fiber.StatusOK, "Cashier updated successfully", nil, nil) return response.WriteJSON(c, fiber.StatusOK, "Cashier updated successfully", nil, nil)
return nil
} }
} }

View File

@ -0,0 +1,229 @@
package handlers
import (
"log/slog"
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
"github.com/gofiber/fiber/v2"
)
type CreateCompanyReq struct {
Name string `json:"name" example:"CompanyName"`
AdminID int64 `json:"admin_id" example:"1"`
}
type CompanyRes struct {
ID int64 `json:"id" example:"1"`
Name string `json:"name" example:"CompanyName"`
AdminID int64 `json:"admin_id" example:"1"`
WalletID int64 `json:"wallet_id" example:"1"`
}
func convertCompany(company domain.Company) CompanyRes {
return CompanyRes{
ID: company.ID,
Name: company.Name,
AdminID: company.AdminID,
WalletID: company.WalletID,
}
}
// CreateCompany godoc
// @Summary Create a company
// @Description Creates a company
// @Tags company
// @Accept json
// @Produce json
// @Param createCompany body CreateCompanyReq true "Creates company"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company [post]
func CreateCompany(logger *slog.Logger, companySvc *company.Service, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
var req CreateCompanyReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// Create Branch Wallet
newWallet, err := walletSvc.CreateWallet(c.Context(), domain.CreateWallet{
IsWithdraw: false,
IsBettable: true,
IsTransferable: true,
UserID: req.AdminID,
})
if err != nil {
logger.Error("Create Company Wallet failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create company wallet", err, nil)
}
company, err := companySvc.CreateCompany(c.Context(), domain.CreateCompany{
Name: req.Name,
AdminID: req.AdminID,
WalletID: newWallet.ID,
})
if err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusCreated, "Company Created", res, nil)
}
}
// GetAllCompanies godoc
// @Summary Gets all companies
// @Description Gets all companies
// @Tags company
// @Accept json
// @Produce json
// @Success 200 {array} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company [get]
func GetAllCompanies(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companies, err := companySvc.GetAllCompanies(c.Context())
if err != nil {
logger.Error("Failed to get companies", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get companies", err, nil)
}
var result []CompanyRes = make([]CompanyRes, 0, len(companies))
for _, company := range companies {
result = append(result, convertCompany(company))
}
return response.WriteJSON(c, fiber.StatusOK, "All Companies retrieved", result, nil)
}
}
// GetCompanyByID godoc
// @Summary Gets company by id
// @Description Gets a single company by id
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [get]
func GetCompanyByID(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company ID", err, nil)
}
company, err := companySvc.GetCompanyByID(c.Context(), id)
if err != nil {
logger.Error("Failed to get company by ID", "companyID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to company branch", err, nil)
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusOK, "Company retrieved successfully", res, nil)
}
}
// UpdateCompany godoc
// @Summary Updates a company
// @Description Updates a company
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID"
// @Param updateCompany body CreateCompanyReq true "Update Company"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [put]
func UpdateCompany(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company ID", err, nil)
}
var req CreateCompanyReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
company, err := companySvc.UpdateCompany(c.Context(), id, domain.UpdateCompany{
Name: req.Name,
AdminID: req.AdminID,
})
if err != nil {
logger.Error("Failed to update company", "companyID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update company", err, nil)
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusOK, "Company Updated", res, nil)
}
}
// DeleteCompany godoc
// @Summary Delete the company
// @Description Delete the company
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID""
// @Success 200 {object} response.APIResponse
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [delete]
func DeleteCompany(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid Company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Company ID", err, nil)
}
err = companySvc.DeleteCompany(c.Context(), id)
if err != nil {
logger.Error("Failed to delete by ID", "Company ID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to Delete Company", err, nil)
}
return response.WriteJSON(c, fiber.StatusOK, "Company removed successfully", nil, nil)
}
}

View File

@ -36,14 +36,11 @@ func CreateManager(logger *slog.Logger, userSvc *user.Service, validator *custom
var req CreateManagerReq var req CreateManagerReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("RegisterUser failed", "error", err) logger.Error("RegisterUser failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
user := domain.CreateUserReq{ user := domain.CreateUserReq{
FirstName: req.FirstName, FirstName: req.FirstName,
@ -56,11 +53,9 @@ func CreateManager(logger *slog.Logger, userSvc *user.Service, validator *custom
_, err := userSvc.CreateUser(c.Context(), user) _, err := userSvc.CreateUser(c.Context(), user)
if err != nil { if err != nil {
logger.Error("CreateManagers failed", "error", err) logger.Error("CreateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create Managers", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create Managers", nil, nil)
return nil
} }
response.WriteJSON(c, fiber.StatusOK, "Managers created successfully", nil, nil) return response.WriteJSON(c, fiber.StatusOK, "Managers created successfully", nil, nil)
return nil
} }
} }
@ -91,17 +86,15 @@ func GetAllManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
} }
valErrs, ok := validator.Validate(c, filter) valErrs, ok := validator.Validate(c, filter)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
Managers, err := userSvc.GetAllUsers(c.Context(), filter) Managers, err := userSvc.GetAllUsers(c.Context(), filter)
if err != nil { if err != nil {
logger.Error("GetAllManagers failed", "error", err) logger.Error("GetAllManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", nil, nil)
return nil
} }
response.WriteJSON(c, fiber.StatusOK, "Managers retrieved successfully", Managers, nil)
return nil return response.WriteJSON(c, fiber.StatusOK, "Managers retrieved successfully", Managers, nil)
} }
} }
@ -123,22 +116,19 @@ func UPdateManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
var req updateUserReq var req updateUserReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateManagers failed", "error", err) logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
return nil
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
ManagersIdStr := c.Params("id") ManagersIdStr := c.Params("id")
ManagersId, err := strconv.ParseInt(ManagersIdStr, 10, 64) ManagersId, err := strconv.ParseInt(ManagersIdStr, 10, 64)
if err != nil { if err != nil {
logger.Error("UpdateManagers failed", "error", err) logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Managers ID", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Managers ID", nil, nil)
return nil
} }
err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{ err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
UserId: ManagersId, UserId: ManagersId,
@ -158,11 +148,9 @@ func UPdateManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
) )
if err != nil { if err != nil {
logger.Error("UpdateManagers failed", "error", err) logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Managers", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Managers", nil, nil)
return nil
} }
response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil) return response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil)
return nil
} }
} }

View File

@ -4,6 +4,7 @@ import (
"log/slog" "log/slog"
"strconv" "strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
@ -98,6 +99,8 @@ func GetRawOddsByMarketID(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fi
// @Produce json // @Produce json
// @Param page query int false "Page number" // @Param page query int false "Page number"
// @Param page_size query int false "Page size" // @Param page_size query int false "Page size"
// @Param league_id query string false "League ID Filter"
// @Param sport_id query string false "Sport ID Filter"
// @Success 200 {array} domain.UpcomingEvent // @Success 200 {array} domain.UpcomingEvent
// @Failure 500 {object} response.APIResponse // @Failure 500 {object} response.APIResponse
// @Router /prematch/events [get] // @Router /prematch/events [get]
@ -105,8 +108,20 @@ func GetAllUpcomingEvents(logger *slog.Logger, eventSvc event.Service) fiber.Han
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
page := c.QueryInt("page", 1) page := c.QueryInt("page", 1)
pageSize := c.QueryInt("page_size", 10) pageSize := c.QueryInt("page_size", 10)
leagueIDQuery := c.Query("league_id")
sportIDQuery := c.Query("sport_id")
leagueID := domain.ValidString{
Value: leagueIDQuery,
Valid: leagueIDQuery != "",
}
sportID := domain.ValidString{
Value: sportIDQuery,
Valid: sportIDQuery != "",
}
events, total, err := eventSvc.GetPaginatedUpcomingEvents(c.Context(), int32(pageSize), int32(page)-1, leagueID, sportID)
events, total, err := eventSvc.GetPaginatedUpcomingEvents(c.Context(), int32(pageSize), int32(page) - 1)
if err != nil { if err != nil {
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil)
} }

View File

@ -38,6 +38,12 @@ type CreateTicketRes struct {
FastCode int64 `json:"fast_code" example:"1234"` FastCode int64 `json:"fast_code" example:"1234"`
CreatedNumber int64 `json:"created_number" example:"3"` CreatedNumber int64 `json:"created_number" example:"3"`
} }
type TicketRes struct {
ID int64 `json:"id" example:"1"`
Outcomes []domain.TicketOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
}
// CreateTicket godoc // CreateTicket godoc
// @Summary Create a temporary ticket // @Summary Create a temporary ticket
@ -55,22 +61,18 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
var req CreateTicketReq var req CreateTicketReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTicketReq failed", "error", err) logger.Error("CreateTicketReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
// TODO Validate Outcomes Here and make sure they didn't expire // TODO Validate Outcomes Here and make sure they didn't expire
// Validation for creating tickets // Validation for creating tickets
if len(req.Outcomes) > 30 { if len(req.Outcomes) > 30 {
response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
return nil
} }
var outcomes []domain.CreateTicketOutcome = make([]domain.CreateTicketOutcome, 0, len(req.Outcomes)) var outcomes []domain.CreateTicketOutcome = make([]domain.CreateTicketOutcome, 0, len(req.Outcomes))
for _, outcome := range req.Outcomes { for _, outcome := range req.Outcomes {
@ -79,22 +81,19 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
oddIDStr := strconv.FormatInt(outcome.OddID, 10) oddIDStr := strconv.FormatInt(outcome.OddID, 10)
event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr) event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr)
if err != nil { if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
return nil
} }
// Checking to make sure the event hasn't already started // Checking to make sure the event hasn't already started
currentTime := time.Now() currentTime := time.Now()
if event.StartTime.Before(currentTime) { if event.StartTime.Before(currentTime) {
response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
return nil
} }
odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr) odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr)
if err != nil { if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
return nil
} }
type rawOddType struct { type rawOddType struct {
ID string ID string
@ -120,8 +119,7 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
} }
if !isOddFound { if !isOddFound {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
return nil
} }
parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32) parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32)
@ -173,13 +171,6 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
} }
} }
type TicketRes struct {
ID int64 `json:"id" example:"1"`
Outcomes []domain.TicketOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
}
// GetTicketByID godoc // GetTicketByID godoc
// @Summary Get ticket by ID // @Summary Get ticket by ID
// @Description Retrieve ticket details by ticket ID // @Description Retrieve ticket details by ticket ID

View File

@ -97,9 +97,7 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
branch, err := branchSvc.GetBranchByID(c.Context(), 1) branch, err := branchSvc.GetBranchByID(c.Context(), 1)
if err != nil { if err != nil {
logger.Error("CreateTransactionReq no branches") logger.Error("CreateTransactionReq no branches")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "This user type doesn't have branches", err, nil)
"error": "This user type doesn't have branches",
})
} }
branchID = branch.ID branchID = branch.ID
@ -108,9 +106,7 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID) branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID)
if err != nil { if err != nil {
logger.Error("CreateTransactionReq failed, branch id invalid") logger.Error("CreateTransactionReq failed, branch id invalid")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID invalid", err, nil)
"error": "Branch ID invalid",
})
} }
branchID = branch.ID branchID = branch.ID
} }
@ -118,16 +114,13 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
var req CreateTransactionReq var req CreateTransactionReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTransactionReq failed", "error", err) logger.Error("CreateTransactionReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
logger.Error("CreateTransactionReq failed v", "error", valErrs) logger.Error("CreateTransactionReq failed v", "error", valErrs)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
transaction, err := transactionSvc.CreateTransaction(c.Context(), domain.CreateTransaction{ transaction, err := transactionSvc.CreateTransaction(c.Context(), domain.CreateTransaction{
@ -288,15 +281,12 @@ func UpdateTransactionVerified(logger *slog.Logger, transactionSvc *transaction.
var req UpdateTransactionVerifiedReq var req UpdateTransactionVerifiedReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateTransactionVerifiedReq failed", "error", err) logger.Error("UpdateTransactionVerifiedReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
err = transactionSvc.UpdateTransactionVerified(c.Context(), id, req.Verified) err = transactionSvc.UpdateTransactionVerified(c.Context(), id, req.Verified)

View File

@ -158,22 +158,18 @@ func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTransferReq failed", "error", err) logger.Error("CreateTransferReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
transfer, err := walletSvc.TransferToWallet(c.Context(), senderID, receiverID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod), domain.ValidInt64{Value: userID, Valid: true}) transfer, err := walletSvc.TransferToWallet(c.Context(), senderID, receiverID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod), domain.ValidInt64{Value: userID, Valid: true})
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
return nil
} }
res := convertTransfer(transfer) res := convertTransfer(transfer)
@ -218,15 +214,12 @@ func RefillWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *cus
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("CreateRefillReq failed", "error", err) logger.Error("CreateRefillReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
valErrs, ok := validator.Validate(c, req) valErrs, ok := validator.Validate(c, req)
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
} }
transfer, err := walletSvc.RefillWallet(c.Context(), domain.CreateTransfer{ transfer, err := walletSvc.RefillWallet(c.Context(), domain.CreateTransfer{
@ -241,8 +234,7 @@ func RefillWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *cus
}) })
if !ok { if !ok {
response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)
return nil
} }
res := convertTransfer(transfer) res := convertTransfer(transfer)

View File

@ -213,9 +213,7 @@ func UpdateWalletActive(logger *slog.Logger, walletSvc *wallet.Service, validato
var req UpdateWalletActiveReq var req UpdateWalletActiveReq
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateWalletActiveReq failed", "error", err) logger.Error("UpdateWalletActiveReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
"error": "Invalid request",
})
} }
err = walletSvc.UpdateWalletActive(c.Context(), id, req.IsActive) err = walletSvc.UpdateWalletActive(c.Context(), id, req.IsActive)
@ -249,7 +247,7 @@ func GetCustomerWallet(logger *slog.Logger, walletSvc *wallet.Service, validator
vendorID, err := strconv.ParseInt(c.Get("vendor_id"), 10, 64) vendorID, err := strconv.ParseInt(c.Get("vendor_id"), 10, 64)
if err != nil { if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id") return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company_id", err, nil)
} }
logger.Info("Company ID: " + strconv.FormatInt(vendorID, 10)) logger.Info("Company ID: " + strconv.FormatInt(vendorID, 10))

View File

@ -47,9 +47,13 @@ func (a *App) authMiddleware(c *fiber.Ctx) error {
c.Locals("branch_id", claim.BranchId) c.Locals("branch_id", claim.BranchId)
c.Locals("refresh_token", refreshToken) c.Locals("refresh_token", refreshToken)
if claim.Role != domain.RoleCustomer { return c.Next()
// TODO: Add branch id here from the user }
// c.Locals("branch_id", claim.)
func (a *App) SuperAdminOnly(c *fiber.Ctx) error {
userRole := c.Locals("role").(domain.Role)
if userRole != domain.RoleSuperAdmin {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid access token")
} }
return c.Next() return c.Next()
} }

View File

@ -25,7 +25,6 @@ func (a *App) initAppRoutes() {
if err != nil { if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id") return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id")
} }
// a.logger.Info("User ID: " + string(userId.(string))) //panic: interface conversion: interface {} is int64, not string
a.logger.Info("User ID: " + strconv.FormatInt(userId, 10)) a.logger.Info("User ID: " + strconv.FormatInt(userId, 10))
fmt.Printf("User ID: %d\n", userId) fmt.Printf("User ID: %d\n", userId)
a.logger.Info("Role: " + role) a.logger.Info("Role: " + role)
@ -85,6 +84,13 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/branch/:id/operation", a.authMiddleware, handlers.GetBranchOperations(a.logger, a.branchSvc, a.validator)) a.fiber.Get("/branch/:id/operation", a.authMiddleware, handlers.GetBranchOperations(a.logger, a.branchSvc, a.validator))
a.fiber.Delete("/branch/:id/operation/:opID", a.authMiddleware, handlers.DeleteBranchOperation(a.logger, a.branchSvc, a.validator)) a.fiber.Delete("/branch/:id/operation/:opID", a.authMiddleware, handlers.DeleteBranchOperation(a.logger, a.branchSvc, a.validator))
// Company
a.fiber.Post("/company", a.authMiddleware, a.SuperAdminOnly, handlers.CreateCompany(a.logger, a.companySvc, a.walletSvc, a.validator))
a.fiber.Get("/company", a.authMiddleware, a.SuperAdminOnly, handlers.GetAllCompanies(a.logger, a.companySvc, a.validator))
a.fiber.Get("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.GetCompanyByID(a.logger, a.companySvc, a.validator))
a.fiber.Put("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.UpdateCompany(a.logger, a.companySvc, a.validator))
a.fiber.Delete("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.DeleteCompany(a.logger, a.companySvc, a.validator))
// Ticket // Ticket
a.fiber.Post("/ticket", handlers.CreateTicket(a.logger, a.ticketSvc, a.eventSvc, *a.prematchSvc, a.validator)) a.fiber.Post("/ticket", handlers.CreateTicket(a.logger, a.ticketSvc, a.eventSvc, *a.prematchSvc, a.validator))
a.fiber.Get("/ticket", handlers.GetAllTickets(a.logger, a.ticketSvc, a.validator)) a.fiber.Get("/ticket", handlers.GetAllTickets(a.logger, a.ticketSvc, a.validator))