major fixes while integrating

This commit is contained in:
Samuel Tariku 2025-04-11 21:46:48 +03:00
parent a97cb32bba
commit 1b0a068a02
48 changed files with 2811 additions and 438 deletions

View File

@ -69,20 +69,26 @@ CREATE TABLE IF NOT EXISTS bet_outcomes (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
bet_id BIGINT NOT NULL, bet_id BIGINT NOT NULL,
event_id bigint not null, event_id bigint not null,
odd_id BIGINT NOT NULL, odd_id BIGINT NOT NULL
); );
CREATE TABLE IF NOT EXISTS ticket_outcomes ( CREATE TABLE IF NOT EXISTS ticket_outcomes (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
ticket_id BIGINT NOT NULL, ticket_id BIGINT NOT NULL,
event_id bigint not null, event_id bigint not null,
odd_id BIGINT NOT NULL, odd_id BIGINT NOT NULL
); );
ALTER TABLE bets CREATE VIEW bet_with_outcomes AS
ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id); SELECT bets.*,
ALTER TABLE bets JSON_AGG(bet_outcomes.*) AS outcomes
ADD CONSTRAINT fk_bets_branches FOREIGN KEY (branch_id) REFERENCES branches(id); FROM bets
ALTER TABLE bet_outcomes LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id
ADD CONSTRAINT fk_bet_outcomes_bet FOREIGN KEY (bet_id) REFERENCES bets(id); GROUP BY bets.id;
CREATE VIEW ticket_with_outcomes AS
SELECT tickets.*,
JSON_AGG(ticket_outcomes.*) AS outcomes
FROM tickets
LEFT JOIN ticket_outcomes ON tickets.id = ticket_outcomes.ticket_id
GROUP BY tickets.id;
CREATE TABLE IF NOT EXISTS wallets ( CREATE TABLE IF NOT EXISTS wallets (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
balance BIGINT NOT NULL DEFAULT 0, balance BIGINT NOT NULL DEFAULT 0,
@ -164,6 +170,48 @@ CREATE TABLE IF NOT EXISTS branch_operations (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
CREATE TABLE IF NOT EXISTS branch_cashiers (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
branch_id BIGINT NOT NULL,
UNIQUE(user_id, branch_id)
);
ALTER TABLE refresh_tokens
ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE bets
ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id),
ADD CONSTRAINT fk_bets_branches FOREIGN KEY (branch_id) REFERENCES branches(id);
ALTER TABLE bet_outcomes
ADD CONSTRAINT fk_bet_outcomes_bets FOREIGN KEY (bet_id) REFERENCES bets(id),
ADD CONSTRAINT fk_bet_outcomes_events FOREIGN KEY (event_id) REFERENCES supported_operations(id),
ADD CONSTRAINT fk_bet_outcomes_odds FOREIGN KEY (odd_id) REFERENCES supported_operations(id);
ALTER TABLE ticket_outcomes
ADD CONSTRAINT fk_ticket_outcomes_tickets FOREIGN KEY (ticket_id) REFERENCES tickets(id),
ADD CONSTRAINT fk_ticket_outcomes_events FOREIGN KEY (event_id) REFERENCES supported_operations(id),
ADD CONSTRAINT fk_ticket_outcomes_odds FOREIGN KEY (odd_id) REFERENCES supported_operations(id);
ALTER TABLE wallets
ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE customer_wallets
ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id),
ADD CONSTRAINT fk_customer_wallets_regular_wallet FOREIGN KEY (regular_wallet_id) REFERENCES wallets(id),
ADD CONSTRAINT fk_customer_wallets_static_wallet FOREIGN KEY (static_wallet_id) REFERENCES wallets(id);
ALTER TABLE wallet_transfer
ADD CONSTRAINT fk_wallet_transfer_receiver_wallet FOREIGN KEY (receiver_wallet_id) REFERENCES wallets(id),
ADD CONSTRAINT fk_wallet_transfer_sender_wallet FOREIGN KEY (sender_wallet_id) REFERENCES wallets(id),
ADD CONSTRAINT fk_wallet_transfer_cashier FOREIGN KEY (cashier_id) REFERENCES users(id);
ALTER TABLE transactions
ADD CONSTRAINT fk_transactions_branches FOREIGN KEY (branch_id) REFERENCES branches(id),
ADD CONSTRAINT fk_transactions_cashiers FOREIGN KEY (cashier_id) REFERENCES users(id),
ADD CONSTRAINT fk_transactions_bets FOREIGN KEY (bet_id) REFERENCES bets(id);
ALTER TABLE branches
ADD CONSTRAINT fk_branches_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id),
ADD CONSTRAINT fk_branches_manager FOREIGN KEY (branch_manager_id) REFERENCES users(id);
ALTER TABLE branch_operations
ADD CONSTRAINT fk_branch_operations_operations FOREIGN KEY (operation_id) REFERENCES supported_operations(id),
ADD CONSTRAINT fk_branch_operations_branches FOREIGN KEY (branch_id) REFERENCES branches(id);
ALTER TABLE branch_cashiers
ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(id),
ADD CONSTRAINT fk_branch_cashiers_branches FOREIGN KEY (branch_id) REFERENCES branches(id);
----------------------------------------------seed data------------------------------------------------------------- ----------------------------------------------seed data-------------------------------------------------------------
-------------------------------------- DO NOT USE IN PRODUCTION------------------------------------------------- -------------------------------------- DO NOT USE IN PRODUCTION-------------------------------------------------
CREATE EXTENSION IF NOT EXISTS pgcrypto; CREATE EXTENSION IF NOT EXISTS pgcrypto;
@ -215,7 +263,7 @@ VALUES (
'cybersamt@gmail.com', 'cybersamt@gmail.com',
NULL, NULL,
crypt('password@123', gen_salt('bf'))::bytea, crypt('password@123', gen_salt('bf'))::bytea,
'cashier', 'super_admin',
TRUE, TRUE,
FALSE, FALSE,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP,
@ -227,3 +275,23 @@ INSERT INTO supported_operations (name, description)
VALUES ('SportBook', 'Sportbook operations'), VALUES ('SportBook', 'Sportbook operations'),
('Virtual', 'Virtual operations'), ('Virtual', 'Virtual operations'),
('GameZone', 'GameZone operations'); ('GameZone', 'GameZone operations');
INSERT INTO wallets (
balance,
is_withdraw,
is_bettable,
is_transferable,
user_id,
is_active,
created_at,
updated_at
)
VALUES (
10000,
TRUE,
TRUE,
TRUE,
1,
TRUE,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP
);

View File

@ -1,16 +1,43 @@
-- name: CreateBet :one -- name: CreateBet :one
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id, is_shop_bet, cashout_id) INSERT INTO bets (
amount,
total_odds,
status,
full_name,
phone_number,
branch_id,
user_id,
is_shop_bet,
cashout_id
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *; RETURNING *;
-- name: CreateBetOutcome :copyfrom
INSERT INTO bet_outcomes (bet_id, event_id, odd_id)
VALUES ($1, $2, $3);
-- name: GetAllBets :many -- name: GetAllBets :many
SELECT * FROM bets; SELECT *
FROM bet_with_outcomes;
-- name: GetBetByID :one -- name: GetBetByID :one
SELECT * FROM bets WHERE id = $1; SELECT *
FROM bet_with_outcomes
WHERE id = $1;
-- name: GetBetByCashoutID :many
SELECT
FROM bet_with_outcomes
WHERE cashout_id = $1;
-- name: GetBetByBranchID :many
SELECT *
FROM bet_with_outcomes
WHERE branch_id = $1;
-- name: UpdateCashOut :exec -- name: UpdateCashOut :exec
UPDATE bets SET cashed_out = $2, updated_at = CURRENT_TIMESTAMP WHERE id = $1; UPDATE bets
SET cashed_out = $2,
updated_at = CURRENT_TIMESTAMP
WHERE id = $1;
-- name: DeleteBet :exec -- name: DeleteBet :exec
DELETE FROM bets WHERE id = $1; DELETE FROM bets
WHERE id = $1;
-- name: DeleteBetOutcome :exec
DELETE FROM bet_outcomes
WHERE bet_id = $1;

View File

@ -1,42 +1,86 @@
-- name: CreateBranch :one -- name: CreateBranch :one
INSERT INTO branches (name, location, wallet_id, branch_manager_id, company_id, is_self_owned) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; INSERT INTO branches (
name,
location,
wallet_id,
branch_manager_id,
company_id,
is_self_owned
)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *;
-- name: CreateSupportedOperation :one -- name: CreateSupportedOperation :one
INSERT INTO supported_operations (name, description) VALUES ($1, $2) RETURNING *; INSERT INTO supported_operations (name, description)
VALUES ($1, $2)
RETURNING *;
-- name: CreateBranchOperation :one -- name: CreateBranchOperation :one
INSERT INTO branch_operations (operation_id, branch_id) VALUES ($1, $2) RETURNING *; INSERT INTO branch_operations (operation_id, branch_id)
VALUES ($1, $2)
RETURNING *;
-- name: CreateBranchCashier :one
INSERT INTO branch_cashiers (user_id, branch_id)
VALUES ($1, $2)
RETURNING *;
-- name: GetAllBranches :many -- name: GetAllBranches :many
SELECT * FROM branch_details; SELECT *
FROM branch_details;
-- name: GetBranchByID :one -- name: GetBranchByID :one
SELECT * FROM branch_details WHERE id = $1; SELECT *
FROM branch_details
WHERE id = $1;
-- name: GetBranchByCompanyID :many -- name: GetBranchByCompanyID :many
SELECT * FROM branch_details WHERE company_id = $1; SELECT *
FROM branch_details
WHERE company_id = $1;
-- name: GetBranchByManagerID :many -- name: GetBranchByManagerID :many
SELECT * FROM branch_details WHERE branch_manager_id = $1; SELECT *
FROM branch_details
WHERE branch_manager_id = $1;
-- name: SearchBranchByName :many -- name: SearchBranchByName :many
SELECT * FROM branch_details WHERE name ILIKE '%' || $1 || '%'; SELECT *
FROM branch_details
WHERE name ILIKE '%' || $1 || '%';
-- name: GetAllSupportedOperations :many -- name: GetAllSupportedOperations :many
SELECT * FROM supported_operations; SELECT *
FROM supported_operations;
-- name: GetBranchOperations :many -- name: GetBranchOperations :many
SELECT branch_operations.*, supported_operations.name, supported_operations.description SELECT branch_operations.*,
supported_operations.name,
supported_operations.description
FROM branch_operations FROM branch_operations
JOIN supported_operations ON branch_operations.operation_id = supported_operations.id JOIN supported_operations ON branch_operations.operation_id = supported_operations.id
WHERE branch_operations.branch_id = $1; WHERE branch_operations.branch_id = $1;
-- name: GetBranchByCashier :one
SELECT branches.*
FROM branch_cashiers
JOIN branches ON branch_cashiers.branch_id = branches.id
WHERE branch_cashiers.user_id = $1;
-- name: GetCashiersByBranch :many
SELECT users.*
FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id
WHERE branch_cashiers.branch_id = $1;
-- name: GetAllCashiers :many
SELECT users.*
FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id;
-- name: UpdateBranch :one -- name: UpdateBranch :one
UPDATE branches SET name = $1, location = $2, branch_manager_id = $3, company_id = $4, is_self_owned = $5 WHERE id = $6 RETURNING *; UPDATE branches
SET name = $1,
location = $2,
branch_manager_id = $3,
company_id = $4,
is_self_owned = $5
WHERE id = $6
RETURNING *;
-- name: DeleteBranch :exec -- name: DeleteBranch :exec
DELETE FROM branches WHERE id = $1; DELETE FROM branches
WHERE id = $1;
-- name: DeleteBranchOperation :exec -- name: DeleteBranchOperation :exec
DELETE FROM branch_operations WHERE operation_id = $1 AND branch_id = $2; DELETE FROM branch_operations
WHERE operation_id = $1
AND branch_id = $2;
-- name: DeleteBranchCashier :exec
DELETE FROM branch_cashiers
WHERE user_id = $1;

View File

@ -2,15 +2,26 @@
INSERT INTO tickets (amount, total_odds) INSERT INTO tickets (amount, total_odds)
VALUES ($1, $2) VALUES ($1, $2)
RETURNING *; RETURNING *;
-- name: CreateTicketOutcome :copyfrom
INSERT INTO ticket_outcomes (ticket_id, event_id, odd_id)
VALUES ($1, $2, $3);
-- name: GetAllTickets :many -- name: GetAllTickets :many
SELECT * FROM tickets; SELECT *
FROM ticket_with_outcomes;
-- name: GetTicketByID :one -- name: GetTicketByID :one
SELECT * FROM tickets WHERE id = $1; SELECT *
FROM ticket_with_outcomes
WHERE id = $1;
-- name: GetTicketOutcome :many
SELECT *
FROM ticket_outcomes
WHERE ticket_id = $1;
-- name: DeleteTicket :exec -- name: DeleteTicket :exec
DELETE FROM tickets WHERE id = $1; DELETE FROM tickets
WHERE id = $1;
-- name: DeleteOldTickets :exec -- name: DeleteOldTickets :exec
Delete from tickets where created_at < now() - interval '1 day'; Delete from tickets
where created_at < now() - interval '1 day';
-- name: DeleteTicketOutcome :exec
Delete from ticket_outcomes
where ticket_id = $1;

View File

@ -1,49 +1,114 @@
-- name: CreateUser :one -- name: CreateUser :one
INSERT INTO users (
INSERT INTO users (first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at) first_name,
last_name,
email,
phone_number,
role,
password,
email_verified,
phone_verified,
created_at,
updated_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at; RETURNING id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at;
-- name: GetUserByID :one -- name: GetUserByID :one
SELECT * SELECT *
FROM users FROM users
WHERE id = $1; WHERE id = $1;
-- name: GetAllUsers :many -- name: GetAllUsers :many
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users; FROM users;
-- name: SearchUserByNameOrPhone :many -- name: SearchUserByNameOrPhone :many
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE first_name ILIKE '%' || $1 || '%' WHERE first_name ILIKE '%' || $1 || '%'
OR last_name ILIKE '%' || $1 || '%' OR last_name ILIKE '%' || $1 || '%'
OR phone_number LIKE '%' || $1 || '%'; OR phone_number LIKE '%' || $1 || '%';
-- name: UpdateUser :exec -- name: UpdateUser :exec
UPDATE users UPDATE users
SET first_name = $1, last_name = $2, email = $3, phone_number = $4, role = $5, updated_at = $6 SET first_name = $1,
last_name = $2,
email = $3,
phone_number = $4,
role = $5,
updated_at = $6
WHERE id = $7; WHERE id = $7;
-- name: DeleteUser :exec -- name: DeleteUser :exec
DELETE FROM users DELETE FROM users
WHERE id = $1; WHERE id = $1;
-- name: CheckPhoneEmailExist :one -- name: CheckPhoneEmailExist :one
SELECT SELECT EXISTS (
EXISTS (SELECT 1 FROM users WHERE users.phone_number = $1 AND users.phone_number IS NOT NULL) AS phone_exists, SELECT 1
EXISTS (SELECT 1 FROM users WHERE users.email = $2 AND users.email IS NOT NULL) AS email_exists; FROM users
WHERE users.phone_number = $1
AND users.phone_number IS NOT NULL
) AS phone_exists,
EXISTS (
SELECT 1
FROM users
WHERE users.email = $2
AND users.email IS NOT NULL
) AS email_exists;
-- name: GetUserByEmail :one -- name: GetUserByEmail :one
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE email = $1; WHERE email = $1;
-- name: GetUserByPhone :one -- name: GetUserByPhone :one
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE phone_number = $1; WHERE phone_number = $1;
-- name: UpdatePassword :exec -- name: UpdatePassword :exec
UPDATE users UPDATE users
SET password = $1, updated_at = $4 SET password = $1,
WHERE (email = $2 OR phone_number = $3); updated_at = $4
WHERE (
email = $2
OR phone_number = $3
);

View File

@ -1,21 +1,34 @@
-- name: CreateWallet :one -- name: CreateWallet :one
INSERT INTO wallets (is_withdraw, is_bettable, is_transferable, user_id) VALUES ($1, $2, $3, $4) RETURNING *; INSERT INTO wallets (
is_withdraw,
is_bettable,
is_transferable,
user_id
)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: CreateCustomerWallet :one -- name: CreateCustomerWallet :one
INSERT INTO customer_wallets (customer_id, company_id, regular_wallet_id, static_wallet_id) VALUES ($1, $2, $3, $4) RETURNING *; INSERT INTO customer_wallets (
customer_id,
company_id,
regular_wallet_id,
static_wallet_id
)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetAllWallets :many -- name: GetAllWallets :many
SELECT * FROM wallets; SELECT *
FROM wallets;
-- name: GetWalletByID :one -- name: GetWalletByID :one
SELECT * FROM wallets WHERE id = $1; SELECT *
FROM wallets
WHERE id = $1;
-- name: GetWalletByUserID :many -- name: GetWalletByUserID :many
SELECT * FROM wallets WHERE user_id = $1; SELECT *
FROM wallets
WHERE user_id = $1;
-- name: GetCustomerWallet :one -- name: GetCustomerWallet :one
SELECT SELECT cw.id,
cw.id,
cw.customer_id, cw.customer_id,
cw.company_id, cw.company_id,
rw.id AS regular_id, rw.id AS regular_id,
@ -26,15 +39,30 @@ SELECT
sw.updated_at as static_updated_at, sw.updated_at as static_updated_at,
cw.created_at cw.created_at
FROM customer_wallets cw FROM customer_wallets cw
JOIN wallets rw ON cw.regular_wallet_id = rw.id JOIN wallets rw ON cw.regular_wallet_id = rw.id
JOIN wallets sw ON cw.static_wallet_id = sw.id JOIN wallets sw ON cw.static_wallet_id = sw.id
WHERE cw.customer_id = $1 AND cw.company_id = $2; WHERE cw.customer_id = $1
AND cw.company_id = $2;
-- name: GetAllBranchWallets :many
SELECT wallets.id,
wallets.balance,
wallets.is_active,
wallets.updated_at,
wallets.created_at,
branches.name,
branches.location,
branches.branch_manager_id,
branches.company_id,
branches.is_self_owned
FROM branches
JOIN wallets ON branches.wallet_id = wallets.id;
-- name: UpdateBalance :exec -- name: UpdateBalance :exec
UPDATE wallets SET balance = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2; UPDATE wallets
SET balance = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2;
-- name: UpdateWalletActive :exec -- name: UpdateWalletActive :exec
UPDATE wallets SET is_active = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2; UPDATE wallets
SET is_active = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2;

View File

@ -618,6 +618,44 @@ const docTemplate = `{
} }
} }
}, },
"/branch/{id}/bets": {
"get": {
"description": "Gets bets by its branch id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"branch"
],
"summary": "Gets bets by its branch id",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.BetRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/branch/{id}/operation": { "/branch/{id}/operation": {
"get": { "get": {
"description": "Gets branch operations", "description": "Gets branch operations",
@ -716,6 +754,44 @@ const docTemplate = `{
} }
} }
}, },
"/branchWallet": {
"get": {
"description": "Retrieve all branch wallets",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wallet"
],
"summary": "Get all branch wallets",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.WalletRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/cashiers": { "/cashiers": {
"get": { "get": {
"description": "Get all cashiers", "description": "Get all cashiers",
@ -1170,6 +1246,53 @@ const docTemplate = `{
} }
} }
}, },
"/search/branch": {
"get": {
"description": "Search branches by name or location",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"branch"
],
"summary": "Search branches",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.BranchDetailRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/supportedOperation": { "/supportedOperation": {
"get": { "get": {
"description": "Gets all supported operations", "description": "Gets all supported operations",
@ -1555,7 +1678,53 @@ const docTemplate = `{
} }
} }
}, },
"/transfer/wallet": { "/transfer/refill/:id": {
"post": {
"description": "Super Admin route to refill a wallet",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"transfer"
],
"summary": "Refill wallet",
"parameters": [
{
"description": "Create Transfer",
"name": "refillWallet",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateTransferReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.TransferWalletRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/transfer/wallet/:id": {
"post": { "post": {
"description": "Create a transfer to wallet", "description": "Create a transfer to wallet",
"consumes": [ "consumes": [
@ -1583,7 +1752,53 @@ const docTemplate = `{
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"$ref": "#/definitions/handlers.TransferRes" "$ref": "#/definitions/handlers.TransferWalletRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/transfer/wallet/{id}": {
"get": {
"description": "Get transfer by wallet",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"transfer"
],
"summary": "Get transfer by wallet",
"parameters": [
{
"description": "Create Transfer",
"name": "transferToWallet",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateTransferReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.TransferWalletRes"
} }
}, },
"400": { "400": {
@ -2101,6 +2316,23 @@ const docTemplate = `{
} }
}, },
"definitions": { "definitions": {
"domain.BetOutcome": {
"type": "object",
"properties": {
"betID": {
"type": "integer"
},
"eventID": {
"type": "integer"
},
"id": {
"type": "integer"
},
"oddID": {
"type": "integer"
}
}
},
"domain.BetStatus": { "domain.BetStatus": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2116,9 +2348,6 @@ const docTemplate = `{
"BET_STATUS_ERROR" "BET_STATUS_ERROR"
] ]
}, },
"domain.Outcome": {
"type": "object"
},
"domain.PaymentOption": { "domain.PaymentOption": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2151,6 +2380,36 @@ const docTemplate = `{
"RoleCashier" "RoleCashier"
] ]
}, },
"domain.TicketOutcome": {
"type": "object",
"properties": {
"eventID": {
"type": "integer"
},
"id": {
"type": "integer"
},
"oddID": {
"type": "integer"
},
"ticketID": {
"type": "integer"
}
}
},
"handlers.BetOutcome": {
"type": "object",
"properties": {
"event_id": {
"type": "integer",
"example": 1
},
"odd_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.BetRes": { "handlers.BetRes": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2177,7 +2436,7 @@ const docTemplate = `{
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/domain.Outcome" "$ref": "#/definitions/domain.BetOutcome"
} }
}, },
"phone_number": { "phone_number": {
@ -2213,6 +2472,10 @@ const docTemplate = `{
"type": "integer", "type": "integer",
"example": 1 "example": 1
}, },
"id": {
"type": "integer",
"example": 1
},
"is_self_owned": { "is_self_owned": {
"type": "boolean", "type": "boolean",
"example": false "example": false
@ -2263,6 +2526,10 @@ const docTemplate = `{
"type": "integer", "type": "integer",
"example": 1 "example": 1
}, },
"id": {
"type": "integer",
"example": 1
},
"is_self_owned": { "is_self_owned": {
"type": "boolean", "type": "boolean",
"example": false "example": false
@ -2306,43 +2573,7 @@ const docTemplate = `{
} }
}, },
"handlers.CreateBetReq": { "handlers.CreateBetReq": {
"type": "object", "type": "object"
"properties": {
"amount": {
"type": "number",
"example": 100
},
"full_name": {
"type": "string",
"example": "John"
},
"is_shop_bet": {
"type": "boolean",
"example": false
},
"outcomes": {
"type": "array",
"items": {
"type": "integer"
}
},
"phone_number": {
"type": "string",
"example": "1234567890"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
}
],
"example": 1
},
"total_odds": {
"type": "number",
"example": 4.22
}
}
}, },
"handlers.CreateBranchOperationReq": { "handlers.CreateBranchOperationReq": {
"type": "object", "type": "object",
@ -2391,6 +2622,10 @@ const docTemplate = `{
"handlers.CreateCashierReq": { "handlers.CreateCashierReq": {
"type": "object", "type": "object",
"properties": { "properties": {
"branch_id": {
"type": "integer",
"example": 1
},
"email": { "email": {
"type": "string", "type": "string",
"example": "john.doe@example.com" "example": "john.doe@example.com"
@ -2416,10 +2651,6 @@ const docTemplate = `{
"handlers.CreateManagerReq": { "handlers.CreateManagerReq": {
"type": "object", "type": "object",
"properties": { "properties": {
"branch_id": {
"type": "integer",
"example": 1
},
"email": { "email": {
"type": "string", "type": "string",
"example": "john.doe@example.com" "example": "john.doe@example.com"
@ -2465,7 +2696,7 @@ const docTemplate = `{
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"type": "integer" "$ref": "#/definitions/handlers.TicketOutcome"
} }
}, },
"total_odds": { "total_odds": {
@ -2477,6 +2708,10 @@ const docTemplate = `{
"handlers.CreateTicketRes": { "handlers.CreateTicketRes": {
"type": "object", "type": "object",
"properties": { "properties": {
"created_number": {
"type": "integer",
"example": 3
},
"fast_code": { "fast_code": {
"type": "integer", "type": "integer",
"example": 1234 "example": 1234
@ -2550,10 +2785,6 @@ const docTemplate = `{
"payment_method": { "payment_method": {
"type": "string", "type": "string",
"example": "cash" "example": "cash"
},
"receiver_id": {
"type": "integer",
"example": 1
} }
} }
}, },
@ -2599,6 +2830,17 @@ const docTemplate = `{
} }
} }
}, },
"handlers.NullableInt64": {
"type": "object",
"properties": {
"valid": {
"type": "boolean"
},
"value": {
"type": "integer"
}
}
},
"handlers.RegisterCodeReq": { "handlers.RegisterCodeReq": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2701,6 +2943,19 @@ const docTemplate = `{
} }
} }
}, },
"handlers.TicketOutcome": {
"type": "object",
"properties": {
"event_id": {
"type": "integer",
"example": 1
},
"odd_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.TicketRes": { "handlers.TicketRes": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2715,7 +2970,7 @@ const docTemplate = `{
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/domain.Outcome" "$ref": "#/definitions/domain.TicketOutcome"
} }
}, },
"total_odds": { "total_odds": {
@ -2788,7 +3043,7 @@ const docTemplate = `{
} }
} }
}, },
"handlers.TransferRes": { "handlers.TransferWalletRes": {
"type": "object", "type": "object",
"properties": { "properties": {
"amount": { "amount": {

View File

@ -610,6 +610,44 @@
} }
} }
}, },
"/branch/{id}/bets": {
"get": {
"description": "Gets bets by its branch id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"branch"
],
"summary": "Gets bets by its branch id",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.BetRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/branch/{id}/operation": { "/branch/{id}/operation": {
"get": { "get": {
"description": "Gets branch operations", "description": "Gets branch operations",
@ -708,6 +746,44 @@
} }
} }
}, },
"/branchWallet": {
"get": {
"description": "Retrieve all branch wallets",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wallet"
],
"summary": "Get all branch wallets",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.WalletRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/cashiers": { "/cashiers": {
"get": { "get": {
"description": "Get all cashiers", "description": "Get all cashiers",
@ -1162,6 +1238,53 @@
} }
} }
}, },
"/search/branch": {
"get": {
"description": "Search branches by name or location",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"branch"
],
"summary": "Search branches",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.BranchDetailRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/supportedOperation": { "/supportedOperation": {
"get": { "get": {
"description": "Gets all supported operations", "description": "Gets all supported operations",
@ -1547,7 +1670,53 @@
} }
} }
}, },
"/transfer/wallet": { "/transfer/refill/:id": {
"post": {
"description": "Super Admin route to refill a wallet",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"transfer"
],
"summary": "Refill wallet",
"parameters": [
{
"description": "Create Transfer",
"name": "refillWallet",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateTransferReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.TransferWalletRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/transfer/wallet/:id": {
"post": { "post": {
"description": "Create a transfer to wallet", "description": "Create a transfer to wallet",
"consumes": [ "consumes": [
@ -1575,7 +1744,53 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"$ref": "#/definitions/handlers.TransferRes" "$ref": "#/definitions/handlers.TransferWalletRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/transfer/wallet/{id}": {
"get": {
"description": "Get transfer by wallet",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"transfer"
],
"summary": "Get transfer by wallet",
"parameters": [
{
"description": "Create Transfer",
"name": "transferToWallet",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateTransferReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.TransferWalletRes"
} }
}, },
"400": { "400": {
@ -2093,6 +2308,23 @@
} }
}, },
"definitions": { "definitions": {
"domain.BetOutcome": {
"type": "object",
"properties": {
"betID": {
"type": "integer"
},
"eventID": {
"type": "integer"
},
"id": {
"type": "integer"
},
"oddID": {
"type": "integer"
}
}
},
"domain.BetStatus": { "domain.BetStatus": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2108,9 +2340,6 @@
"BET_STATUS_ERROR" "BET_STATUS_ERROR"
] ]
}, },
"domain.Outcome": {
"type": "object"
},
"domain.PaymentOption": { "domain.PaymentOption": {
"type": "integer", "type": "integer",
"enum": [ "enum": [
@ -2143,6 +2372,36 @@
"RoleCashier" "RoleCashier"
] ]
}, },
"domain.TicketOutcome": {
"type": "object",
"properties": {
"eventID": {
"type": "integer"
},
"id": {
"type": "integer"
},
"oddID": {
"type": "integer"
},
"ticketID": {
"type": "integer"
}
}
},
"handlers.BetOutcome": {
"type": "object",
"properties": {
"event_id": {
"type": "integer",
"example": 1
},
"odd_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.BetRes": { "handlers.BetRes": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2169,7 +2428,7 @@
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/domain.Outcome" "$ref": "#/definitions/domain.BetOutcome"
} }
}, },
"phone_number": { "phone_number": {
@ -2205,6 +2464,10 @@
"type": "integer", "type": "integer",
"example": 1 "example": 1
}, },
"id": {
"type": "integer",
"example": 1
},
"is_self_owned": { "is_self_owned": {
"type": "boolean", "type": "boolean",
"example": false "example": false
@ -2255,6 +2518,10 @@
"type": "integer", "type": "integer",
"example": 1 "example": 1
}, },
"id": {
"type": "integer",
"example": 1
},
"is_self_owned": { "is_self_owned": {
"type": "boolean", "type": "boolean",
"example": false "example": false
@ -2298,43 +2565,7 @@
} }
}, },
"handlers.CreateBetReq": { "handlers.CreateBetReq": {
"type": "object", "type": "object"
"properties": {
"amount": {
"type": "number",
"example": 100
},
"full_name": {
"type": "string",
"example": "John"
},
"is_shop_bet": {
"type": "boolean",
"example": false
},
"outcomes": {
"type": "array",
"items": {
"type": "integer"
}
},
"phone_number": {
"type": "string",
"example": "1234567890"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
}
],
"example": 1
},
"total_odds": {
"type": "number",
"example": 4.22
}
}
}, },
"handlers.CreateBranchOperationReq": { "handlers.CreateBranchOperationReq": {
"type": "object", "type": "object",
@ -2383,6 +2614,10 @@
"handlers.CreateCashierReq": { "handlers.CreateCashierReq": {
"type": "object", "type": "object",
"properties": { "properties": {
"branch_id": {
"type": "integer",
"example": 1
},
"email": { "email": {
"type": "string", "type": "string",
"example": "john.doe@example.com" "example": "john.doe@example.com"
@ -2408,10 +2643,6 @@
"handlers.CreateManagerReq": { "handlers.CreateManagerReq": {
"type": "object", "type": "object",
"properties": { "properties": {
"branch_id": {
"type": "integer",
"example": 1
},
"email": { "email": {
"type": "string", "type": "string",
"example": "john.doe@example.com" "example": "john.doe@example.com"
@ -2457,7 +2688,7 @@
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"type": "integer" "$ref": "#/definitions/handlers.TicketOutcome"
} }
}, },
"total_odds": { "total_odds": {
@ -2469,6 +2700,10 @@
"handlers.CreateTicketRes": { "handlers.CreateTicketRes": {
"type": "object", "type": "object",
"properties": { "properties": {
"created_number": {
"type": "integer",
"example": 3
},
"fast_code": { "fast_code": {
"type": "integer", "type": "integer",
"example": 1234 "example": 1234
@ -2542,10 +2777,6 @@
"payment_method": { "payment_method": {
"type": "string", "type": "string",
"example": "cash" "example": "cash"
},
"receiver_id": {
"type": "integer",
"example": 1
} }
} }
}, },
@ -2591,6 +2822,17 @@
} }
} }
}, },
"handlers.NullableInt64": {
"type": "object",
"properties": {
"valid": {
"type": "boolean"
},
"value": {
"type": "integer"
}
}
},
"handlers.RegisterCodeReq": { "handlers.RegisterCodeReq": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2693,6 +2935,19 @@
} }
} }
}, },
"handlers.TicketOutcome": {
"type": "object",
"properties": {
"event_id": {
"type": "integer",
"example": 1
},
"odd_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.TicketRes": { "handlers.TicketRes": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2707,7 +2962,7 @@
"outcomes": { "outcomes": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/domain.Outcome" "$ref": "#/definitions/domain.TicketOutcome"
} }
}, },
"total_odds": { "total_odds": {
@ -2780,7 +3035,7 @@
} }
} }
}, },
"handlers.TransferRes": { "handlers.TransferWalletRes": {
"type": "object", "type": "object",
"properties": { "properties": {
"amount": { "amount": {

View File

@ -1,4 +1,15 @@
definitions: definitions:
domain.BetOutcome:
properties:
betID:
type: integer
eventID:
type: integer
id:
type: integer
oddID:
type: integer
type: object
domain.BetStatus: domain.BetStatus:
enum: enum:
- 0 - 0
@ -11,8 +22,6 @@ definitions:
- BET_STATUS_WIN - BET_STATUS_WIN
- BET_STATUS_LOSS - BET_STATUS_LOSS
- BET_STATUS_ERROR - BET_STATUS_ERROR
domain.Outcome:
type: object
domain.PaymentOption: domain.PaymentOption:
enum: enum:
- 0 - 0
@ -39,6 +48,26 @@ definitions:
- RoleBranchManager - RoleBranchManager
- RoleCustomer - RoleCustomer
- RoleCashier - RoleCashier
domain.TicketOutcome:
properties:
eventID:
type: integer
id:
type: integer
oddID:
type: integer
ticketID:
type: integer
type: object
handlers.BetOutcome:
properties:
event_id:
example: 1
type: integer
odd_id:
example: 1
type: integer
type: object
handlers.BetRes: handlers.BetRes:
properties: properties:
amount: amount:
@ -58,7 +87,7 @@ definitions:
type: boolean type: boolean
outcomes: outcomes:
items: items:
$ref: '#/definitions/domain.Outcome' $ref: '#/definitions/domain.BetOutcome'
type: array type: array
phone_number: phone_number:
example: "1234567890" example: "1234567890"
@ -82,6 +111,9 @@ definitions:
company_id: company_id:
example: 1 example: 1
type: integer type: integer
id:
example: 1
type: integer
is_self_owned: is_self_owned:
example: false example: false
type: boolean type: boolean
@ -118,6 +150,9 @@ definitions:
company_id: company_id:
example: 1 example: 1
type: integer type: integer
id:
example: 1
type: integer
is_self_owned: is_self_owned:
example: false example: false
type: boolean type: boolean
@ -148,30 +183,6 @@ definitions:
type: boolean type: boolean
type: object type: object
handlers.CreateBetReq: handlers.CreateBetReq:
properties:
amount:
example: 100
type: number
full_name:
example: John
type: string
is_shop_bet:
example: false
type: boolean
outcomes:
items:
type: integer
type: array
phone_number:
example: "1234567890"
type: string
status:
allOf:
- $ref: '#/definitions/domain.BetStatus'
example: 1
total_odds:
example: 4.22
type: number
type: object type: object
handlers.CreateBranchOperationReq: handlers.CreateBranchOperationReq:
properties: properties:
@ -206,6 +217,9 @@ definitions:
type: object type: object
handlers.CreateCashierReq: handlers.CreateCashierReq:
properties: properties:
branch_id:
example: 1
type: integer
email: email:
example: john.doe@example.com example: john.doe@example.com
type: string type: string
@ -224,9 +238,6 @@ definitions:
type: object type: object
handlers.CreateManagerReq: handlers.CreateManagerReq:
properties: properties:
branch_id:
example: 1
type: integer
email: email:
example: john.doe@example.com example: john.doe@example.com
type: string type: string
@ -259,7 +270,7 @@ definitions:
type: number type: number
outcomes: outcomes:
items: items:
type: integer $ref: '#/definitions/handlers.TicketOutcome'
type: array type: array
total_odds: total_odds:
example: 4.22 example: 4.22
@ -267,6 +278,9 @@ definitions:
type: object type: object
handlers.CreateTicketRes: handlers.CreateTicketRes:
properties: properties:
created_number:
example: 3
type: integer
fast_code: fast_code:
example: 1234 example: 1234
type: integer type: integer
@ -318,9 +332,6 @@ definitions:
payment_method: payment_method:
example: cash example: cash
type: string type: string
receiver_id:
example: 1
type: integer
type: object type: object
handlers.CustomerWalletRes: handlers.CustomerWalletRes:
properties: properties:
@ -352,6 +363,13 @@ definitions:
static_updated_at: static_updated_at:
type: string type: string
type: object type: object
handlers.NullableInt64:
properties:
valid:
type: boolean
value:
type: integer
type: object
handlers.RegisterCodeReq: handlers.RegisterCodeReq:
properties: properties:
email: email:
@ -423,6 +441,15 @@ definitions:
example: SportsBook example: SportsBook
type: string type: string
type: object type: object
handlers.TicketOutcome:
properties:
event_id:
example: 1
type: integer
odd_id:
example: 1
type: integer
type: object
handlers.TicketRes: handlers.TicketRes:
properties: properties:
amount: amount:
@ -433,7 +460,7 @@ definitions:
type: integer type: integer
outcomes: outcomes:
items: items:
$ref: '#/definitions/domain.Outcome' $ref: '#/definitions/domain.TicketOutcome'
type: array type: array
total_odds: total_odds:
example: 4.22 example: 4.22
@ -483,7 +510,7 @@ definitions:
example: true example: true
type: boolean type: boolean
type: object type: object
handlers.TransferRes: handlers.TransferWalletRes:
properties: properties:
amount: amount:
example: 100 example: 100
@ -1055,6 +1082,31 @@ paths:
summary: Updates a branch summary: Updates a branch
tags: tags:
- branch - branch
/branch/{id}/bets:
get:
consumes:
- application/json
description: Gets bets by its branch id
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/handlers.BetRes'
type: array
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Gets bets by its branch id
tags:
- branch
/branch/{id}/operation: /branch/{id}/operation:
get: get:
consumes: consumes:
@ -1120,6 +1172,31 @@ paths:
summary: Delete the branch operation summary: Delete the branch operation
tags: tags:
- branch - branch
/branchWallet:
get:
consumes:
- application/json
description: Retrieve all branch wallets
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/handlers.WalletRes'
type: array
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Get all branch wallets
tags:
- wallet
/cashiers: /cashiers:
get: get:
consumes: consumes:
@ -1418,6 +1495,37 @@ paths:
summary: Create a operation summary: Create a operation
tags: tags:
- branch - branch
/search/branch:
get:
consumes:
- application/json
description: Search branches by name or location
parameters:
- description: Search query
in: query
name: q
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/handlers.BranchDetailRes'
type: array
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Search branches
tags:
- branch
/supportedOperation: /supportedOperation:
get: get:
consumes: consumes:
@ -1672,7 +1780,37 @@ paths:
summary: Updates the cashed out field summary: Updates the cashed out field
tags: tags:
- transaction - transaction
/transfer/wallet: /transfer/refill/:id:
post:
consumes:
- application/json
description: Super Admin route to refill a wallet
parameters:
- description: Create Transfer
in: body
name: refillWallet
required: true
schema:
$ref: '#/definitions/handlers.CreateTransferReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.TransferWalletRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Refill wallet
tags:
- transfer
/transfer/wallet/:id:
post: post:
consumes: consumes:
- application/json - application/json
@ -1690,7 +1828,7 @@ paths:
"200": "200":
description: OK description: OK
schema: schema:
$ref: '#/definitions/handlers.TransferRes' $ref: '#/definitions/handlers.TransferWalletRes'
"400": "400":
description: Bad Request description: Bad Request
schema: schema:
@ -1702,6 +1840,36 @@ paths:
summary: Create a transfer to wallet summary: Create a transfer to wallet
tags: tags:
- transfer - transfer
/transfer/wallet/{id}:
get:
consumes:
- application/json
description: Get transfer by wallet
parameters:
- description: Create Transfer
in: body
name: transferToWallet
required: true
schema:
$ref: '#/definitions/handlers.CreateTransferReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.TransferWalletRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Get transfer by wallet
tags:
- transfer
/user/checkPhoneEmailExist: /user/checkPhoneEmailExist:
post: post:
consumes: consumes:

View File

@ -12,7 +12,17 @@ import (
) )
const CreateBet = `-- name: CreateBet :one const CreateBet = `-- name: CreateBet :one
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id, is_shop_bet, cashout_id) INSERT INTO bets (
amount,
total_odds,
status,
full_name,
phone_number,
branch_id,
user_id,
is_shop_bet,
cashout_id
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet RETURNING id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet
` `
@ -60,8 +70,15 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro
return i, err return i, err
} }
type CreateBetOutcomeParams struct {
BetID int64
EventID int64
OddID int64
}
const DeleteBet = `-- name: DeleteBet :exec const DeleteBet = `-- name: DeleteBet :exec
DELETE FROM bets WHERE id = $1 DELETE FROM bets
WHERE id = $1
` `
func (q *Queries) DeleteBet(ctx context.Context, id int64) error { func (q *Queries) DeleteBet(ctx context.Context, id int64) error {
@ -69,19 +86,30 @@ func (q *Queries) DeleteBet(ctx context.Context, id int64) error {
return err return err
} }
const GetAllBets = `-- name: GetAllBets :many const DeleteBetOutcome = `-- name: DeleteBetOutcome :exec
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet FROM bets DELETE FROM bet_outcomes
WHERE bet_id = $1
` `
func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) { func (q *Queries) DeleteBetOutcome(ctx context.Context, betID int64) error {
_, err := q.db.Exec(ctx, DeleteBetOutcome, betID)
return err
}
const GetAllBets = `-- name: GetAllBets :many
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes
FROM bet_with_outcomes
`
func (q *Queries) GetAllBets(ctx context.Context) ([]BetWithOutcome, error) {
rows, err := q.db.Query(ctx, GetAllBets) rows, err := q.db.Query(ctx, GetAllBets)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close() defer rows.Close()
var items []Bet var items []BetWithOutcome
for rows.Next() { for rows.Next() {
var i Bet var i BetWithOutcome
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
@ -96,6 +124,7 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
&i.CreatedAt, &i.CreatedAt,
&i.UpdatedAt, &i.UpdatedAt,
&i.IsShopBet, &i.IsShopBet,
&i.Outcomes,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -107,13 +136,85 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
return items, nil return items, nil
} }
const GetBetByID = `-- name: GetBetByID :one const GetBetByBranchID = `-- name: GetBetByBranchID :many
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet FROM bets WHERE id = $1 SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes
FROM bet_with_outcomes
WHERE branch_id = $1
` `
func (q *Queries) GetBetByID(ctx context.Context, id int64) (Bet, error) { func (q *Queries) GetBetByBranchID(ctx context.Context, branchID pgtype.Int8) ([]BetWithOutcome, error) {
rows, err := q.db.Query(ctx, GetBetByBranchID, branchID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []BetWithOutcome
for rows.Next() {
var i BetWithOutcome
if err := rows.Scan(
&i.ID,
&i.Amount,
&i.TotalOdds,
&i.Status,
&i.FullName,
&i.PhoneNumber,
&i.BranchID,
&i.UserID,
&i.CashedOut,
&i.CashoutID,
&i.CreatedAt,
&i.UpdatedAt,
&i.IsShopBet,
&i.Outcomes,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetBetByCashoutID = `-- name: GetBetByCashoutID :many
SELECT
FROM bet_with_outcomes
WHERE cashout_id = $1
`
type GetBetByCashoutIDRow struct {
}
func (q *Queries) GetBetByCashoutID(ctx context.Context, cashoutID string) ([]GetBetByCashoutIDRow, error) {
rows, err := q.db.Query(ctx, GetBetByCashoutID, cashoutID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetBetByCashoutIDRow
for rows.Next() {
var i GetBetByCashoutIDRow
if err := rows.Scan(); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetBetByID = `-- name: GetBetByID :one
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes
FROM bet_with_outcomes
WHERE id = $1
`
func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, error) {
row := q.db.QueryRow(ctx, GetBetByID, id) row := q.db.QueryRow(ctx, GetBetByID, id)
var i Bet var i BetWithOutcome
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
@ -128,12 +229,16 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (Bet, error) {
&i.CreatedAt, &i.CreatedAt,
&i.UpdatedAt, &i.UpdatedAt,
&i.IsShopBet, &i.IsShopBet,
&i.Outcomes,
) )
return i, err return i, err
} }
const UpdateCashOut = `-- name: UpdateCashOut :exec const UpdateCashOut = `-- name: UpdateCashOut :exec
UPDATE bets SET cashed_out = $2, updated_at = CURRENT_TIMESTAMP WHERE id = $1 UPDATE bets
SET cashed_out = $2,
updated_at = CURRENT_TIMESTAMP
WHERE id = $1
` `
type UpdateCashOutParams struct { type UpdateCashOutParams struct {

View File

@ -12,7 +12,16 @@ import (
) )
const CreateBranch = `-- name: CreateBranch :one const CreateBranch = `-- name: CreateBranch :one
INSERT INTO branches (name, location, wallet_id, branch_manager_id, company_id, is_self_owned) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at INSERT INTO branches (
name,
location,
wallet_id,
branch_manager_id,
company_id,
is_self_owned
)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at
` `
type CreateBranchParams struct { type CreateBranchParams struct {
@ -48,8 +57,28 @@ func (q *Queries) CreateBranch(ctx context.Context, arg CreateBranchParams) (Bra
return i, err return i, err
} }
const CreateBranchCashier = `-- name: CreateBranchCashier :one
INSERT INTO branch_cashiers (user_id, branch_id)
VALUES ($1, $2)
RETURNING id, user_id, branch_id
`
type CreateBranchCashierParams struct {
UserID int64
BranchID int64
}
func (q *Queries) CreateBranchCashier(ctx context.Context, arg CreateBranchCashierParams) (BranchCashier, error) {
row := q.db.QueryRow(ctx, CreateBranchCashier, arg.UserID, arg.BranchID)
var i BranchCashier
err := row.Scan(&i.ID, &i.UserID, &i.BranchID)
return i, err
}
const CreateBranchOperation = `-- name: CreateBranchOperation :one const CreateBranchOperation = `-- name: CreateBranchOperation :one
INSERT INTO branch_operations (operation_id, branch_id) VALUES ($1, $2) RETURNING id, operation_id, branch_id, created_at, updated_at INSERT INTO branch_operations (operation_id, branch_id)
VALUES ($1, $2)
RETURNING id, operation_id, branch_id, created_at, updated_at
` `
type CreateBranchOperationParams struct { type CreateBranchOperationParams struct {
@ -71,7 +100,9 @@ func (q *Queries) CreateBranchOperation(ctx context.Context, arg CreateBranchOpe
} }
const CreateSupportedOperation = `-- name: CreateSupportedOperation :one const CreateSupportedOperation = `-- name: CreateSupportedOperation :one
INSERT INTO supported_operations (name, description) VALUES ($1, $2) RETURNING id, name, description INSERT INTO supported_operations (name, description)
VALUES ($1, $2)
RETURNING id, name, description
` `
type CreateSupportedOperationParams struct { type CreateSupportedOperationParams struct {
@ -87,7 +118,8 @@ func (q *Queries) CreateSupportedOperation(ctx context.Context, arg CreateSuppor
} }
const DeleteBranch = `-- name: DeleteBranch :exec const DeleteBranch = `-- name: DeleteBranch :exec
DELETE FROM branches WHERE id = $1 DELETE FROM branches
WHERE id = $1
` `
func (q *Queries) DeleteBranch(ctx context.Context, id int64) error { func (q *Queries) DeleteBranch(ctx context.Context, id int64) error {
@ -95,8 +127,20 @@ func (q *Queries) DeleteBranch(ctx context.Context, id int64) error {
return err return err
} }
const DeleteBranchCashier = `-- name: DeleteBranchCashier :exec
DELETE FROM branch_cashiers
WHERE user_id = $1
`
func (q *Queries) DeleteBranchCashier(ctx context.Context, userID int64) error {
_, err := q.db.Exec(ctx, DeleteBranchCashier, userID)
return err
}
const DeleteBranchOperation = `-- name: DeleteBranchOperation :exec const DeleteBranchOperation = `-- name: DeleteBranchOperation :exec
DELETE FROM branch_operations WHERE operation_id = $1 AND branch_id = $2 DELETE FROM branch_operations
WHERE operation_id = $1
AND branch_id = $2
` `
type DeleteBranchOperationParams struct { type DeleteBranchOperationParams struct {
@ -110,7 +154,8 @@ func (q *Queries) DeleteBranchOperation(ctx context.Context, arg DeleteBranchOpe
} }
const GetAllBranches = `-- name: GetAllBranches :many const GetAllBranches = `-- name: GetAllBranches :many
SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number
FROM branch_details
` `
func (q *Queries) GetAllBranches(ctx context.Context) ([]BranchDetail, error) { func (q *Queries) GetAllBranches(ctx context.Context) ([]BranchDetail, error) {
@ -145,8 +190,49 @@ func (q *Queries) GetAllBranches(ctx context.Context) ([]BranchDetail, error) {
return items, nil return items, nil
} }
const GetAllCashiers = `-- name: GetAllCashiers :many
SELECT users.id, users.first_name, users.last_name, users.email, users.phone_number, users.role, users.password, users.email_verified, users.phone_verified, users.created_at, users.updated_at, users.suspended_at, users.suspended
FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id
`
func (q *Queries) GetAllCashiers(ctx context.Context) ([]User, error) {
rows, err := q.db.Query(ctx, GetAllCashiers)
if err != nil {
return nil, err
}
defer rows.Close()
var items []User
for rows.Next() {
var i User
if err := rows.Scan(
&i.ID,
&i.FirstName,
&i.LastName,
&i.Email,
&i.PhoneNumber,
&i.Role,
&i.Password,
&i.EmailVerified,
&i.PhoneVerified,
&i.CreatedAt,
&i.UpdatedAt,
&i.SuspendedAt,
&i.Suspended,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetAllSupportedOperations = `-- name: GetAllSupportedOperations :many const GetAllSupportedOperations = `-- name: GetAllSupportedOperations :many
SELECT id, name, description FROM supported_operations SELECT id, name, description
FROM supported_operations
` `
func (q *Queries) GetAllSupportedOperations(ctx context.Context) ([]SupportedOperation, error) { func (q *Queries) GetAllSupportedOperations(ctx context.Context) ([]SupportedOperation, error) {
@ -169,8 +255,34 @@ func (q *Queries) GetAllSupportedOperations(ctx context.Context) ([]SupportedOpe
return items, nil return items, nil
} }
const GetBranchByCashier = `-- name: GetBranchByCashier :one
SELECT branches.id, branches.name, branches.location, branches.wallet_id, branches.branch_manager_id, branches.company_id, branches.is_self_owned, branches.created_at, branches.updated_at
FROM branch_cashiers
JOIN branches ON branch_cashiers.branch_id = branches.id
WHERE branch_cashiers.user_id = $1
`
func (q *Queries) GetBranchByCashier(ctx context.Context, userID int64) (Branch, error) {
row := q.db.QueryRow(ctx, GetBranchByCashier, userID)
var i Branch
err := row.Scan(
&i.ID,
&i.Name,
&i.Location,
&i.WalletID,
&i.BranchManagerID,
&i.CompanyID,
&i.IsSelfOwned,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetBranchByCompanyID = `-- name: GetBranchByCompanyID :many const GetBranchByCompanyID = `-- name: GetBranchByCompanyID :many
SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE company_id = $1 SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number
FROM branch_details
WHERE company_id = $1
` `
func (q *Queries) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]BranchDetail, error) { func (q *Queries) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]BranchDetail, error) {
@ -206,7 +318,9 @@ func (q *Queries) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]
} }
const GetBranchByID = `-- name: GetBranchByID :one const GetBranchByID = `-- name: GetBranchByID :one
SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE id = $1 SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number
FROM branch_details
WHERE id = $1
` `
func (q *Queries) GetBranchByID(ctx context.Context, id int64) (BranchDetail, error) { func (q *Queries) GetBranchByID(ctx context.Context, id int64) (BranchDetail, error) {
@ -229,7 +343,9 @@ func (q *Queries) GetBranchByID(ctx context.Context, id int64) (BranchDetail, er
} }
const GetBranchByManagerID = `-- name: GetBranchByManagerID :many const GetBranchByManagerID = `-- name: GetBranchByManagerID :many
SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE branch_manager_id = $1 SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number
FROM branch_details
WHERE branch_manager_id = $1
` `
func (q *Queries) GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]BranchDetail, error) { func (q *Queries) GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]BranchDetail, error) {
@ -265,9 +381,11 @@ func (q *Queries) GetBranchByManagerID(ctx context.Context, branchManagerID int6
} }
const GetBranchOperations = `-- name: GetBranchOperations :many const GetBranchOperations = `-- name: GetBranchOperations :many
SELECT branch_operations.id, branch_operations.operation_id, branch_operations.branch_id, branch_operations.created_at, branch_operations.updated_at, supported_operations.name, supported_operations.description SELECT branch_operations.id, branch_operations.operation_id, branch_operations.branch_id, branch_operations.created_at, branch_operations.updated_at,
supported_operations.name,
supported_operations.description
FROM branch_operations FROM branch_operations
JOIN supported_operations ON branch_operations.operation_id = supported_operations.id JOIN supported_operations ON branch_operations.operation_id = supported_operations.id
WHERE branch_operations.branch_id = $1 WHERE branch_operations.branch_id = $1
` `
@ -309,8 +427,51 @@ func (q *Queries) GetBranchOperations(ctx context.Context, branchID int64) ([]Ge
return items, nil return items, nil
} }
const GetCashiersByBranch = `-- name: GetCashiersByBranch :many
SELECT users.id, users.first_name, users.last_name, users.email, users.phone_number, users.role, users.password, users.email_verified, users.phone_verified, users.created_at, users.updated_at, users.suspended_at, users.suspended
FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id
WHERE branch_cashiers.branch_id = $1
`
func (q *Queries) GetCashiersByBranch(ctx context.Context, branchID int64) ([]User, error) {
rows, err := q.db.Query(ctx, GetCashiersByBranch, branchID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []User
for rows.Next() {
var i User
if err := rows.Scan(
&i.ID,
&i.FirstName,
&i.LastName,
&i.Email,
&i.PhoneNumber,
&i.Role,
&i.Password,
&i.EmailVerified,
&i.PhoneVerified,
&i.CreatedAt,
&i.UpdatedAt,
&i.SuspendedAt,
&i.Suspended,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const SearchBranchByName = `-- name: SearchBranchByName :many const SearchBranchByName = `-- name: SearchBranchByName :many
SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE name ILIKE '%' || $1 || '%' SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number
FROM branch_details
WHERE name ILIKE '%' || $1 || '%'
` `
func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text) ([]BranchDetail, error) { func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text) ([]BranchDetail, error) {
@ -346,7 +507,14 @@ func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text)
} }
const UpdateBranch = `-- name: UpdateBranch :one const UpdateBranch = `-- name: UpdateBranch :one
UPDATE branches SET name = $1, location = $2, branch_manager_id = $3, company_id = $4, is_self_owned = $5 WHERE id = $6 RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at UPDATE branches
SET name = $1,
location = $2,
branch_manager_id = $3,
company_id = $4,
is_self_owned = $5
WHERE id = $6
RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at
` `
type UpdateBranchParams struct { type UpdateBranchParams struct {

78
gen/db/copyfrom.go Normal file
View File

@ -0,0 +1,78 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
// source: copyfrom.go
package dbgen
import (
"context"
)
// iteratorForCreateBetOutcome implements pgx.CopyFromSource.
type iteratorForCreateBetOutcome struct {
rows []CreateBetOutcomeParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateBetOutcome) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateBetOutcome) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].BetID,
r.rows[0].EventID,
r.rows[0].OddID,
}, nil
}
func (r iteratorForCreateBetOutcome) Err() error {
return nil
}
func (q *Queries) CreateBetOutcome(ctx context.Context, arg []CreateBetOutcomeParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"bet_outcomes"}, []string{"bet_id", "event_id", "odd_id"}, &iteratorForCreateBetOutcome{rows: arg})
}
// iteratorForCreateTicketOutcome implements pgx.CopyFromSource.
type iteratorForCreateTicketOutcome struct {
rows []CreateTicketOutcomeParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateTicketOutcome) Next() bool {
if len(r.rows) == 0 {
return false
}
if !r.skippedFirstNextCall {
r.skippedFirstNextCall = true
return true
}
r.rows = r.rows[1:]
return len(r.rows) > 0
}
func (r iteratorForCreateTicketOutcome) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].TicketID,
r.rows[0].EventID,
r.rows[0].OddID,
}, nil
}
func (r iteratorForCreateTicketOutcome) Err() error {
return nil
}
func (q *Queries) CreateTicketOutcome(ctx context.Context, arg []CreateTicketOutcomeParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"ticket_outcomes"}, []string{"ticket_id", "event_id", "odd_id"}, &iteratorForCreateTicketOutcome{rows: arg})
}

View File

@ -15,6 +15,7 @@ type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error) Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row QueryRow(context.Context, string, ...interface{}) pgx.Row
CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error)
} }
func New(db DBTX) *Queries { func New(db DBTX) *Queries {

View File

@ -24,6 +24,30 @@ type Bet struct {
IsShopBet bool IsShopBet bool
} }
type BetOutcome struct {
ID int64
BetID int64
EventID int64
OddID int64
}
type BetWithOutcome struct {
ID int64
Amount int64
TotalOdds float32
Status int32
FullName string
PhoneNumber string
BranchID pgtype.Int8
UserID pgtype.Int8
CashedOut bool
CashoutID string
CreatedAt pgtype.Timestamp
UpdatedAt pgtype.Timestamp
IsShopBet bool
Outcomes []BetOutcome
}
type Branch struct { type Branch struct {
ID int64 ID int64
Name string Name string
@ -36,6 +60,12 @@ type Branch struct {
UpdatedAt pgtype.Timestamp UpdatedAt pgtype.Timestamp
} }
type BranchCashier struct {
ID int64
UserID int64
BranchID int64
}
type BranchDetail struct { type BranchDetail struct {
ID int64 ID int64
Name string Name string
@ -120,6 +150,22 @@ type Ticket struct {
UpdatedAt pgtype.Timestamp UpdatedAt pgtype.Timestamp
} }
type TicketOutcome struct {
ID int64
TicketID int64
EventID int64
OddID int64
}
type TicketWithOutcome struct {
ID int64
Amount pgtype.Int8
TotalOdds float32
CreatedAt pgtype.Timestamp
UpdatedAt pgtype.Timestamp
Outcomes []TicketOutcome
}
type Transaction struct { type Transaction struct {
ID int64 ID int64
Amount int64 Amount int64

View File

@ -35,8 +35,15 @@ func (q *Queries) CreateTicket(ctx context.Context, arg CreateTicketParams) (Tic
return i, err return i, err
} }
type CreateTicketOutcomeParams struct {
TicketID int64
EventID int64
OddID int64
}
const DeleteOldTickets = `-- name: DeleteOldTickets :exec const DeleteOldTickets = `-- name: DeleteOldTickets :exec
Delete from tickets where created_at < now() - interval '1 day' Delete from tickets
where created_at < now() - interval '1 day'
` `
func (q *Queries) DeleteOldTickets(ctx context.Context) error { func (q *Queries) DeleteOldTickets(ctx context.Context) error {
@ -45,7 +52,8 @@ func (q *Queries) DeleteOldTickets(ctx context.Context) error {
} }
const DeleteTicket = `-- name: DeleteTicket :exec const DeleteTicket = `-- name: DeleteTicket :exec
DELETE FROM tickets WHERE id = $1 DELETE FROM tickets
WHERE id = $1
` `
func (q *Queries) DeleteTicket(ctx context.Context, id int64) error { func (q *Queries) DeleteTicket(ctx context.Context, id int64) error {
@ -53,25 +61,37 @@ func (q *Queries) DeleteTicket(ctx context.Context, id int64) error {
return err return err
} }
const GetAllTickets = `-- name: GetAllTickets :many const DeleteTicketOutcome = `-- name: DeleteTicketOutcome :exec
SELECT id, amount, total_odds, created_at, updated_at FROM tickets Delete from ticket_outcomes
where ticket_id = $1
` `
func (q *Queries) GetAllTickets(ctx context.Context) ([]Ticket, error) { func (q *Queries) DeleteTicketOutcome(ctx context.Context, ticketID int64) error {
_, err := q.db.Exec(ctx, DeleteTicketOutcome, ticketID)
return err
}
const GetAllTickets = `-- name: GetAllTickets :many
SELECT id, amount, total_odds, created_at, updated_at, outcomes
FROM ticket_with_outcomes
`
func (q *Queries) GetAllTickets(ctx context.Context) ([]TicketWithOutcome, error) {
rows, err := q.db.Query(ctx, GetAllTickets) rows, err := q.db.Query(ctx, GetAllTickets)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close() defer rows.Close()
var items []Ticket var items []TicketWithOutcome
for rows.Next() { for rows.Next() {
var i Ticket var i TicketWithOutcome
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.TotalOdds, &i.TotalOdds,
&i.CreatedAt, &i.CreatedAt,
&i.UpdatedAt, &i.UpdatedAt,
&i.Outcomes,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -84,18 +104,52 @@ func (q *Queries) GetAllTickets(ctx context.Context) ([]Ticket, error) {
} }
const GetTicketByID = `-- name: GetTicketByID :one const GetTicketByID = `-- name: GetTicketByID :one
SELECT id, amount, total_odds, created_at, updated_at FROM tickets WHERE id = $1 SELECT id, amount, total_odds, created_at, updated_at, outcomes
FROM ticket_with_outcomes
WHERE id = $1
` `
func (q *Queries) GetTicketByID(ctx context.Context, id int64) (Ticket, error) { func (q *Queries) GetTicketByID(ctx context.Context, id int64) (TicketWithOutcome, error) {
row := q.db.QueryRow(ctx, GetTicketByID, id) row := q.db.QueryRow(ctx, GetTicketByID, id)
var i Ticket var i TicketWithOutcome
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.TotalOdds, &i.TotalOdds,
&i.CreatedAt, &i.CreatedAt,
&i.UpdatedAt, &i.UpdatedAt,
&i.Outcomes,
) )
return i, err return i, err
} }
const GetTicketOutcome = `-- name: GetTicketOutcome :many
SELECT id, ticket_id, event_id, odd_id
FROM ticket_outcomes
WHERE ticket_id = $1
`
func (q *Queries) GetTicketOutcome(ctx context.Context, ticketID int64) ([]TicketOutcome, error) {
rows, err := q.db.Query(ctx, GetTicketOutcome, ticketID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []TicketOutcome
for rows.Next() {
var i TicketOutcome
if err := rows.Scan(
&i.ID,
&i.TicketID,
&i.EventID,
&i.OddID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View File

@ -12,9 +12,18 @@ import (
) )
const CheckPhoneEmailExist = `-- name: CheckPhoneEmailExist :one const CheckPhoneEmailExist = `-- name: CheckPhoneEmailExist :one
SELECT SELECT EXISTS (
EXISTS (SELECT 1 FROM users WHERE users.phone_number = $1 AND users.phone_number IS NOT NULL) AS phone_exists, SELECT 1
EXISTS (SELECT 1 FROM users WHERE users.email = $2 AND users.email IS NOT NULL) AS email_exists FROM users
WHERE users.phone_number = $1
AND users.phone_number IS NOT NULL
) AS phone_exists,
EXISTS (
SELECT 1
FROM users
WHERE users.email = $2
AND users.email IS NOT NULL
) AS email_exists
` `
type CheckPhoneEmailExistParams struct { type CheckPhoneEmailExistParams struct {
@ -35,10 +44,29 @@ func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailE
} }
const CreateUser = `-- name: CreateUser :one const CreateUser = `-- name: CreateUser :one
INSERT INTO users (
INSERT INTO users (first_name, last_name, email, phone_number, role, password, email_verified, phone_verified, created_at, updated_at) first_name,
last_name,
email,
phone_number,
role,
password,
email_verified,
phone_verified,
created_at,
updated_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at RETURNING id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
` `
type CreateUserParams struct { type CreateUserParams struct {
@ -107,7 +135,16 @@ func (q *Queries) DeleteUser(ctx context.Context, id int64) error {
} }
const GetAllUsers = `-- name: GetAllUsers :many const GetAllUsers = `-- name: GetAllUsers :many
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
` `
@ -156,7 +193,16 @@ func (q *Queries) GetAllUsers(ctx context.Context) ([]GetAllUsersRow, error) {
} }
const GetUserByEmail = `-- name: GetUserByEmail :one const GetUserByEmail = `-- name: GetUserByEmail :one
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE email = $1 WHERE email = $1
` `
@ -220,7 +266,16 @@ func (q *Queries) GetUserByID(ctx context.Context, id int64) (User, error) {
} }
const GetUserByPhone = `-- name: GetUserByPhone :one const GetUserByPhone = `-- name: GetUserByPhone :one
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE phone_number = $1 WHERE phone_number = $1
` `
@ -257,7 +312,16 @@ func (q *Queries) GetUserByPhone(ctx context.Context, phoneNumber pgtype.Text) (
} }
const SearchUserByNameOrPhone = `-- name: SearchUserByNameOrPhone :many const SearchUserByNameOrPhone = `-- name: SearchUserByNameOrPhone :many
SELECT id, first_name, last_name, email, phone_number, role, email_verified, phone_verified, created_at, updated_at SELECT id,
first_name,
last_name,
email,
phone_number,
role,
email_verified,
phone_verified,
created_at,
updated_at
FROM users FROM users
WHERE first_name ILIKE '%' || $1 || '%' WHERE first_name ILIKE '%' || $1 || '%'
OR last_name ILIKE '%' || $1 || '%' OR last_name ILIKE '%' || $1 || '%'
@ -310,8 +374,12 @@ func (q *Queries) SearchUserByNameOrPhone(ctx context.Context, dollar_1 pgtype.T
const UpdatePassword = `-- name: UpdatePassword :exec const UpdatePassword = `-- name: UpdatePassword :exec
UPDATE users UPDATE users
SET password = $1, updated_at = $4 SET password = $1,
WHERE (email = $2 OR phone_number = $3) updated_at = $4
WHERE (
email = $2
OR phone_number = $3
)
` `
type UpdatePasswordParams struct { type UpdatePasswordParams struct {
@ -333,7 +401,12 @@ func (q *Queries) UpdatePassword(ctx context.Context, arg UpdatePasswordParams)
const UpdateUser = `-- name: UpdateUser :exec const UpdateUser = `-- name: UpdateUser :exec
UPDATE users UPDATE users
SET first_name = $1, last_name = $2, email = $3, phone_number = $4, role = $5, updated_at = $6 SET first_name = $1,
last_name = $2,
email = $3,
phone_number = $4,
role = $5,
updated_at = $6
WHERE id = $7 WHERE id = $7
` `

View File

@ -12,7 +12,14 @@ import (
) )
const CreateCustomerWallet = `-- name: CreateCustomerWallet :one const CreateCustomerWallet = `-- name: CreateCustomerWallet :one
INSERT INTO customer_wallets (customer_id, company_id, regular_wallet_id, static_wallet_id) VALUES ($1, $2, $3, $4) RETURNING id, customer_id, company_id, regular_wallet_id, static_wallet_id, created_at, updated_at INSERT INTO customer_wallets (
customer_id,
company_id,
regular_wallet_id,
static_wallet_id
)
VALUES ($1, $2, $3, $4)
RETURNING id, customer_id, company_id, regular_wallet_id, static_wallet_id, created_at, updated_at
` `
type CreateCustomerWalletParams struct { type CreateCustomerWalletParams struct {
@ -43,7 +50,14 @@ func (q *Queries) CreateCustomerWallet(ctx context.Context, arg CreateCustomerWa
} }
const CreateWallet = `-- name: CreateWallet :one const CreateWallet = `-- name: CreateWallet :one
INSERT INTO wallets (is_withdraw, is_bettable, is_transferable, user_id) VALUES ($1, $2, $3, $4) RETURNING id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at INSERT INTO wallets (
is_withdraw,
is_bettable,
is_transferable,
user_id
)
VALUES ($1, $2, $3, $4)
RETURNING id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at
` `
type CreateWalletParams struct { type CreateWalletParams struct {
@ -75,8 +89,68 @@ func (q *Queries) CreateWallet(ctx context.Context, arg CreateWalletParams) (Wal
return i, err return i, err
} }
const GetAllBranchWallets = `-- name: GetAllBranchWallets :many
SELECT wallets.id,
wallets.balance,
wallets.is_active,
wallets.updated_at,
wallets.created_at,
branches.name,
branches.location,
branches.branch_manager_id,
branches.company_id,
branches.is_self_owned
FROM branches
JOIN wallets ON branches.wallet_id = wallets.id
`
type GetAllBranchWalletsRow struct {
ID int64
Balance int64
IsActive bool
UpdatedAt pgtype.Timestamp
CreatedAt pgtype.Timestamp
Name string
Location string
BranchManagerID int64
CompanyID int64
IsSelfOwned bool
}
func (q *Queries) GetAllBranchWallets(ctx context.Context) ([]GetAllBranchWalletsRow, error) {
rows, err := q.db.Query(ctx, GetAllBranchWallets)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetAllBranchWalletsRow
for rows.Next() {
var i GetAllBranchWalletsRow
if err := rows.Scan(
&i.ID,
&i.Balance,
&i.IsActive,
&i.UpdatedAt,
&i.CreatedAt,
&i.Name,
&i.Location,
&i.BranchManagerID,
&i.CompanyID,
&i.IsSelfOwned,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetAllWallets = `-- name: GetAllWallets :many const GetAllWallets = `-- name: GetAllWallets :many
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at FROM wallets SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at
FROM wallets
` `
func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) { func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
@ -110,8 +184,7 @@ func (q *Queries) GetAllWallets(ctx context.Context) ([]Wallet, error) {
} }
const GetCustomerWallet = `-- name: GetCustomerWallet :one const GetCustomerWallet = `-- name: GetCustomerWallet :one
SELECT SELECT cw.id,
cw.id,
cw.customer_id, cw.customer_id,
cw.company_id, cw.company_id,
rw.id AS regular_id, rw.id AS regular_id,
@ -122,9 +195,10 @@ SELECT
sw.updated_at as static_updated_at, sw.updated_at as static_updated_at,
cw.created_at cw.created_at
FROM customer_wallets cw FROM customer_wallets cw
JOIN wallets rw ON cw.regular_wallet_id = rw.id JOIN wallets rw ON cw.regular_wallet_id = rw.id
JOIN wallets sw ON cw.static_wallet_id = sw.id JOIN wallets sw ON cw.static_wallet_id = sw.id
WHERE cw.customer_id = $1 AND cw.company_id = $2 WHERE cw.customer_id = $1
AND cw.company_id = $2
` `
type GetCustomerWalletParams struct { type GetCustomerWalletParams struct {
@ -164,7 +238,9 @@ func (q *Queries) GetCustomerWallet(ctx context.Context, arg GetCustomerWalletPa
} }
const GetWalletByID = `-- name: GetWalletByID :one const GetWalletByID = `-- name: GetWalletByID :one
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at FROM wallets WHERE id = $1 SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at
FROM wallets
WHERE id = $1
` `
func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) { func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
@ -185,7 +261,9 @@ func (q *Queries) GetWalletByID(ctx context.Context, id int64) (Wallet, error) {
} }
const GetWalletByUserID = `-- name: GetWalletByUserID :many const GetWalletByUserID = `-- name: GetWalletByUserID :many
SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at FROM wallets WHERE user_id = $1 SELECT id, balance, is_withdraw, is_bettable, is_transferable, user_id, is_active, created_at, updated_at
FROM wallets
WHERE user_id = $1
` `
func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet, error) { func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet, error) {
@ -219,7 +297,10 @@ func (q *Queries) GetWalletByUserID(ctx context.Context, userID int64) ([]Wallet
} }
const UpdateBalance = `-- name: UpdateBalance :exec const UpdateBalance = `-- name: UpdateBalance :exec
UPDATE wallets SET balance = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2 UPDATE wallets
SET balance = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2
` `
type UpdateBalanceParams struct { type UpdateBalanceParams struct {
@ -233,7 +314,10 @@ func (q *Queries) UpdateBalance(ctx context.Context, arg UpdateBalanceParams) er
} }
const UpdateWalletActive = `-- name: UpdateWalletActive :exec const UpdateWalletActive = `-- name: UpdateWalletActive :exec
UPDATE wallets SET is_active = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2 UPDATE wallets
SET is_active = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2
` `
type UpdateWalletActiveParams struct { type UpdateWalletActiveParams struct {

View File

@ -1,5 +1,18 @@
package domain package domain
type BetOutcome struct {
ID int64
BetID int64
EventID int64
OddID int64
}
type CreateBetOutcome struct {
BetID int64
EventID int64
OddID int64
}
type BetStatus int type BetStatus int
const ( const (
@ -13,7 +26,6 @@ const (
// 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
Outcomes []Outcome
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
Status BetStatus Status BetStatus
@ -26,8 +38,22 @@ type Bet struct {
CashoutID string CashoutID string
} }
type GetBet struct {
ID int64
Amount Currency
TotalOdds float32
Status BetStatus
FullName string
PhoneNumber string
BranchID ValidInt64 // Can Be Nullable
UserID ValidInt64 // Can Be Nullable
IsShopBet bool
CashedOut bool
CashoutID string
Outcomes []BetOutcome
}
type CreateBet struct { type CreateBet struct {
Outcomes []int64
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
Status BetStatus Status BetStatus

View File

@ -37,3 +37,5 @@ func (m Currency) String() string {
return fmt.Sprintf("$%.2f", x) return fmt.Sprintf("$%.2f", x)
} }

View File

@ -1,15 +1,33 @@
package domain package domain
type TicketOutcome struct {
ID int64
TicketID int64
EventID int64
OddID int64
}
type CreateTicketOutcome struct {
TicketID int64
EventID int64
OddID int64
}
// ID will serve as the fast code since this doesn't need to be secure // ID will serve as the fast code since this doesn't need to be secure
type Ticket struct { type Ticket struct {
ID int64 ID int64
Outcomes []Outcome
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
} }
type GetTicket struct {
ID int64
Amount Currency
TotalOdds float32
Outcomes []TicketOutcome
}
type CreateTicket struct { type CreateTicket struct {
Outcomes []int64
Amount Currency Amount Currency
TotalOdds float32 TotalOdds float32
} }

View File

@ -42,7 +42,6 @@ type RegisterUserReq struct {
OtpMedium OtpMedium OtpMedium OtpMedium
} }
type CreateUserReq struct { type CreateUserReq struct {
BranchID int64
FirstName string FirstName string
LastName string LastName string
Email string Email string

View File

@ -3,23 +3,23 @@ package domain
import "time" import "time"
type Wallet struct { type Wallet struct {
ID int64 ID int64
Balance Currency Balance Currency
IsWithdraw bool IsWithdraw bool
IsBettable bool IsBettable bool
IsTransferable bool IsTransferable bool
IsActive bool IsActive bool
UserID int64 UserID int64
UpdatedAt time.Time UpdatedAt time.Time
CreatedAt time.Time CreatedAt time.Time
} }
type CustomerWallet struct { type CustomerWallet struct {
ID int64 ID int64
RegularID int64 RegularID int64
StaticID int64 StaticID int64
CustomerID int64 CustomerID int64
CompanyID int64 CompanyID int64
} }
type GetCustomerWallet struct { type GetCustomerWallet struct {
ID int64 ID int64
@ -34,11 +34,24 @@ type GetCustomerWallet struct {
CreatedAt time.Time CreatedAt time.Time
} }
type BranchWallet struct {
ID int64
Balance Currency
IsActive bool
Name string
Location string
BranchManagerID int64
CompanyID int64
IsSelfOwned bool
UpdatedAt time.Time
CreatedAt time.Time
}
type CreateWallet struct { type CreateWallet struct {
IsWithdraw bool IsWithdraw bool
IsBettable bool IsBettable bool
IsTransferable bool IsTransferable bool
UserID int64 UserID int64
} }
type CreateCustomerWallet struct { type CreateCustomerWallet struct {

View File

@ -30,6 +30,39 @@ func convertDBBet(bet dbgen.Bet) domain.Bet {
} }
} }
func convertDBBetOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, len(bet.Outcomes))
for _, outcome := range bet.Outcomes {
outcomes = append(outcomes, domain.BetOutcome{
ID: outcome.ID,
BetID: outcome.BetID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
}
return domain.GetBet{
ID: bet.ID,
Amount: domain.Currency(bet.Amount),
TotalOdds: bet.TotalOdds,
Status: domain.BetStatus(bet.Status),
FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber,
BranchID: domain.ValidInt64{
Value: bet.BranchID.Int64,
Valid: bet.BranchID.Valid,
},
UserID: domain.ValidInt64{
Value: bet.UserID.Int64,
Valid: bet.UserID.Valid,
},
IsShopBet: bet.IsShopBet,
CashedOut: bet.CashedOut,
CashoutID: bet.CashoutID,
Outcomes: outcomes,
}
}
func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams { func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams {
return dbgen.CreateBetParams{ return dbgen.CreateBetParams{
Amount: int64(bet.Amount), Amount: int64(bet.Amount),
@ -51,7 +84,6 @@ func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams {
} }
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) { func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
newBet, err := s.queries.CreateBet(ctx, convertCreateBet(bet)) newBet, err := s.queries.CreateBet(ctx, convertCreateBet(bet))
if err != nil { if err != nil {
return domain.Bet{}, err return domain.Bet{}, err
@ -60,25 +92,62 @@ func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet
} }
func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.Bet, error) { func (s *Store) CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBetOutcome) (int64, error) {
bet, err := s.queries.GetBetByID(ctx, id) var dbParams []dbgen.CreateBetOutcomeParams = make([]dbgen.CreateBetOutcomeParams, 0, len(outcomes))
for _, outcome := range outcomes {
dbParams = append(dbParams, dbgen.CreateBetOutcomeParams{
BetID: outcome.BetID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
}
rows, err := s.queries.CreateBetOutcome(ctx, dbParams)
if err != nil { if err != nil {
return domain.Bet{}, err return rows, err
} }
return convertDBBet(bet), nil return rows, nil
} }
func (s *Store) GetAllBets(ctx context.Context) ([]domain.Bet, error) { func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) {
bet, err := s.queries.GetBetByID(ctx, id)
if err != nil {
return domain.GetBet{}, err
}
return convertDBBetOutcomes(bet), nil
}
func (s *Store) GetAllBets(ctx context.Context) ([]domain.GetBet, error) {
bets, err := s.queries.GetAllBets(ctx) bets, err := s.queries.GetAllBets(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var result []domain.Bet = make([]domain.Bet, 0, len(bets)) var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
for _, bet := range bets { for _, bet := range bets {
result = append(result, convertDBBet(bet)) result = append(result, convertDBBetOutcomes(bet))
}
return result, nil
}
func (s *Store) GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error) {
bets, err := s.queries.GetBetByBranchID(ctx, pgtype.Int8{
Int64: BranchID,
Valid: true,
})
if err != nil {
return nil, err
}
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
for _, bet := range bets {
result = append(result, convertDBBetOutcomes(bet))
} }
return result, nil return result, nil

View File

@ -154,6 +154,18 @@ func (s *Store) CreateSupportedOperation(ctx context.Context, supportedOperation
}, nil }, nil
} }
func (s *Store) CreateBranchCashier(ctx context.Context, branchID int64, userID int64) error {
_, err := s.queries.CreateBranchCashier(ctx, dbgen.CreateBranchCashierParams{
UserID: userID,
BranchID: branchID,
})
if err != nil {
return err
}
return nil
}
func (s *Store) GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error) { func (s *Store) GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error) {
dbOperations, err := s.queries.GetAllSupportedOperations(ctx) dbOperations, err := s.queries.GetAllSupportedOperations(ctx)
if err != nil { if err != nil {
@ -188,6 +200,16 @@ func (s *Store) GetBranchOperations(ctx context.Context, branchID int64) ([]doma
return branchOperations, nil return branchOperations, nil
} }
func (s *Store) GetBranchByCashier(ctx context.Context, userID int64) (domain.Branch, error) {
branch, err := s.queries.GetBranchByCashier(ctx, userID)
if err != nil {
return domain.Branch{}, err
}
return convertDBBranch(branch), err
}
func (s *Store) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error { func (s *Store) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error {
err := s.queries.DeleteBranchOperation(ctx, dbgen.DeleteBranchOperationParams{ err := s.queries.DeleteBranchOperation(ctx, dbgen.DeleteBranchOperationParams{
BranchID: branchID, BranchID: branchID,
@ -195,3 +217,8 @@ func (s *Store) DeleteBranchOperation(ctx context.Context, branchID int64, opera
}) })
return err return err
} }
func (s *Store) DeleteBranchCashier(ctx context.Context, userID int64) error {
return s.queries.DeleteBranchCashier(ctx, userID)
}

View File

@ -14,6 +14,27 @@ func convertDBTicket(ticket dbgen.Ticket) domain.Ticket {
Amount: domain.Currency(ticket.Amount.Int64), Amount: domain.Currency(ticket.Amount.Int64),
TotalOdds: ticket.TotalOdds, TotalOdds: ticket.TotalOdds,
} }
}
func convertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) domain.GetTicket {
var outcomes []domain.TicketOutcome = make([]domain.TicketOutcome, 0, len(ticket.Outcomes))
for _, outcome := range ticket.Outcomes {
outcomes = append(outcomes, domain.TicketOutcome{
ID: outcome.ID,
TicketID: outcome.TicketID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
}
return domain.GetTicket{
ID: ticket.ID,
Amount: domain.Currency(ticket.Amount.Int64),
TotalOdds: ticket.TotalOdds,
Outcomes: outcomes,
}
} }
func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams { func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams {
@ -35,25 +56,45 @@ func (s *Store) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (d
} }
func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error) { func (s *Store) CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error) {
ticket, err := s.queries.GetTicketByID(ctx, id)
if err != nil { var dbParams []dbgen.CreateTicketOutcomeParams = make([]dbgen.CreateTicketOutcomeParams, 0, len(outcomes))
return domain.Ticket{}, err for _, outcome := range outcomes {
dbParams = append(dbParams, dbgen.CreateTicketOutcomeParams{
TicketID: outcome.TicketID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
} }
return convertDBTicket(ticket), nil rows, err := s.queries.CreateTicketOutcome(ctx, dbParams)
if err != nil {
return rows, err
}
return rows, nil
} }
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.Ticket, error) { func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error) {
ticket, err := s.queries.GetTicketByID(ctx, id)
if err != nil {
return domain.GetTicket{}, err
}
return convertDBTicketOutcomes(ticket), nil
}
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
tickets, err := s.queries.GetAllTickets(ctx) tickets, err := s.queries.GetAllTickets(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var result []domain.Ticket = make([]domain.Ticket, 0, len(tickets)) var result []domain.GetTicket = make([]domain.GetTicket, 0, len(tickets))
for _, ticket := range tickets { for _, ticket := range tickets {
result = append(result, convertDBTicket(ticket)) result = append(result, convertDBTicketOutcomes(ticket))
} }
return result, nil return result, nil

View File

@ -102,6 +102,44 @@ func (s *Store) GetAllUsers(ctx context.Context, filter user.Filter) ([]domain.U
return userList, nil return userList, nil
} }
func (s *Store) GetAllCashiers(ctx context.Context) ([]domain.User, error) {
users, err := s.queries.GetAllCashiers(ctx)
if err != nil {
return nil, err
}
userList := make([]domain.User, len(users))
for i, user := range users {
userList[i] = domain.User{
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email.String,
PhoneNumber: user.PhoneNumber.String,
Role: domain.Role(user.Role),
}
}
return userList, nil
}
func (s *Store) GetCashiersByBranch(ctx context.Context, branchID int64) ([]domain.User, error) {
users, err := s.queries.GetCashiersByBranch(ctx, branchID)
if err != nil {
return nil, err
}
userList := make([]domain.User, len(users))
for i, user := range users {
userList[i] = domain.User{
ID: user.ID,
FirstName: user.FirstName,
LastName: user.LastName,
Email: user.Email.String,
PhoneNumber: user.PhoneNumber.String,
Role: domain.Role(user.Role),
}
}
return userList, nil
}
func (s *Store) SearchUserByNameOrPhone(ctx context.Context, searchString string) ([]domain.User, error) { func (s *Store) SearchUserByNameOrPhone(ctx context.Context, searchString string) ([]domain.User, error) {
users, err := s.queries.SearchUserByNameOrPhone(ctx, pgtype.Text{ users, err := s.queries.SearchUserByNameOrPhone(ctx, pgtype.Text{
String: searchString, String: searchString,
@ -234,6 +272,40 @@ func (s *Store) UpdatePassword(ctx context.Context, identifier string, password
} }
return nil return nil
} }
func (s *Store) CreateUserWithoutOtp(ctx context.Context, user domain.CreateUserReq) (domain.User, error) { func (s *Store) CreateUserWithoutOtp(ctx context.Context, user domain.User) (domain.User, error) {
return domain.User{}, nil userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{
FirstName: user.FirstName,
LastName: user.LastName,
Email: pgtype.Text{
String: user.Email,
Valid: user.Email != "",
},
PhoneNumber: pgtype.Text{
String: user.PhoneNumber,
Valid: user.PhoneNumber != "",
},
Password: user.Password,
Role: string(user.Role),
EmailVerified: user.EmailVerified,
PhoneVerified: user.PhoneVerified,
CreatedAt: pgtype.Timestamptz{
Time: time.Now(),
Valid: true,
},
UpdatedAt: pgtype.Timestamptz{
Time: time.Now(),
Valid: true,
},
})
if err != nil {
return domain.User{}, err
}
return domain.User{
ID: userRes.ID,
FirstName: userRes.FirstName,
LastName: userRes.LastName,
Email: userRes.Email.String,
PhoneNumber: userRes.PhoneNumber.String,
Role: domain.Role(userRes.Role),
}, nil
} }

View File

@ -129,6 +129,31 @@ func (s *Store) GetCustomerWallet(ctx context.Context, customerID int64, company
return convertDBGetCustomerWallet(customerWallet), nil return convertDBGetCustomerWallet(customerWallet), nil
} }
func (s *Store) GetAllBranchWallets(ctx context.Context) ([]domain.BranchWallet, error) {
wallets, err := s.queries.GetAllBranchWallets(ctx)
if err != nil {
return nil, err
}
var result []domain.BranchWallet = make([]domain.BranchWallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, domain.BranchWallet{
ID: wallet.ID,
Balance: domain.Currency(wallet.Balance),
IsActive: wallet.IsActive,
UpdatedAt: wallet.UpdatedAt.Time,
CreatedAt: wallet.CreatedAt.Time,
Name: wallet.Name,
Location: wallet.Location,
BranchManagerID: wallet.BranchManagerID,
CompanyID: wallet.CompanyID,
IsSelfOwned: wallet.IsSelfOwned,
})
}
return result, nil
}
func (s *Store) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error { func (s *Store) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error {
err := s.queries.UpdateBalance(ctx, dbgen.UpdateBalanceParams{ err := s.queries.UpdateBalance(ctx, dbgen.UpdateBalanceParams{
ID: id, ID: id,

View File

@ -8,8 +8,10 @@ import (
type BetStore interface { type BetStore interface {
CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error)
GetBetByID(ctx context.Context, id int64) (domain.Bet, error) CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBetOutcome) (int64, error)
GetAllBets(ctx context.Context) ([]domain.Bet, error) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error)
GetAllBets(ctx context.Context) ([]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
DeleteBet(ctx context.Context, id int64) error DeleteBet(ctx context.Context, id int64) error
} }

View File

@ -19,13 +19,22 @@ 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)
} }
func (s *Service) GetBetByID(ctx context.Context, id int64) (domain.Bet, error) {
func (s *Service) CreateBetOutcome(ctx context.Context, outcomes []domain.CreateBetOutcome) (int64, error) {
return s.betStore.CreateBetOutcome(ctx, outcomes)
}
func (s *Service) GetBetByID(ctx context.Context, id int64) (domain.GetBet, error) {
return s.betStore.GetBetByID(ctx, id) return s.betStore.GetBetByID(ctx, id)
} }
func (s *Service) GetAllBets(ctx context.Context) ([]domain.Bet, error) { func (s *Service) GetAllBets(ctx context.Context) ([]domain.GetBet, error) {
return s.betStore.GetAllBets(ctx) return s.betStore.GetAllBets(ctx)
} }
func (s *Service) GetBetByBranchID(ctx context.Context, branchID int64) ([]domain.GetBet, error) {
return s.betStore.GetBetByBranchID(ctx, branchID)
}
func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error { func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error {
return s.betStore.UpdateCashOut(ctx, id, cashedOut) return s.betStore.UpdateCashOut(ctx, id, cashedOut)
} }

View File

@ -8,16 +8,19 @@ import (
type BranchStore interface { type BranchStore interface {
CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error)
CreateSupportedOperation(ctx context.Context, supportedOperation domain.CreateSupportedOperation) (domain.SupportedOperation, error)
CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error) GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error)
GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error) GetBranchByManagerID(ctx context.Context, branchManagerID int64) ([]domain.BranchDetail, error)
GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error) GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error)
GetBranchOperations(ctx context.Context, branchID int64) ([]domain.BranchOperation, error)
GetAllBranches(ctx context.Context) ([]domain.BranchDetail, error) GetAllBranches(ctx context.Context) ([]domain.BranchDetail, error)
GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error)
SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error) SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error)
UpdateBranch(ctx context.Context, id int64, branch domain.UpdateBranch) (domain.Branch, error) UpdateBranch(ctx context.Context, id int64, branch domain.UpdateBranch) (domain.Branch, error)
DeleteBranch(ctx context.Context, id int64) error DeleteBranch(ctx context.Context, id int64) error
CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
CreateSupportedOperation(ctx context.Context, supportedOperation domain.CreateSupportedOperation) (domain.SupportedOperation, error)
GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error)
GetBranchOperations(ctx context.Context, branchID int64) ([]domain.BranchOperation, error)
DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error
CreateBranchCashier(ctx context.Context, branchID int64, userID int64) error
GetBranchByCashier(ctx context.Context, userID int64) (domain.Branch, error)
DeleteBranchCashier(ctx context.Context, userID int64) error
} }

View File

@ -25,6 +25,11 @@ func (s *Service) CreateSupportedOperation(ctx context.Context, supportedOperati
func (s *Service) CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error { func (s *Service) CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error {
return s.branchStore.CreateBranchOperation(ctx, branchOperation) return s.branchStore.CreateBranchOperation(ctx, branchOperation)
} }
func (s *Service) CreateBranchCashier(ctx context.Context, branchID int64, userID int64) error {
return s.branchStore.CreateBranchCashier(ctx, branchID, userID)
}
func (s *Service) GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error) { func (s *Service) GetBranchByID(ctx context.Context, id int64) (domain.BranchDetail, error) {
return s.branchStore.GetBranchByID(ctx, id) return s.branchStore.GetBranchByID(ctx, id)
} }
@ -41,6 +46,10 @@ func (s *Service) GetAllBranches(ctx context.Context) ([]domain.BranchDetail, er
return s.branchStore.GetAllBranches(ctx) return s.branchStore.GetAllBranches(ctx)
} }
func (s *Service) GetBranchByCashier(ctx context.Context, userID int64) (domain.Branch, error) {
return s.branchStore.GetBranchByCashier(ctx, userID)
}
func (s *Service) GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error) { func (s *Service) GetAllSupportedOperations(ctx context.Context) ([]domain.SupportedOperation, error) {
return s.branchStore.GetAllSupportedOperations(ctx) return s.branchStore.GetAllSupportedOperations(ctx)
} }
@ -57,3 +66,7 @@ func (s *Service) DeleteBranch(ctx context.Context, id int64) error {
func (s *Service) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error { func (s *Service) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error {
return s.branchStore.DeleteBranchOperation(ctx, branchID, operationID) return s.branchStore.DeleteBranchOperation(ctx, branchID, operationID)
} }
func (s *Service) DeleteBranchCashier(ctx context.Context, userID int64) error {
return s.branchStore.DeleteBranchCashier(ctx, userID)
}

View File

@ -8,8 +8,9 @@ import (
type TicketStore interface { type TicketStore interface {
CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error)
GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error) CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error)
GetAllTickets(ctx context.Context) ([]domain.Ticket, error) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error)
GetAllTickets(ctx context.Context) ([]domain.GetTicket, 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

@ -19,10 +19,15 @@ func NewService(ticketStore TicketStore) *Service {
func (s *Service) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) { func (s *Service) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) {
return s.ticketStore.CreateTicket(ctx, ticket) return s.ticketStore.CreateTicket(ctx, ticket)
} }
func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error) {
func (s *Service) CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error) {
return s.ticketStore.CreateTicketOutcome(ctx, outcomes)
}
func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error) {
return s.ticketStore.GetTicketByID(ctx, id) return s.ticketStore.GetTicketByID(ctx, id)
} }
func (s *Service) GetAllTickets(ctx context.Context) ([]domain.Ticket, error) { func (s *Service) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
return s.ticketStore.GetAllTickets(ctx) return s.ticketStore.GetAllTickets(ctx)
} }
func (s *Service) DeleteTicket(ctx context.Context, id int64) error { func (s *Service) DeleteTicket(ctx context.Context, id int64) error {

View File

@ -19,8 +19,21 @@ func (s *Service) CreateUser(ctx context.Context, User domain.CreateUserReq) (do
// User.BranchID = branchId // User.BranchID = branchId
// User.Role = string(domain.RoleBranchManager) // User.Role = string(domain.RoleBranchManager)
// } // }
hashedPassword, err := hashPassword(User.Password)
if err != nil {
return domain.User{}, err
}
return s.userStore.CreateUserWithoutOtp(ctx, User) return s.userStore.CreateUserWithoutOtp(ctx, domain.User{
FirstName: User.FirstName,
LastName: User.LastName,
Email: User.Email,
PhoneNumber: User.PhoneNumber,
Password: hashedPassword,
Role: domain.Role(User.Role),
EmailVerified: true,
PhoneVerified: true,
})
} }
func (s *Service) DeleteUser(ctx context.Context, id int64) error { func (s *Service) DeleteUser(ctx context.Context, id int64) error {
@ -51,3 +64,11 @@ func (s *Service) GetUserById(ctx context.Context, id int64) (domain.User, error
return s.userStore.GetUserByID(ctx, id) return s.userStore.GetUserByID(ctx, id)
} }
func (s *Service) GetCashiersByBranch(ctx context.Context, branchID int64) ([]domain.User, error) {
return s.userStore.GetCashiersByBranch(ctx, branchID)
}
func (s *Service) GetAllCashiers(ctx context.Context) ([]domain.User, error) {
return s.userStore.GetAllCashiers(ctx)
}

View File

@ -8,9 +8,11 @@ import (
type UserStore interface { type UserStore interface {
CreateUser(ctx context.Context, user domain.User, usedOtpId int64) (domain.User, error) CreateUser(ctx context.Context, user domain.User, usedOtpId int64) (domain.User, error)
CreateUserWithoutOtp(ctx context.Context, user domain.CreateUserReq) (domain.User, error) CreateUserWithoutOtp(ctx context.Context, user domain.User) (domain.User, error)
GetUserByID(ctx context.Context, id int64) (domain.User, error) GetUserByID(ctx context.Context, id int64) (domain.User, error)
GetAllUsers(ctx context.Context, filter Filter) ([]domain.User, error) GetAllUsers(ctx context.Context, filter Filter) ([]domain.User, error)
GetAllCashiers(ctx context.Context) ([]domain.User, error)
GetCashiersByBranch(ctx context.Context, branchID int64) ([]domain.User, error)
UpdateUser(ctx context.Context, user domain.UpdateUserReq) error UpdateUser(ctx context.Context, user domain.UpdateUserReq) error
DeleteUser(ctx context.Context, id int64) error DeleteUser(ctx context.Context, id int64) error
CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error) CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error)

View File

@ -13,6 +13,7 @@ type WalletStore interface {
GetAllWallets(ctx context.Context) ([]domain.Wallet, error) GetAllWallets(ctx context.Context) ([]domain.Wallet, error)
GetWalletsByUser(ctx context.Context, id int64) ([]domain.Wallet, error) GetWalletsByUser(ctx context.Context, id int64) ([]domain.Wallet, error)
GetCustomerWallet(ctx context.Context, customerID int64, companyID int64) (domain.GetCustomerWallet, error) GetCustomerWallet(ctx context.Context, customerID int64, companyID int64) (domain.GetCustomerWallet, error)
GetAllBranchWallets(ctx context.Context) ([]domain.BranchWallet, error)
UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error
UpdateWalletActive(ctx context.Context, id int64, isActive bool) error UpdateWalletActive(ctx context.Context, id int64, isActive bool) error
} }
@ -24,4 +25,3 @@ type TransferStore interface {
GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error) GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error)
UpdateTransferVerification(ctx context.Context, id int64, verified bool) error UpdateTransferVerification(ctx context.Context, id int64, verified bool) error
} }

View File

@ -23,10 +23,43 @@ func (s *Service) GetTransferByID(ctx context.Context, id int64) (domain.Transfe
return s.transferStore.GetTransferByID(ctx, id) return s.transferStore.GetTransferByID(ctx, id)
} }
func (s *Service) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.Transfer, error) {
return s.transferStore.GetTransfersByWallet(ctx, walletID)
}
func (s *Service) UpdateTransferVerification(ctx context.Context, id int64, verified bool) error { func (s *Service) UpdateTransferVerification(ctx context.Context, id int64, verified bool) error {
return s.transferStore.UpdateTransferVerification(ctx, id, verified) return s.transferStore.UpdateTransferVerification(ctx, id, verified)
} }
func (s *Service) RefillWallet(ctx context.Context, transfer domain.CreateTransfer) (domain.Transfer, error) {
receiverWallet, err := s.GetWalletByID(ctx, transfer.ReceiverWalletID)
if err != nil {
return domain.Transfer{}, err
}
// Add to receiver
err = s.walletStore.UpdateBalance(ctx, receiverWallet.ID, receiverWallet.Balance+transfer.Amount)
if err != nil {
return domain.Transfer{}, err
}
// Log the transfer so that if there is a mistake, it can be reverted
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
CashierID: transfer.CashierID,
ReceiverWalletID: receiverWallet.ID,
Amount: transfer.Amount,
Type: domain.DEPOSIT,
PaymentMethod: transfer.PaymentMethod,
Verified: true,
})
if err != nil {
return domain.Transfer{}, err
}
return newTransfer, nil
}
func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiverID int64, amount domain.Currency, paymentMethod domain.PaymentMethod, cashierID domain.ValidInt64) (domain.Transfer, error) { func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiverID int64, amount domain.Currency, paymentMethod domain.PaymentMethod, cashierID domain.ValidInt64) (domain.Transfer, error) {
senderWallet, err := s.GetWalletByID(ctx, senderID) senderWallet, err := s.GetWalletByID(ctx, senderID)

View File

@ -7,7 +7,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
) )
var ( var (
ErrBalanceInsufficient = errors.New("wallet balance is insufficient") ErrBalanceInsufficient = errors.New("wallet balance is insufficient")
) )
@ -62,6 +61,10 @@ func (s *Service) GetCustomerWallet(ctx context.Context, customerID int64, compa
return s.walletStore.GetCustomerWallet(ctx, customerID, companyID) return s.walletStore.GetCustomerWallet(ctx, customerID, companyID)
} }
func (s *Service) GetAllBranchWallets(ctx context.Context) ([]domain.BranchWallet, error) {
return s.walletStore.GetAllBranchWallets(ctx)
}
func (s *Service) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error { func (s *Service) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error {
return s.walletStore.UpdateBalance(ctx, id, balance) return s.walletStore.UpdateBalance(ctx, id, balance)
} }

View File

@ -1,44 +1,106 @@
package handlers package handlers
import ( import (
"encoding/json"
"log/slog" "log/slog"
"strconv" "strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"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/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator" customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/google/uuid" "github.com/google/uuid"
) )
type BetOutcome struct {
EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"`
}
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 []int64 `json:"outcomes"` Outcomes []BetOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"` Status domain.BetStatus `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"`
BranchID NullableInt64 `json:"branch_id" example:"1"`
} }
type CreateBetRes struct {
ID int64 `json:"id" example:"1"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"`
BranchID int64 `json:"branch_id" example:"2"`
UserID int64 `json:"user_id" example:"2"`
IsShopBet bool `json:"is_shop_bet" example:"false"`
CreatedNumber int64 `json:"created_number" example:"2"`
}
type BetRes struct { type BetRes struct {
ID int64 `json:"id" example:"1"` ID int64 `json:"id" example:"1"`
Outcomes []domain.Outcome `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.BetStatus `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"`
} }
func convertBet(bet domain.Bet) BetRes { func convertCreateBet(bet domain.Bet, createdNumber int64) CreateBetRes {
return CreateBetRes{
ID: bet.ID,
Amount: bet.Amount.Float64(),
TotalOdds: bet.TotalOdds,
Status: bet.Status,
FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber,
BranchID: bet.BranchID.Value,
UserID: bet.UserID.Value,
CreatedNumber: createdNumber,
}
}
func convertBet(bet domain.GetBet) BetRes {
return BetRes{ return BetRes{
ID: bet.ID, ID: bet.ID,
Outcomes: bet.Outcomes,
Amount: bet.Amount.Float64(), Amount: bet.Amount.Float64(),
TotalOdds: bet.TotalOdds, TotalOdds: bet.TotalOdds,
Status: bet.Status, Status: bet.Status,
@ -60,15 +122,12 @@ func convertBet(bet domain.Bet) BetRes {
// @Failure 400 {object} response.APIResponse // @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse // @Failure 500 {object} response.APIResponse
// @Router /bet [post] // @Router /bet [post]
func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler { func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service, branchSvc *branch.Service, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
// TODO if user is customer, get id from the token then get the wallet id from there
// TODO: If user is a cashier, check the token, and find the role and get the branch id from there. Reduce amount from the branch wallet // Get user_id from middleware
userID := c.Locals("user_id").(int64)
var isShopBet bool = true var isShopBet bool
var branchID int64 = 1
var userID int64
var req CreateBetReq var req CreateBetReq
@ -85,12 +144,46 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalida
return nil return nil
} }
user, err := userSvc.GetUserByID(c.Context(), userID)
if user.Role != domain.RoleCustomer {
isShopBet = true
if !req.BranchID.Valid {
logger.Error("CreateBetReq failed, branch id necessary")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Branch ID necessary",
})
}
// Get the branch from the branch ID
branch, err := branchSvc.GetBranchByID(c.Context(), req.BranchID.Value)
if err != nil {
logger.Error("CreateBetReq failed, branch id invalid")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Branch ID invalid",
})
}
// Deduct a percentage of the amount
var deductedAmount = req.Amount / 10
err = walletSvc.DeductFromWallet(c.Context(), branch.WalletID, domain.Currency(deductedAmount))
if err != nil {
logger.Error("CreateBetReq failed, unable to deduct from WalletID", branch.WalletID)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Unable to deduct from branch wallet",
})
}
} else {
isShopBet = false
// TODO if user is customer, get id from the token then get the wallet id from there and reduce the amount
}
// TODO Validate Outcomes Here and make sure they didn't expire // TODO Validate Outcomes Here and make sure they didn't expire
cashoutUUID := uuid.New() cashoutUUID := uuid.New()
bet, err := betSvc.CreateBet(c.Context(), domain.CreateBet{ bet, err := betSvc.CreateBet(c.Context(), domain.CreateBet{
Outcomes: req.Outcomes,
Amount: domain.Currency(req.Amount), Amount: domain.Currency(req.Amount),
TotalOdds: req.TotalOdds, TotalOdds: req.TotalOdds,
Status: req.Status, Status: req.Status,
@ -98,7 +191,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalida
PhoneNumber: req.PhoneNumber, PhoneNumber: req.PhoneNumber,
BranchID: domain.ValidInt64{ BranchID: domain.ValidInt64{
Value: branchID, Value: req.BranchID.Value,
Valid: isShopBet, Valid: isShopBet,
}, },
UserID: domain.ValidInt64{ UserID: domain.ValidInt64{
@ -113,8 +206,25 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalida
logger.Error("CreateBetReq failed", "error", err) logger.Error("CreateBetReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil)
} }
var outcomes []domain.CreateBetOutcome = make([]domain.CreateBetOutcome, 0, len(req.Outcomes))
res := convertBet(bet) for _, outcome := range req.Outcomes {
outcomes = append(outcomes, domain.CreateBetOutcome{
BetID: bet.ID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
}
rows, err := betSvc.CreateBetOutcome(c.Context(), outcomes)
if err != nil {
logger.Error("CreateBetReq failed to create outcomes", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
res := convertCreateBet(bet, rows)
return response.WriteJSON(c, fiber.StatusOK, "Bet Created", res, nil) return response.WriteJSON(c, fiber.StatusOK, "Bet Created", res, nil)
} }

View File

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"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/wallet" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
@ -43,6 +44,7 @@ type BranchOperationRes struct {
} }
type BranchRes struct { type BranchRes struct {
ID int64 `json:"id" example:"1"`
Name string `json:"name" example:"4-kilo Branch"` Name string `json:"name" example:"4-kilo Branch"`
Location string `json:"location" example:"Addis Ababa"` Location string `json:"location" example:"Addis Ababa"`
WalletID int64 `json:"wallet_id" example:"1"` WalletID int64 `json:"wallet_id" example:"1"`
@ -52,6 +54,7 @@ type BranchRes struct {
} }
type BranchDetailRes struct { type BranchDetailRes struct {
ID int64 `json:"id" example:"1"`
Name string `json:"name" example:"4-kilo Branch"` Name string `json:"name" example:"4-kilo Branch"`
Location string `json:"location" example:"Addis Ababa"` Location string `json:"location" example:"Addis Ababa"`
WalletID int64 `json:"wallet_id" example:"1"` WalletID int64 `json:"wallet_id" example:"1"`
@ -64,6 +67,7 @@ type BranchDetailRes struct {
func convertBranch(branch domain.Branch) BranchRes { func convertBranch(branch domain.Branch) BranchRes {
return BranchRes{ return BranchRes{
ID: branch.ID,
Name: branch.Name, Name: branch.Name,
Location: branch.Location, Location: branch.Location,
WalletID: branch.WalletID, WalletID: branch.WalletID,
@ -75,6 +79,7 @@ func convertBranch(branch domain.Branch) BranchRes {
func convertBranchDetail(branch domain.BranchDetail) BranchDetailRes { func convertBranchDetail(branch domain.BranchDetail) BranchDetailRes {
return BranchDetailRes{ return BranchDetailRes{
ID: branch.ID,
Name: branch.Name, Name: branch.Name,
Location: branch.Location, Location: branch.Location,
WalletID: branch.WalletID, WalletID: branch.WalletID,
@ -393,6 +398,42 @@ func GetAllBranches(logger *slog.Logger, branchSvc *branch.Service, validator *c
} }
} }
// SearchBranch godoc
// @Summary Search branches
// @Description Search branches by name or location
// @Tags branch
// @Accept json
// @Produce json
// @Param q query string true "Search query"
// @Success 200 {array} BranchDetailRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /search/branch [get]
func SearchBranch(logger *slog.Logger, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
// Get search query from request
searchQuery := c.Query("q")
if searchQuery == "" {
return response.WriteJSON(c, fiber.StatusBadRequest, "Search query is required", nil, nil)
}
// Call the service to search for branches
branches, err := branchSvc.SearchBranchByName(c.Context(), searchQuery)
if err != nil {
logger.Error("Failed to search branches", "query", searchQuery, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to search branches", err, nil)
}
// Convert branches to response format
var result []BranchDetailRes
for _, branch := range branches {
result = append(result, convertBranchDetail(branch))
}
return response.WriteJSON(c, fiber.StatusOK, "Branches retrieved successfully", result, nil)
}
}
// GetAllSupportedOperations godoc // GetAllSupportedOperations godoc
// @Summary Gets all supported operations // @Summary Gets all supported operations
// @Description Gets all supported operations // @Description Gets all supported operations
@ -465,6 +506,41 @@ func GetBranchOperations(logger *slog.Logger, branchSvc *branch.Service, validat
} }
} }
// GetBetByBranchID godoc
// @Summary Gets bets by its branch id
// @Description Gets bets by its branch id
// @Tags branch
// @Accept json
// @Produce json
// @Success 200 {array} BetRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /branch/{id}/bets [get]
func GetBetByBranchID(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
branchID := c.Params("id")
id, err := strconv.ParseInt(branchID, 10, 64)
if err != nil {
logger.Error("Invalid branch ID", "branchID", branchID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid branch ID", err, nil)
}
bets, err := betSvc.GetBetByBranchID(c.Context(), id)
if err != nil {
logger.Error("Failed to get bets", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve bets", err, nil)
}
var res []BetRes = make([]BetRes, 0, len(bets))
for _, bet := range bets {
res = append(res, convertBet(bet))
}
return response.WriteJSON(c, fiber.StatusOK, "Branch Bets Retrieved", res, nil)
}
}
// UpdateBranch godoc // UpdateBranch godoc
// @Summary Updates a branch // @Summary Updates a branch
// @Description Updates a branch // @Description Updates a branch

View File

@ -3,8 +3,10 @@ package handlers
import ( import (
"log/slog" "log/slog"
"strconv" "strconv"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator" customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
@ -17,6 +19,7 @@ type CreateCashierReq struct {
Email string `json:"email" example:"john.doe@example.com"` Email string `json:"email" example:"john.doe@example.com"`
PhoneNumber string `json:"phone_number" example:"1234567890"` PhoneNumber string `json:"phone_number" example:"1234567890"`
Password string `json:"password" example:"password123"` Password string `json:"password" example:"password123"`
BranchID int64 `json:"branch_id" example:"1"`
} }
// CreateCashier godoc // CreateCashier godoc
@ -31,10 +34,9 @@ type CreateCashierReq struct {
// @Failure 401 {object} response.APIResponse // @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse // @Failure 500 {object} response.APIResponse
// @Router /cashiers [post] // @Router /cashiers [post]
func CreateCashier(logger *slog.Logger, userSvc *user.Service, validator *customvalidator.CustomValidator) fiber.Handler { func CreateCashier(logger *slog.Logger, userSvc *user.Service, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
creatorBranch := c.Locals("branch_id").(int64)
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)
@ -47,27 +49,49 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil return nil
} }
user := domain.CreateUserReq{ userRequest := domain.CreateUserReq{
FirstName: req.FirstName, FirstName: req.FirstName,
LastName: req.LastName, LastName: req.LastName,
Email: req.Email, Email: req.Email,
PhoneNumber: req.PhoneNumber, PhoneNumber: req.PhoneNumber,
Password: req.Password, Password: req.Password,
Role: string(domain.RoleCashier), Role: string(domain.RoleCashier),
BranchID: creatorBranch,
} }
_, err := userSvc.CreateUser(c.Context(), user) 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) response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil return nil
} }
err = branchSvc.CreateBranchCashier(c.Context(), req.BranchID, newUser.ID)
if err != nil {
logger.Error("CreateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil
}
response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil) response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil)
return nil return nil
} }
} }
type GetCashierRes struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
Role domain.Role `json:"role"`
EmailVerified bool `json:"email_verified"`
PhoneVerified bool `json:"phone_verified"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
SuspendedAt time.Time `json:"suspended_at"`
Suspended bool `json:"suspended"`
}
// GetAllCashiers godoc // GetAllCashiers godoc
// @Summary Get all cashiers // @Summary Get all cashiers
// @Description Get all cashiers // @Description Get all cashiers
@ -83,28 +107,48 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
// @Router /cashiers [get] // @Router /cashiers [get]
func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *customvalidator.CustomValidator) fiber.Handler { func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
branchId := int64(12) //c.Locals("branch_id").(int64) // branchId := int64(12) //c.Locals("branch_id").(int64)
filter := user.Filter{ // filter := user.Filter{
Role: string(domain.RoleCashier), // Role: string(domain.RoleCashier),
BranchId: user.ValidBranchId{ // BranchId: user.ValidBranchId{
Value: branchId, // Value: branchId,
Valid: true, // Valid: true,
}, // },
Page: c.QueryInt("page", 1), // Page: c.QueryInt("page", 1),
PageSize: c.QueryInt("page_size", 10), // PageSize: c.QueryInt("page_size", 10),
} // }
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) // response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil // return nil
} // }
cashiers, err := userSvc.GetAllUsers(c.Context(), filter)
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) response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil)
return nil return nil
} }
response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", cashiers, nil)
var result []GetCashierRes
for _, cashier := range cashiers {
result = append(result, GetCashierRes{
ID: cashier.ID,
FirstName: cashier.FirstName,
LastName: cashier.LastName,
Email: cashier.Email,
PhoneNumber: cashier.PhoneNumber,
Role: cashier.Role,
EmailVerified: cashier.EmailVerified,
PhoneVerified: cashier.PhoneVerified,
CreatedAt: cashier.CreatedAt,
UpdatedAt: cashier.UpdatedAt,
SuspendedAt: cashier.SuspendedAt,
Suspended: cashier.Suspended,
})
}
response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", result, nil)
return nil return nil
} }

View File

@ -17,7 +17,6 @@ type CreateManagerReq struct {
Email string `json:"email" example:"john.doe@example.com"` Email string `json:"email" example:"john.doe@example.com"`
PhoneNumber string `json:"phone_number" example:"1234567890"` PhoneNumber string `json:"phone_number" example:"1234567890"`
Password string `json:"password" example:"password123"` Password string `json:"password" example:"password123"`
BranchId int64 `json:"branch_id" example:"1"`
} }
// CreateManagers godoc // CreateManagers godoc
@ -53,7 +52,6 @@ func CreateManager(logger *slog.Logger, userSvc *user.Service, validator *custom
PhoneNumber: req.PhoneNumber, PhoneNumber: req.PhoneNumber,
Password: req.Password, Password: req.Password,
Role: string(domain.RoleBranchManager), Role: string(domain.RoleBranchManager),
BranchID: req.BranchId,
} }
_, err := userSvc.CreateUser(c.Context(), user) _, err := userSvc.CreateUser(c.Context(), user)
if err != nil { if err != nil {

View File

@ -11,13 +11,19 @@ import (
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
type TicketOutcome struct {
EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"`
}
type CreateTicketReq struct { type CreateTicketReq struct {
Outcomes []int64 `json:"outcomes"` Outcomes []TicketOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
} }
type CreateTicketRes struct { type CreateTicketRes struct {
FastCode int64 `json:"fast_code" example:"1234"` FastCode int64 `json:"fast_code" example:"1234"`
CreatedNumber int64 `json:"created_number" example:"3"`
} }
// CreateTicket godoc // CreateTicket godoc
@ -51,7 +57,6 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service,
// TODO Validate Outcomes Here and make sure they didn't expire // TODO Validate Outcomes Here and make sure they didn't expire
ticket, err := ticketSvc.CreateTicket(c.Context(), domain.CreateTicket{ ticket, err := ticketSvc.CreateTicket(c.Context(), domain.CreateTicket{
Outcomes: req.Outcomes,
Amount: domain.Currency(req.Amount), Amount: domain.Currency(req.Amount),
TotalOdds: req.TotalOdds, TotalOdds: req.TotalOdds,
}) })
@ -61,18 +66,37 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service,
"error": "Internal server error", "error": "Internal server error",
}) })
} }
var outcomes []domain.CreateTicketOutcome = make([]domain.CreateTicketOutcome, 0, len(req.Outcomes))
for _, outcome := range req.Outcomes {
outcomes = append(outcomes, domain.CreateTicketOutcome{
TicketID: ticket.ID,
EventID: outcome.EventID,
OddID: outcome.OddID,
})
}
rows, err := ticketSvc.CreateTicketOutcome(c.Context(), outcomes)
if err != nil {
logger.Error("CreateTicketReq failed to create outcomes", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
res := CreateTicketRes{ res := CreateTicketRes{
FastCode: ticket.ID, FastCode: ticket.ID,
CreatedNumber: rows,
} }
return response.WriteJSON(c, fiber.StatusOK, "Ticket Created", res, nil) return response.WriteJSON(c, fiber.StatusOK, "Ticket Created", res, nil)
} }
} }
type TicketRes struct { type TicketRes struct {
ID int64 `json:"id" example:"1"` ID int64 `json:"id" example:"1"`
Outcomes []domain.Outcome `json:"outcomes"` Outcomes []domain.TicketOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"` Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"` TotalOdds float32 `json:"total_odds" example:"4.22"`
} }
// GetTicketByID godoc // GetTicketByID godoc

View File

@ -153,6 +153,9 @@ func GetAllTransactions(
// Check user role and fetch transactions accordingly // Check user role and fetch transactions accordingly
switch user.Role { switch user.Role {
case domain.RoleSuperAdmin:
// Admin can fetch all transactions
transactions, err = transactionSvc.GetAllTransactions(c.Context())
case domain.RoleAdmin: case domain.RoleAdmin:
// Admin can fetch all transactions // Admin can fetch all transactions
transactions, err = transactionSvc.GetAllTransactions(c.Context()) transactions, err = transactionSvc.GetAllTransactions(c.Context())

View File

@ -2,6 +2,7 @@ package handlers
import ( import (
"log/slog" "log/slog"
"strconv"
"time" "time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
@ -12,7 +13,19 @@ import (
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
type TransferRes struct { type TransferWalletRes struct {
ID int64 `json:"id" example:"1"`
Amount float32 `json:"amount" example:"100.0"`
Verified bool `json:"verified" example:"true"`
Type string `json:"type" example:"transfer"`
PaymentMethod string `json:"payment_method" example:"bank"`
ReceiverWalletID int64 `json:"receiver_wallet_id" example:"1"`
SenderWalletID *int64 `json:"sender_wallet_id" example:"1"`
CashierID *int64 `json:"cashier_id" example:"789"`
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:30:00Z"`
}
type RefillRes 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"`
Verified bool `json:"verified" example:"true"` Verified bool `json:"verified" example:"true"`
@ -25,7 +38,7 @@ type TransferRes struct {
UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:30:00Z"` UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:30:00Z"`
} }
func convertTransfer(transfer domain.Transfer) TransferRes { func convertTransfer(transfer domain.Transfer) TransferWalletRes {
var senderWalletID *int64 var senderWalletID *int64
if transfer.SenderWalletID.Valid { if transfer.SenderWalletID.Valid {
senderWalletID = &transfer.SenderWalletID.Value senderWalletID = &transfer.SenderWalletID.Value
@ -36,7 +49,7 @@ func convertTransfer(transfer domain.Transfer) TransferRes {
cashierID = &transfer.CashierID.Value cashierID = &transfer.CashierID.Value
} }
return TransferRes{ return TransferWalletRes{
ID: transfer.ID, ID: transfer.ID,
Amount: transfer.Amount.Float64(), Amount: transfer.Amount.Float64(),
Verified: transfer.Verified, Verified: transfer.Verified,
@ -51,11 +64,47 @@ func convertTransfer(transfer domain.Transfer) TransferRes {
} }
type CreateTransferReq struct { type CreateTransferReq struct {
ReceiverID int64 `json:"receiver_id" example:"1"`
Amount float64 `json:"amount" example:"100.0"` Amount float64 `json:"amount" example:"100.0"`
PaymentMethod string `json:"payment_method" example:"cash"` PaymentMethod string `json:"payment_method" example:"cash"`
} }
// GetTransfersByWallet godoc
// @Summary Get transfer by wallet
// @Description Get transfer by wallet
// @Tags transfer
// @Accept json
// @Produce json
// @Param transferToWallet body CreateTransferReq true "Create Transfer"
// @Success 200 {object} TransferWalletRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /transfer/wallet/{id} [get]
func GetTransfersByWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
walletID := c.Params("id")
id, err := strconv.ParseInt(walletID, 10, 64)
if err != nil {
logger.Error("Invalid wallet ID", "walletID", walletID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid wallet ID", err, nil)
}
transfers, err := walletSvc.GetTransfersByWallet(c.Context(), int64(id))
if err != nil {
logger.Error("Failed to get transfers by wallet", "walletID", walletID, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve transfers", err, nil)
}
var transferResponses []TransferWalletRes
for _, transfer := range transfers {
transferResponses = append(transferResponses, convertTransfer(transfer))
}
return response.WriteJSON(c, fiber.StatusOK, "Transfers retrieved successfully", transferResponses, nil)
}
}
// TransferToWallet godoc // TransferToWallet godoc
// @Summary Create a transfer to wallet // @Summary Create a transfer to wallet
// @Description Create a transfer to wallet // @Description Create a transfer to wallet
@ -63,26 +112,42 @@ type CreateTransferReq struct {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param transferToWallet body CreateTransferReq true "Create Transfer" // @Param transferToWallet body CreateTransferReq true "Create Transfer"
// @Success 200 {object} TransferRes // @Success 200 {object} TransferWalletRes
// @Failure 400 {object} response.APIResponse // @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse // @Failure 500 {object} response.APIResponse
// @Router /transfer/wallet [post] // @Router /transfer/wallet/:id [post]
func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler { func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
receiverIDString := c.Params("id")
receiverID, err := strconv.ParseInt(receiverIDString, 10, 64)
if err != nil {
logger.Error("Invalid wallet ID", "walletID", receiverID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid wallet ID", err, nil)
}
// Get sender ID from the cashier // Get sender ID from the cashier
userID := c.Locals("user_id").(int64) userID := c.Locals("user_id").(int64)
role := string(c.Locals("role").(domain.Role)) role := string(c.Locals("role").(domain.Role))
branchID := c.Locals("branch_id").(int64)
var senderID int64
if role == string(domain.RoleCustomer) { if role == string(domain.RoleCustomer) {
logger.Error("Unauthorized access", "userID", userID, "role", role) logger.Error("Unauthorized access", "userID", userID, "role", role)
return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil) return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
} } else if role == string(domain.RoleBranchManager) || role == string(domain.RoleAdmin) || role == string(domain.RoleSuperAdmin) {
// TODO Add a way for admins to reference branch wallet
branchWallet, err := branchSvc.GetBranchByID(c.Context(), branchID) senderID = 0
if err != nil { logger.Error("Will", "userID", userID, "role", role)
logger.Error("Failed to get branch wallet", "branch ID", branchID, "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "Unauthorized access", nil, nil)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve branch wallet", err, nil) } else {
cashierBranch, err := branchSvc.GetBranchByCashier(c.Context(), userID)
if err != nil {
logger.Error("Failed to get branch", "user ID", userID, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve cashier branch", err, nil)
}
senderID = cashierBranch.WalletID
} }
var req CreateTransferReq var req CreateTransferReq
@ -100,7 +165,7 @@ func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc
return nil return nil
} }
transfer, err := walletSvc.TransferToWallet(c.Context(), branchWallet.ID, req.ReceiverID, domain.Currency(req.Amount), domain.PaymentMethod(req.PaymentMethod), domain.ValidInt64{Value: userID, Valid: true}) transfer, err := walletSvc.TransferToWallet(c.Context(), senderID, receiverID, domain.Currency(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) response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
@ -113,3 +178,72 @@ func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc
} }
} }
// RefillWallet godoc
// @Summary Refill wallet
// @Description Super Admin route to refill a wallet
// @Tags transfer
// @Accept json
// @Produce json
// @Param refillWallet body CreateTransferReq true "Create Transfer"
// @Success 200 {object} TransferWalletRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /transfer/refill/:id [post]
func RefillWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
receiverIDString := c.Params("id")
receiverID, err := strconv.ParseInt(receiverIDString, 10, 64)
if err != nil {
logger.Error("Invalid wallet ID", "walletID", receiverID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid wallet ID", err, nil)
}
// Get sender ID from the cashier
userID := c.Locals("user_id").(int64)
role := string(c.Locals("role").(domain.Role))
if role != string(domain.RoleSuperAdmin) {
logger.Error("Unauthorized access", "userID", userID, "role", role)
return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
}
var req CreateTransferReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTransferReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
}
transfer, err := walletSvc.RefillWallet(c.Context(), domain.CreateTransfer{
Amount: domain.Currency(req.Amount),
PaymentMethod: domain.PaymentMethod(req.PaymentMethod),
ReceiverWalletID: receiverID,
CashierID: domain.ValidInt64{
Value: userID,
Valid: true,
},
Type: domain.TransferType("deposit"),
})
if !ok {
response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)
return nil
}
res := convertTransfer(transfer)
return response.WriteJSON(c, fiber.StatusOK, "Transfer Successful", res, nil)
}
}

View File

@ -66,6 +66,19 @@ func convertCustomerWallet(wallet domain.GetCustomerWallet) CustomerWalletRes {
} }
} }
type BranchWalletRes struct {
ID int64 `json:"id" example:"1"`
Balance float32 `json:"balance" example:"100.0"`
IsActive bool `json:"is_active" example:"true"`
Name string `json:"name" example:"true"`
Location string `json:"location" example:"somewhere"`
BranchManagerID int64 `json:"branch_manager_id" example:"1"`
CompanyID int64 `json:"company_id" example:"1"`
IsSelfOwned bool `json:"is_self_owned" example:"false"`
UpdatedAt time.Time `json:"updated_at"`
CreatedAt time.Time `json:"created_at"`
}
// GetWalletByID godoc // GetWalletByID godoc
// @Summary Get wallet by ID // @Summary Get wallet by ID
// @Description Retrieve wallet details by wallet ID // @Description Retrieve wallet details by wallet ID
@ -112,10 +125,12 @@ func GetWalletByID(logger *slog.Logger, walletSvc *wallet.Service, validator *cu
// @Router /wallet [get] // @Router /wallet [get]
func GetAllWallets(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler { func GetAllWallets(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
wallets, err := walletSvc.GetAllWallets(c.Context()) wallets, err := walletSvc.GetAllWallets(c.Context())
if err != nil { if err != nil {
logger.Error("Failed to get wallets", "error", err) logger.Error("Failed to get wallets", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallets", err, nil)
} }
var res []WalletRes = make([]WalletRes, 0, len(wallets)) var res []WalletRes = make([]WalletRes, 0, len(wallets))
@ -128,6 +143,47 @@ func GetAllWallets(logger *slog.Logger, walletSvc *wallet.Service, validator *cu
} }
} }
// GetAllBranchWallets godoc
// @Summary Get all branch wallets
// @Description Retrieve all branch wallets
// @Tags wallet
// @Accept json
// @Produce json
// @Success 200 {array} WalletRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /branchWallet [get]
func GetAllBranchWallets(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
wallets, err := walletSvc.GetAllBranchWallets(c.Context())
if err != nil {
logger.Error("Failed to get wallets", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallets", err, nil)
}
var res []BranchWalletRes = make([]BranchWalletRes, 0, len(wallets))
for _, wallet := range wallets {
res = append(res, BranchWalletRes{
ID: wallet.ID,
Balance: wallet.Balance.Float64(),
IsActive: wallet.IsActive,
Name: wallet.Name,
Location: wallet.Location,
BranchManagerID: wallet.BranchManagerID,
CompanyID: wallet.CompanyID,
IsSelfOwned: wallet.IsSelfOwned,
UpdatedAt: wallet.UpdatedAt,
CreatedAt: wallet.CreatedAt,
})
}
return response.WriteJSON(c, fiber.StatusOK, "All Wallets retrieved", res, nil)
}
}
type UpdateWalletActiveReq struct { type UpdateWalletActiveReq struct {
IsActive bool IsActive bool
} }

View File

@ -42,7 +42,7 @@ func (a *App) initAppRoutes() {
// //
//, a.authMiddleware //, a.authMiddleware
a.fiber.Get("/cashiers", handlers.GetAllCashiers(a.logger, a.userSvc, a.validator)) a.fiber.Get("/cashiers", handlers.GetAllCashiers(a.logger, a.userSvc, a.validator))
a.fiber.Post("/cashiers", handlers.CreateCashier(a.logger, a.userSvc, a.validator)) a.fiber.Post("/cashiers", handlers.CreateCashier(a.logger, a.userSvc, a.branchSvc, a.validator))
a.fiber.Put("/cashiers/:id", handlers.UpdateCashier(a.logger, a.userSvc, a.validator)) a.fiber.Put("/cashiers/:id", handlers.UpdateCashier(a.logger, a.userSvc, a.validator))
// //
@ -64,8 +64,11 @@ func (a *App) initAppRoutes() {
a.fiber.Post("/branch", handlers.CreateBranch(a.logger, a.branchSvc, a.walletSvc, a.validator)) a.fiber.Post("/branch", handlers.CreateBranch(a.logger, a.branchSvc, a.walletSvc, a.validator))
a.fiber.Get("/branch", handlers.GetAllBranches(a.logger, a.branchSvc, a.validator)) a.fiber.Get("/branch", handlers.GetAllBranches(a.logger, a.branchSvc, a.validator))
a.fiber.Get("/branch/:id", handlers.GetBranchByID(a.logger, a.branchSvc, a.validator)) a.fiber.Get("/branch/:id", handlers.GetBranchByID(a.logger, a.branchSvc, a.validator))
a.fiber.Get("/branch/:id/bets", handlers.GetBetByBranchID(a.logger, a.betSvc, a.validator))
a.fiber.Put("/branch/:id", handlers.UpdateBranch(a.logger, a.branchSvc, a.validator)) a.fiber.Put("/branch/:id", handlers.UpdateBranch(a.logger, a.branchSvc, a.validator))
a.fiber.Delete("/branch/:id", handlers.DeleteBranch(a.logger, a.branchSvc, a.validator)) a.fiber.Delete("/branch/:id", handlers.DeleteBranch(a.logger, a.branchSvc, a.validator))
a.fiber.Get("/search/branch", a.authMiddleware, handlers.SearchBranch(a.logger, a.branchSvc, a.validator))
// /branch/search
// branch/wallet // branch/wallet
// Branch Operation // Branch Operation
@ -81,7 +84,7 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/ticket/:id", handlers.GetTicketByID(a.logger, a.ticketSvc, a.validator)) a.fiber.Get("/ticket/:id", handlers.GetTicketByID(a.logger, a.ticketSvc, a.validator))
// Bet // Bet
a.fiber.Post("/bet", handlers.CreateBet(a.logger, a.betSvc, a.validator)) a.fiber.Post("/bet", handlers.CreateBet(a.logger, a.betSvc, a.userSvc, a.branchSvc, a.walletSvc, a.validator))
a.fiber.Get("/bet", handlers.GetAllBet(a.logger, a.betSvc, a.validator)) a.fiber.Get("/bet", handlers.GetAllBet(a.logger, a.betSvc, a.validator))
a.fiber.Get("/bet/:id", handlers.GetBetByID(a.logger, a.betSvc, a.validator)) a.fiber.Get("/bet/:id", handlers.GetBetByID(a.logger, a.betSvc, a.validator))
a.fiber.Patch("/bet/:id", handlers.UpdateCashOut(a.logger, a.betSvc, a.validator)) a.fiber.Patch("/bet/:id", handlers.UpdateCashOut(a.logger, a.betSvc, a.validator))
@ -91,10 +94,13 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/wallet", handlers.GetAllWallets(a.logger, a.walletSvc, a.validator)) a.fiber.Get("/wallet", handlers.GetAllWallets(a.logger, a.walletSvc, a.validator))
a.fiber.Get("/wallet/:id", handlers.GetWalletByID(a.logger, a.walletSvc, a.validator)) a.fiber.Get("/wallet/:id", handlers.GetWalletByID(a.logger, a.walletSvc, a.validator))
a.fiber.Put("/wallet/:id", handlers.UpdateWalletActive(a.logger, a.walletSvc, a.validator)) a.fiber.Put("/wallet/:id", handlers.UpdateWalletActive(a.logger, a.walletSvc, a.validator))
a.fiber.Get("/branchWallet", handlers.GetAllBranchWallets(a.logger, a.walletSvc, a.validator))
// Transfer // Transfer
// /transfer/wallet - transfer from one wallet to another wallet // /transfer/wallet - transfer from one wallet to another wallet
a.fiber.Post("/transfer/wallet", a.authMiddleware, handlers.TransferToWallet(a.logger, a.walletSvc, a.branchSvc, a.validator)) a.fiber.Post("/transfer/wallet/:id", a.authMiddleware, handlers.TransferToWallet(a.logger, a.walletSvc, a.branchSvc, a.validator))
a.fiber.Get("/transfer/wallet/:id", a.authMiddleware, handlers.GetTransfersByWallet(a.logger, a.walletSvc, a.validator))
a.fiber.Get("/transfer/refill/:id", a.authMiddleware, handlers.RefillWallet(a.logger, a.walletSvc, a.validator))
// Transactions // Transactions
a.fiber.Post("/transaction", a.authMiddleware, handlers.CreateTransaction(a.logger, a.transactionSvc, a.validator)) a.fiber.Post("/transaction", a.authMiddleware, handlers.CreateTransaction(a.logger, a.transactionSvc, a.validator))

View File

@ -16,4 +16,12 @@ sql:
- db_type: "uuid" - db_type: "uuid"
go_type: "github.com/google/uuid.NullUUID" go_type: "github.com/google/uuid.NullUUID"
nullable: true nullable: true
- column: "bet_with_outcomes.outcomes"
go_type:
type: "BetOutcome"
slice: true
- column: "ticket_with_outcomes.outcomes"
go_type:
type: "TicketOutcome"
slice: true