fix: refactored the transactions into shop_transactions
This commit is contained in:
parent
f27a75eb66
commit
d678b4e9d3
|
|
@ -119,7 +119,6 @@ func main() {
|
||||||
logger,
|
logger,
|
||||||
)
|
)
|
||||||
|
|
||||||
transactionSvc := transaction.NewService(store)
|
|
||||||
branchSvc := branch.NewService(store)
|
branchSvc := branch.NewService(store)
|
||||||
companySvc := company.NewService(store)
|
companySvc := company.NewService(store)
|
||||||
leagueSvc := league.New(store)
|
leagueSvc := league.New(store)
|
||||||
|
|
@ -153,6 +152,7 @@ func main() {
|
||||||
cfg.FIXER_API_KEY,
|
cfg.FIXER_API_KEY,
|
||||||
cfg.FIXER_BASE_URL,
|
cfg.FIXER_BASE_URL,
|
||||||
)
|
)
|
||||||
|
transactionSvc := transaction.NewService(store, *branchSvc)
|
||||||
|
|
||||||
reportSvc := report.NewService(
|
reportSvc := report.NewService(
|
||||||
bet.BetStore(store),
|
bet.BetStore(store),
|
||||||
|
|
@ -167,6 +167,8 @@ func main() {
|
||||||
logger,
|
logger,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
go httpserver.SetupReportCronJobs(context.Background(), reportSvc)
|
go httpserver.SetupReportCronJobs(context.Background(), reportSvc)
|
||||||
|
|
||||||
bankRepository := repository.NewBankRepository(store)
|
bankRepository := repository.NewBankRepository(store)
|
||||||
|
|
|
||||||
|
|
@ -172,28 +172,45 @@ CREATE TABLE IF NOT EXISTS shop_transactions (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
amount BIGINT NOT NULL,
|
amount BIGINT NOT NULL,
|
||||||
branch_id BIGINT NOT NULL,
|
branch_id BIGINT NOT NULL,
|
||||||
company_id BIGINT,
|
company_id BIGINT NOT NULL,
|
||||||
cashier_id BIGINT,
|
user_id BIGINT NOT NULL,
|
||||||
cashier_name VARCHAR(255),
|
type BIGINT NOT NULL,
|
||||||
bet_id BIGINT,
|
full_name VARCHAR(255) NOT NULL,
|
||||||
number_of_outcomes BIGINT,
|
phone_number VARCHAR(255) NOT NULL,
|
||||||
type BIGINT,
|
payment_option BIGINT NOT NULL,
|
||||||
payment_option BIGINT,
|
|
||||||
full_name VARCHAR(255),
|
|
||||||
phone_number VARCHAR(255),
|
|
||||||
bank_code VARCHAR(255),
|
bank_code VARCHAR(255),
|
||||||
beneficiary_name VARCHAR(255),
|
beneficiary_name VARCHAR(255),
|
||||||
account_name VARCHAR(255),
|
account_name VARCHAR(255),
|
||||||
account_number VARCHAR(255),
|
account_number VARCHAR(255),
|
||||||
reference_number VARCHAR(255),
|
reference_number VARCHAR(255),
|
||||||
verified BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
approved_by BIGINT,
|
approved_by BIGINT,
|
||||||
approver_name VARCHAR(255),
|
verified BOOLEAN DEFAULT false NOT NULL,
|
||||||
branch_location VARCHAR(255),
|
|
||||||
branch_name VARCHAR(255),
|
|
||||||
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 shop_bets (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
shop_transaction_id BIGINT NOT NULL,
|
||||||
|
cashout_id VARCHAR(255) NOT NULL,
|
||||||
|
cashed_out_by BIGINT,
|
||||||
|
bet_id BIGINT NOT NULL,
|
||||||
|
number_of_outcomes BIGINT NOT NULL,
|
||||||
|
cashed_out BOOLEAN DEFAULT FALSE NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(shop_transaction_id),
|
||||||
|
UNIQUE(bet_id),
|
||||||
|
UNIQUE(cashout_id)
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS shop_deposits (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
shop_transaction_id BIGINT NOT NULL,
|
||||||
|
customer_id BIGINT NOT NULL,
|
||||||
|
wallet_transfer_id BIGINT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(shop_transaction_id)
|
||||||
|
);
|
||||||
CREATE TABLE IF NOT EXISTS branches (
|
CREATE TABLE IF NOT EXISTS branches (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
|
|
@ -318,7 +335,7 @@ SELECT branches.*,
|
||||||
wallets.is_active AS wallet_is_active
|
wallets.is_active AS wallet_is_active
|
||||||
FROM branches
|
FROM branches
|
||||||
LEFT JOIN users ON branches.branch_manager_id = users.id
|
LEFT JOIN users ON branches.branch_manager_id = users.id
|
||||||
LEFT JOin wallets ON wallets.id = branches.wallet_id;
|
LEFT JOIN wallets ON wallets.id = branches.wallet_id;
|
||||||
CREATE TABLE IF NOT EXISTS supported_operations (
|
CREATE TABLE IF NOT EXISTS supported_operations (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
|
|
@ -362,6 +379,54 @@ SELECT wt.*,
|
||||||
users.phone_number
|
users.phone_number
|
||||||
FROM wallet_transfer wt
|
FROM wallet_transfer wt
|
||||||
LEFT JOIN users ON users.id = wt.cashier_id;
|
LEFT JOIN users ON users.id = wt.cashier_id;
|
||||||
|
CREATE VIEW shop_transaction_detail AS
|
||||||
|
SELECT st.*,
|
||||||
|
cr.first_name AS creator_first_name,
|
||||||
|
cr.last_name AS creator_last_name,
|
||||||
|
cr.phone_number AS creator_phone_number,
|
||||||
|
ap.first_name AS approver_first_name,
|
||||||
|
ap.last_name AS approver_last_name,
|
||||||
|
ap.phone_number AS approver_phone_number,
|
||||||
|
branches.name AS branch_name,
|
||||||
|
branches.location AS branch_location
|
||||||
|
FROM shop_transactions st
|
||||||
|
LEFT JOIN users cr ON cr.id = st.user_id
|
||||||
|
LEFT JOIN users ap ON ap.id = st.approved_by
|
||||||
|
LEFT JOIN branches ON branches.id = st.branch_id;
|
||||||
|
CREATE VIEW shop_bet_detail AS
|
||||||
|
SELECT sb.*,
|
||||||
|
st.full_name AS customer_full_name,
|
||||||
|
st.phone_number AS customer_phone_number,
|
||||||
|
st.branch_id,
|
||||||
|
st.company_id,
|
||||||
|
st.amount,
|
||||||
|
st.verified AS transaction_verified,
|
||||||
|
bets.status,
|
||||||
|
bets.total_odds,
|
||||||
|
JSON_AGG(bet_outcomes.*) AS outcomes
|
||||||
|
FROM shop_bets AS sb
|
||||||
|
JOIN shop_transactions st ON st.id = sb.shop_transaction_id
|
||||||
|
JOIN bets ON bets.id = sb.bet_id
|
||||||
|
LEFT JOIN bet_outcomes ON bet_outcomes.bet_id = sb.bet_id
|
||||||
|
GROUP BY sb.id,
|
||||||
|
st.full_name,
|
||||||
|
st.phone_number,
|
||||||
|
st.branch_id,
|
||||||
|
st.company_id,
|
||||||
|
st.amount,
|
||||||
|
st.verified,
|
||||||
|
bets.status,
|
||||||
|
bets.total_odds;
|
||||||
|
CREATE VIEW shop_deposit_detail AS
|
||||||
|
SELECT sd.*,
|
||||||
|
st.full_name,
|
||||||
|
st.phone_number,
|
||||||
|
st.branch_id,
|
||||||
|
st.company_id,
|
||||||
|
st.amount,
|
||||||
|
st.verified AS transaction_verified
|
||||||
|
FROM shop_deposits AS sd
|
||||||
|
JOIN shop_transactions st ON st.id = sd.shop_transaction_id;
|
||||||
-- Foreign Keys
|
-- Foreign Keys
|
||||||
ALTER TABLE users
|
ALTER TABLE users
|
||||||
ADD CONSTRAINT unique_email UNIQUE (email),
|
ADD CONSTRAINT unique_email UNIQUE (email),
|
||||||
|
|
@ -384,8 +449,13 @@ ADD CONSTRAINT fk_wallet_transfer_receiver_wallet FOREIGN KEY (receiver_wallet_i
|
||||||
ADD CONSTRAINT fk_wallet_transfer_cashier FOREIGN KEY (cashier_id) REFERENCES users(id);
|
ADD CONSTRAINT fk_wallet_transfer_cashier FOREIGN KEY (cashier_id) REFERENCES users(id);
|
||||||
ALTER TABLE shop_transactions
|
ALTER TABLE shop_transactions
|
||||||
ADD CONSTRAINT fk_shop_transactions_branches FOREIGN KEY (branch_id) REFERENCES branches(id),
|
ADD CONSTRAINT fk_shop_transactions_branches FOREIGN KEY (branch_id) REFERENCES branches(id),
|
||||||
ADD CONSTRAINT fk_shop_transactions_cashiers FOREIGN KEY (cashier_id) REFERENCES users(id),
|
ADD CONSTRAINT fk_shop_transactions_users FOREIGN KEY (user_id) REFERENCES users(id);
|
||||||
ADD CONSTRAINT fk_shop_transactions_bets FOREIGN KEY (bet_id) REFERENCES bets(id);
|
ALTER TABLE shop_bets
|
||||||
|
ADD CONSTRAINT fk_shop_bet_transactions FOREIGN KEY (shop_transaction_id) REFERENCES shop_transactions(id),
|
||||||
|
ADD CONSTRAINT fk_shop_bet_bets FOREIGN KEY (bet_id) REFERENCES bets(id);
|
||||||
|
ALTER TABLE shop_deposits
|
||||||
|
ADD CONSTRAINT fk_shop_deposit_transactions FOREIGN KEY (shop_transaction_id) REFERENCES shop_transactions(id),
|
||||||
|
ADD CONSTRAINT fk_shop_deposit_customers FOREIGN KEY (customer_id) REFERENCES users(id);
|
||||||
ALTER TABLE branches
|
ALTER TABLE branches
|
||||||
ADD CONSTRAINT fk_branches_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id),
|
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);
|
ADD CONSTRAINT fk_branches_manager FOREIGN KEY (branch_manager_id) REFERENCES users(id);
|
||||||
|
|
|
||||||
169
db/query/shop_transactions.sql
Normal file
169
db/query/shop_transactions.sql
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
-- name: CreateShopTransaction :one
|
||||||
|
INSERT INTO shop_transactions (
|
||||||
|
amount,
|
||||||
|
branch_id,
|
||||||
|
company_id,
|
||||||
|
user_id,
|
||||||
|
type,
|
||||||
|
full_name,
|
||||||
|
phone_number,
|
||||||
|
payment_option,
|
||||||
|
bank_code,
|
||||||
|
beneficiary_name,
|
||||||
|
account_name,
|
||||||
|
account_number,
|
||||||
|
reference_number
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
$1,
|
||||||
|
$2,
|
||||||
|
$3,
|
||||||
|
$4,
|
||||||
|
$5,
|
||||||
|
$6,
|
||||||
|
$7,
|
||||||
|
$8,
|
||||||
|
$9,
|
||||||
|
$10,
|
||||||
|
$11,
|
||||||
|
$12,
|
||||||
|
$13
|
||||||
|
)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllShopTransactions :many
|
||||||
|
SELECT *
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
wHERE (
|
||||||
|
branch_id = sqlc.narg('branch_id')
|
||||||
|
OR sqlc.narg('branch_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
user_id = sqlc.narg('user_id')
|
||||||
|
OR sqlc.narg('user_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
full_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetShopTransactionByID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: GetShopTransactionByBranch :many
|
||||||
|
SELECT *
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
WHERE branch_id = $1;
|
||||||
|
-- name: UpdateShopTransactionVerified :exec
|
||||||
|
UPDATE shop_transactions
|
||||||
|
SET verified = $2,
|
||||||
|
approved_by = $3,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: CreateShopBet :one
|
||||||
|
INSERT INTO shop_bets (
|
||||||
|
shop_transaction_id,
|
||||||
|
cashout_id,
|
||||||
|
bet_id,
|
||||||
|
number_of_outcomes
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllShopBets :many
|
||||||
|
SELECT *
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE (
|
||||||
|
full_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
branch_id = sqlc.narg('branch_id')
|
||||||
|
OR sqlc.narg('branch_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetShopBetByID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: GetShopBetByBetID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE bet_id = $1;
|
||||||
|
-- name: GetShopBetByShopTransactionID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE shop_transaction_id = $1;
|
||||||
|
-- name: UpdateShopBetCashOut :exec
|
||||||
|
UPDATE shop_bets
|
||||||
|
SET cashed_out = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: UpdateShopBetCashoutID :exec
|
||||||
|
UPDATE shop_bets
|
||||||
|
SET cashout_id = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: CreateShopDeposit :one
|
||||||
|
INSERT INTO shop_deposits (
|
||||||
|
shop_transaction_id,
|
||||||
|
customer_id,
|
||||||
|
wallet_transfer_id
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
RETURNING *;
|
||||||
|
-- name: GetAllShopDeposit :many
|
||||||
|
SELECT *
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE (
|
||||||
|
full_name ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
|
||||||
|
OR sqlc.narg('query') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
branch_id = sqlc.narg('branch_id')
|
||||||
|
OR sqlc.narg('branch_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = sqlc.narg('company_id')
|
||||||
|
OR sqlc.narg('company_id') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > sqlc.narg('created_before')
|
||||||
|
OR sqlc.narg('created_before') IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < sqlc.narg('created_after')
|
||||||
|
OR sqlc.narg('created_after') IS NULL
|
||||||
|
);
|
||||||
|
-- name: GetShopDepositByID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE id = $1;
|
||||||
|
-- name: GetShopDepositByShopTransactionID :one
|
||||||
|
SELECT *
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE shop_transaction_id = $1;
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
-- name: CreateShopTransaction :one
|
|
||||||
INSERT INTO shop_transactions (
|
|
||||||
amount,
|
|
||||||
branch_id,
|
|
||||||
cashier_id,
|
|
||||||
bet_id,
|
|
||||||
type,
|
|
||||||
payment_option,
|
|
||||||
full_name,
|
|
||||||
phone_number,
|
|
||||||
bank_code,
|
|
||||||
beneficiary_name,
|
|
||||||
account_name,
|
|
||||||
account_number,
|
|
||||||
reference_number,
|
|
||||||
number_of_outcomes,
|
|
||||||
branch_name,
|
|
||||||
branch_location,
|
|
||||||
company_id,
|
|
||||||
cashier_name
|
|
||||||
)
|
|
||||||
VALUES (
|
|
||||||
$1,
|
|
||||||
$2,
|
|
||||||
$3,
|
|
||||||
$4,
|
|
||||||
$5,
|
|
||||||
$6,
|
|
||||||
$7,
|
|
||||||
$8,
|
|
||||||
$9,
|
|
||||||
$10,
|
|
||||||
$11,
|
|
||||||
$12,
|
|
||||||
$13,
|
|
||||||
$14,
|
|
||||||
$15,
|
|
||||||
$16,
|
|
||||||
$17,
|
|
||||||
$18
|
|
||||||
)
|
|
||||||
RETURNING *;
|
|
||||||
-- name: GetAllShopTransactions :many
|
|
||||||
SELECT *
|
|
||||||
FROM shop_transactions
|
|
||||||
wHERE (
|
|
||||||
branch_id = sqlc.narg('branch_id')
|
|
||||||
OR sqlc.narg('branch_id') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
company_id = sqlc.narg('company_id')
|
|
||||||
OR sqlc.narg('company_id') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
cashier_id = sqlc.narg('cashier_id')
|
|
||||||
OR sqlc.narg('cashier_id') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
full_name ILIKE '%' || sqlc.narg('query') || '%'
|
|
||||||
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
|
|
||||||
OR sqlc.narg('query') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
created_at > sqlc.narg('created_before')
|
|
||||||
OR sqlc.narg('created_before') IS NULL
|
|
||||||
)
|
|
||||||
AND (
|
|
||||||
created_at < sqlc.narg('created_after')
|
|
||||||
OR sqlc.narg('created_after') IS NULL
|
|
||||||
);
|
|
||||||
-- name: GetShopTransactionByID :one
|
|
||||||
SELECT *
|
|
||||||
FROM shop_transactions
|
|
||||||
WHERE id = $1;
|
|
||||||
-- name: GetShopTransactionByBranch :many
|
|
||||||
SELECT *
|
|
||||||
FROM shop_transactions
|
|
||||||
WHERE branch_id = $1;
|
|
||||||
-- name: UpdateShopTransactionVerified :exec
|
|
||||||
UPDATE shop_transactions
|
|
||||||
SET verified = $2,
|
|
||||||
approved_by = $3,
|
|
||||||
approver_name = $4,
|
|
||||||
updated_at = CURRENT_TIMESTAMP
|
|
||||||
WHERE id = $1;
|
|
||||||
106
gen/db/models.go
106
gen/db/models.go
|
|
@ -392,33 +392,113 @@ type Setting struct {
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShopBet struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CashoutID string `json:"cashout_id"`
|
||||||
|
CashedOutBy pgtype.Int8 `json:"cashed_out_by"`
|
||||||
|
BetID int64 `json:"bet_id"`
|
||||||
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
|
CashedOut bool `json:"cashed_out"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopBetDetail struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CashoutID string `json:"cashout_id"`
|
||||||
|
CashedOutBy pgtype.Int8 `json:"cashed_out_by"`
|
||||||
|
BetID int64 `json:"bet_id"`
|
||||||
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
|
CashedOut bool `json:"cashed_out"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
CustomerFullName string `json:"customer_full_name"`
|
||||||
|
CustomerPhoneNumber string `json:"customer_phone_number"`
|
||||||
|
BranchID int64 `json:"branch_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
TransactionVerified bool `json:"transaction_verified"`
|
||||||
|
Status int32 `json:"status"`
|
||||||
|
TotalOdds float32 `json:"total_odds"`
|
||||||
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDeposit struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CustomerID int64 `json:"customer_id"`
|
||||||
|
WalletTransferID int64 `json:"wallet_transfer_id"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDepositDetail struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CustomerID int64 `json:"customer_id"`
|
||||||
|
WalletTransferID int64 `json:"wallet_transfer_id"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
|
BranchID int64 `json:"branch_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
TransactionVerified bool `json:"transaction_verified"`
|
||||||
|
}
|
||||||
|
|
||||||
type ShopTransaction struct {
|
type ShopTransaction struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
BranchID int64 `json:"branch_id"`
|
BranchID int64 `json:"branch_id"`
|
||||||
CompanyID pgtype.Int8 `json:"company_id"`
|
CompanyID int64 `json:"company_id"`
|
||||||
CashierID pgtype.Int8 `json:"cashier_id"`
|
UserID int64 `json:"user_id"`
|
||||||
CashierName pgtype.Text `json:"cashier_name"`
|
Type int64 `json:"type"`
|
||||||
BetID pgtype.Int8 `json:"bet_id"`
|
FullName string `json:"full_name"`
|
||||||
NumberOfOutcomes pgtype.Int8 `json:"number_of_outcomes"`
|
PhoneNumber string `json:"phone_number"`
|
||||||
Type pgtype.Int8 `json:"type"`
|
PaymentOption int64 `json:"payment_option"`
|
||||||
PaymentOption pgtype.Int8 `json:"payment_option"`
|
|
||||||
FullName pgtype.Text `json:"full_name"`
|
|
||||||
PhoneNumber pgtype.Text `json:"phone_number"`
|
|
||||||
BankCode pgtype.Text `json:"bank_code"`
|
BankCode pgtype.Text `json:"bank_code"`
|
||||||
BeneficiaryName pgtype.Text `json:"beneficiary_name"`
|
BeneficiaryName pgtype.Text `json:"beneficiary_name"`
|
||||||
AccountName pgtype.Text `json:"account_name"`
|
AccountName pgtype.Text `json:"account_name"`
|
||||||
AccountNumber pgtype.Text `json:"account_number"`
|
AccountNumber pgtype.Text `json:"account_number"`
|
||||||
ReferenceNumber pgtype.Text `json:"reference_number"`
|
ReferenceNumber pgtype.Text `json:"reference_number"`
|
||||||
Verified bool `json:"verified"`
|
|
||||||
ApprovedBy pgtype.Int8 `json:"approved_by"`
|
ApprovedBy pgtype.Int8 `json:"approved_by"`
|
||||||
ApproverName pgtype.Text `json:"approver_name"`
|
Verified bool `json:"verified"`
|
||||||
BranchLocation pgtype.Text `json:"branch_location"`
|
|
||||||
BranchName pgtype.Text `json:"branch_name"`
|
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShopTransactionDetail struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
BranchID int64 `json:"branch_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
Type int64 `json:"type"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
|
PaymentOption int64 `json:"payment_option"`
|
||||||
|
BankCode pgtype.Text `json:"bank_code"`
|
||||||
|
BeneficiaryName pgtype.Text `json:"beneficiary_name"`
|
||||||
|
AccountName pgtype.Text `json:"account_name"`
|
||||||
|
AccountNumber pgtype.Text `json:"account_number"`
|
||||||
|
ReferenceNumber pgtype.Text `json:"reference_number"`
|
||||||
|
ApprovedBy pgtype.Int8 `json:"approved_by"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamp `json:"updated_at"`
|
||||||
|
CreatorFirstName pgtype.Text `json:"creator_first_name"`
|
||||||
|
CreatorLastName pgtype.Text `json:"creator_last_name"`
|
||||||
|
CreatorPhoneNumber pgtype.Text `json:"creator_phone_number"`
|
||||||
|
ApproverFirstName pgtype.Text `json:"approver_first_name"`
|
||||||
|
ApproverLastName pgtype.Text `json:"approver_last_name"`
|
||||||
|
ApproverPhoneNumber pgtype.Text `json:"approver_phone_number"`
|
||||||
|
BranchName pgtype.Text `json:"branch_name"`
|
||||||
|
BranchLocation pgtype.Text `json:"branch_location"`
|
||||||
|
}
|
||||||
|
|
||||||
type SupportedOperation struct {
|
type SupportedOperation struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
|
||||||
711
gen/db/shop_transactions.sql.go
Normal file
711
gen/db/shop_transactions.sql.go
Normal file
|
|
@ -0,0 +1,711 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.29.0
|
||||||
|
// source: shop_transactions.sql
|
||||||
|
|
||||||
|
package dbgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CreateShopBet = `-- name: CreateShopBet :one
|
||||||
|
INSERT INTO shop_bets (
|
||||||
|
shop_transaction_id,
|
||||||
|
cashout_id,
|
||||||
|
bet_id,
|
||||||
|
number_of_outcomes
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateShopBetParams struct {
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CashoutID string `json:"cashout_id"`
|
||||||
|
BetID int64 `json:"bet_id"`
|
||||||
|
NumberOfOutcomes int64 `json:"number_of_outcomes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateShopBet(ctx context.Context, arg CreateShopBetParams) (ShopBet, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CreateShopBet,
|
||||||
|
arg.ShopTransactionID,
|
||||||
|
arg.CashoutID,
|
||||||
|
arg.BetID,
|
||||||
|
arg.NumberOfOutcomes,
|
||||||
|
)
|
||||||
|
var i ShopBet
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CashoutID,
|
||||||
|
&i.CashedOutBy,
|
||||||
|
&i.BetID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
|
&i.CashedOut,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateShopDeposit = `-- name: CreateShopDeposit :one
|
||||||
|
INSERT INTO shop_deposits (
|
||||||
|
shop_transaction_id,
|
||||||
|
customer_id,
|
||||||
|
wallet_transfer_id
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
RETURNING id, shop_transaction_id, customer_id, wallet_transfer_id, created_at, updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateShopDepositParams struct {
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CustomerID int64 `json:"customer_id"`
|
||||||
|
WalletTransferID int64 `json:"wallet_transfer_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateShopDeposit(ctx context.Context, arg CreateShopDepositParams) (ShopDeposit, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CreateShopDeposit, arg.ShopTransactionID, arg.CustomerID, arg.WalletTransferID)
|
||||||
|
var i ShopDeposit
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.WalletTransferID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateShopTransaction = `-- name: CreateShopTransaction :one
|
||||||
|
INSERT INTO shop_transactions (
|
||||||
|
amount,
|
||||||
|
branch_id,
|
||||||
|
company_id,
|
||||||
|
user_id,
|
||||||
|
type,
|
||||||
|
full_name,
|
||||||
|
phone_number,
|
||||||
|
payment_option,
|
||||||
|
bank_code,
|
||||||
|
beneficiary_name,
|
||||||
|
account_name,
|
||||||
|
account_number,
|
||||||
|
reference_number
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
$1,
|
||||||
|
$2,
|
||||||
|
$3,
|
||||||
|
$4,
|
||||||
|
$5,
|
||||||
|
$6,
|
||||||
|
$7,
|
||||||
|
$8,
|
||||||
|
$9,
|
||||||
|
$10,
|
||||||
|
$11,
|
||||||
|
$12,
|
||||||
|
$13
|
||||||
|
)
|
||||||
|
RETURNING id, amount, branch_id, company_id, user_id, type, full_name, phone_number, payment_option, bank_code, beneficiary_name, account_name, account_number, reference_number, approved_by, verified, created_at, updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateShopTransactionParams struct {
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
BranchID int64 `json:"branch_id"`
|
||||||
|
CompanyID int64 `json:"company_id"`
|
||||||
|
UserID int64 `json:"user_id"`
|
||||||
|
Type int64 `json:"type"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
|
PaymentOption int64 `json:"payment_option"`
|
||||||
|
BankCode pgtype.Text `json:"bank_code"`
|
||||||
|
BeneficiaryName pgtype.Text `json:"beneficiary_name"`
|
||||||
|
AccountName pgtype.Text `json:"account_name"`
|
||||||
|
AccountNumber pgtype.Text `json:"account_number"`
|
||||||
|
ReferenceNumber pgtype.Text `json:"reference_number"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateShopTransaction(ctx context.Context, arg CreateShopTransactionParams) (ShopTransaction, error) {
|
||||||
|
row := q.db.QueryRow(ctx, CreateShopTransaction,
|
||||||
|
arg.Amount,
|
||||||
|
arg.BranchID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.UserID,
|
||||||
|
arg.Type,
|
||||||
|
arg.FullName,
|
||||||
|
arg.PhoneNumber,
|
||||||
|
arg.PaymentOption,
|
||||||
|
arg.BankCode,
|
||||||
|
arg.BeneficiaryName,
|
||||||
|
arg.AccountName,
|
||||||
|
arg.AccountNumber,
|
||||||
|
arg.ReferenceNumber,
|
||||||
|
)
|
||||||
|
var i ShopTransaction
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Type,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.PaymentOption,
|
||||||
|
&i.BankCode,
|
||||||
|
&i.BeneficiaryName,
|
||||||
|
&i.AccountName,
|
||||||
|
&i.AccountNumber,
|
||||||
|
&i.ReferenceNumber,
|
||||||
|
&i.ApprovedBy,
|
||||||
|
&i.Verified,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllShopBets = `-- name: GetAllShopBets :many
|
||||||
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE (
|
||||||
|
full_name ILIKE '%' || $1 || '%'
|
||||||
|
OR phone_number ILIKE '%' || $1 || '%'
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
branch_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllShopBetsParams struct {
|
||||||
|
Query pgtype.Text `json:"query"`
|
||||||
|
BranchID pgtype.Int8 `json:"branch_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllShopBets(ctx context.Context, arg GetAllShopBetsParams) ([]ShopBetDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllShopBets,
|
||||||
|
arg.Query,
|
||||||
|
arg.BranchID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ShopBetDetail
|
||||||
|
for rows.Next() {
|
||||||
|
var i ShopBetDetail
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CashoutID,
|
||||||
|
&i.CashedOutBy,
|
||||||
|
&i.BetID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
|
&i.CashedOut,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CustomerFullName,
|
||||||
|
&i.CustomerPhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
&i.Status,
|
||||||
|
&i.TotalOdds,
|
||||||
|
&i.Outcomes,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllShopDeposit = `-- name: GetAllShopDeposit :many
|
||||||
|
SELECT id, shop_transaction_id, customer_id, wallet_transfer_id, created_at, updated_at, full_name, phone_number, branch_id, company_id, amount, transaction_verified
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE (
|
||||||
|
full_name ILIKE '%' || $1 || '%'
|
||||||
|
OR phone_number ILIKE '%' || $1 || '%'
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
branch_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $4
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllShopDepositParams struct {
|
||||||
|
Query pgtype.Text `json:"query"`
|
||||||
|
BranchID pgtype.Int8 `json:"branch_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllShopDeposit(ctx context.Context, arg GetAllShopDepositParams) ([]ShopDepositDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllShopDeposit,
|
||||||
|
arg.Query,
|
||||||
|
arg.BranchID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ShopDepositDetail
|
||||||
|
for rows.Next() {
|
||||||
|
var i ShopDepositDetail
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.WalletTransferID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAllShopTransactions = `-- name: GetAllShopTransactions :many
|
||||||
|
SELECT id, amount, branch_id, company_id, user_id, type, full_name, phone_number, payment_option, bank_code, beneficiary_name, account_name, account_number, reference_number, approved_by, verified, created_at, updated_at, creator_first_name, creator_last_name, creator_phone_number, approver_first_name, approver_last_name, approver_phone_number, branch_name, branch_location
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
wHERE (
|
||||||
|
branch_id = $1
|
||||||
|
OR $1 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
company_id = $2
|
||||||
|
OR $2 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
user_id = $3
|
||||||
|
OR $3 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
full_name ILIKE '%' || $4 || '%'
|
||||||
|
OR phone_number ILIKE '%' || $4 || '%'
|
||||||
|
OR $4 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at > $5
|
||||||
|
OR $5 IS NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
created_at < $6
|
||||||
|
OR $6 IS NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllShopTransactionsParams struct {
|
||||||
|
BranchID pgtype.Int8 `json:"branch_id"`
|
||||||
|
CompanyID pgtype.Int8 `json:"company_id"`
|
||||||
|
UserID pgtype.Int8 `json:"user_id"`
|
||||||
|
Query pgtype.Text `json:"query"`
|
||||||
|
CreatedBefore pgtype.Timestamp `json:"created_before"`
|
||||||
|
CreatedAfter pgtype.Timestamp `json:"created_after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllShopTransactions(ctx context.Context, arg GetAllShopTransactionsParams) ([]ShopTransactionDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetAllShopTransactions,
|
||||||
|
arg.BranchID,
|
||||||
|
arg.CompanyID,
|
||||||
|
arg.UserID,
|
||||||
|
arg.Query,
|
||||||
|
arg.CreatedBefore,
|
||||||
|
arg.CreatedAfter,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ShopTransactionDetail
|
||||||
|
for rows.Next() {
|
||||||
|
var i ShopTransactionDetail
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Type,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.PaymentOption,
|
||||||
|
&i.BankCode,
|
||||||
|
&i.BeneficiaryName,
|
||||||
|
&i.AccountName,
|
||||||
|
&i.AccountNumber,
|
||||||
|
&i.ReferenceNumber,
|
||||||
|
&i.ApprovedBy,
|
||||||
|
&i.Verified,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CreatorFirstName,
|
||||||
|
&i.CreatorLastName,
|
||||||
|
&i.CreatorPhoneNumber,
|
||||||
|
&i.ApproverFirstName,
|
||||||
|
&i.ApproverLastName,
|
||||||
|
&i.ApproverPhoneNumber,
|
||||||
|
&i.BranchName,
|
||||||
|
&i.BranchLocation,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopBetByBetID = `-- name: GetShopBetByBetID :one
|
||||||
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE bet_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopBetByBetID(ctx context.Context, betID int64) (ShopBetDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopBetByBetID, betID)
|
||||||
|
var i ShopBetDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CashoutID,
|
||||||
|
&i.CashedOutBy,
|
||||||
|
&i.BetID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
|
&i.CashedOut,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CustomerFullName,
|
||||||
|
&i.CustomerPhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
&i.Status,
|
||||||
|
&i.TotalOdds,
|
||||||
|
&i.Outcomes,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopBetByID = `-- name: GetShopBetByID :one
|
||||||
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopBetByID(ctx context.Context, id int64) (ShopBetDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopBetByID, id)
|
||||||
|
var i ShopBetDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CashoutID,
|
||||||
|
&i.CashedOutBy,
|
||||||
|
&i.BetID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
|
&i.CashedOut,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CustomerFullName,
|
||||||
|
&i.CustomerPhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
&i.Status,
|
||||||
|
&i.TotalOdds,
|
||||||
|
&i.Outcomes,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopBetByShopTransactionID = `-- name: GetShopBetByShopTransactionID :one
|
||||||
|
SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes
|
||||||
|
FROM shop_bet_detail
|
||||||
|
WHERE shop_transaction_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopBetByShopTransactionID(ctx context.Context, shopTransactionID int64) (ShopBetDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopBetByShopTransactionID, shopTransactionID)
|
||||||
|
var i ShopBetDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CashoutID,
|
||||||
|
&i.CashedOutBy,
|
||||||
|
&i.BetID,
|
||||||
|
&i.NumberOfOutcomes,
|
||||||
|
&i.CashedOut,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CustomerFullName,
|
||||||
|
&i.CustomerPhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
&i.Status,
|
||||||
|
&i.TotalOdds,
|
||||||
|
&i.Outcomes,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopDepositByID = `-- name: GetShopDepositByID :one
|
||||||
|
SELECT id, shop_transaction_id, customer_id, wallet_transfer_id, created_at, updated_at, full_name, phone_number, branch_id, company_id, amount, transaction_verified
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopDepositByID(ctx context.Context, id int64) (ShopDepositDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopDepositByID, id)
|
||||||
|
var i ShopDepositDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.WalletTransferID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopDepositByShopTransactionID = `-- name: GetShopDepositByShopTransactionID :one
|
||||||
|
SELECT id, shop_transaction_id, customer_id, wallet_transfer_id, created_at, updated_at, full_name, phone_number, branch_id, company_id, amount, transaction_verified
|
||||||
|
FROM shop_deposit_detail
|
||||||
|
WHERE shop_transaction_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopDepositByShopTransactionID(ctx context.Context, shopTransactionID int64) (ShopDepositDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopDepositByShopTransactionID, shopTransactionID)
|
||||||
|
var i ShopDepositDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.ShopTransactionID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.WalletTransferID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.TransactionVerified,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopTransactionByBranch = `-- name: GetShopTransactionByBranch :many
|
||||||
|
SELECT id, amount, branch_id, company_id, user_id, type, full_name, phone_number, payment_option, bank_code, beneficiary_name, account_name, account_number, reference_number, approved_by, verified, created_at, updated_at, creator_first_name, creator_last_name, creator_phone_number, approver_first_name, approver_last_name, approver_phone_number, branch_name, branch_location
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
WHERE branch_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopTransactionByBranch(ctx context.Context, branchID int64) ([]ShopTransactionDetail, error) {
|
||||||
|
rows, err := q.db.Query(ctx, GetShopTransactionByBranch, branchID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ShopTransactionDetail
|
||||||
|
for rows.Next() {
|
||||||
|
var i ShopTransactionDetail
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Type,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.PaymentOption,
|
||||||
|
&i.BankCode,
|
||||||
|
&i.BeneficiaryName,
|
||||||
|
&i.AccountName,
|
||||||
|
&i.AccountNumber,
|
||||||
|
&i.ReferenceNumber,
|
||||||
|
&i.ApprovedBy,
|
||||||
|
&i.Verified,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CreatorFirstName,
|
||||||
|
&i.CreatorLastName,
|
||||||
|
&i.CreatorPhoneNumber,
|
||||||
|
&i.ApproverFirstName,
|
||||||
|
&i.ApproverLastName,
|
||||||
|
&i.ApproverPhoneNumber,
|
||||||
|
&i.BranchName,
|
||||||
|
&i.BranchLocation,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetShopTransactionByID = `-- name: GetShopTransactionByID :one
|
||||||
|
SELECT id, amount, branch_id, company_id, user_id, type, full_name, phone_number, payment_option, bank_code, beneficiary_name, account_name, account_number, reference_number, approved_by, verified, created_at, updated_at, creator_first_name, creator_last_name, creator_phone_number, approver_first_name, approver_last_name, approver_phone_number, branch_name, branch_location
|
||||||
|
FROM shop_transaction_detail
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetShopTransactionByID(ctx context.Context, id int64) (ShopTransactionDetail, error) {
|
||||||
|
row := q.db.QueryRow(ctx, GetShopTransactionByID, id)
|
||||||
|
var i ShopTransactionDetail
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Amount,
|
||||||
|
&i.BranchID,
|
||||||
|
&i.CompanyID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Type,
|
||||||
|
&i.FullName,
|
||||||
|
&i.PhoneNumber,
|
||||||
|
&i.PaymentOption,
|
||||||
|
&i.BankCode,
|
||||||
|
&i.BeneficiaryName,
|
||||||
|
&i.AccountName,
|
||||||
|
&i.AccountNumber,
|
||||||
|
&i.ReferenceNumber,
|
||||||
|
&i.ApprovedBy,
|
||||||
|
&i.Verified,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.CreatorFirstName,
|
||||||
|
&i.CreatorLastName,
|
||||||
|
&i.CreatorPhoneNumber,
|
||||||
|
&i.ApproverFirstName,
|
||||||
|
&i.ApproverLastName,
|
||||||
|
&i.ApproverPhoneNumber,
|
||||||
|
&i.BranchName,
|
||||||
|
&i.BranchLocation,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateShopBetCashOut = `-- name: UpdateShopBetCashOut :exec
|
||||||
|
UPDATE shop_bets
|
||||||
|
SET cashed_out = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateShopBetCashOutParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CashedOut bool `json:"cashed_out"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateShopBetCashOut(ctx context.Context, arg UpdateShopBetCashOutParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateShopBetCashOut, arg.ID, arg.CashedOut)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateShopBetCashoutID = `-- name: UpdateShopBetCashoutID :exec
|
||||||
|
UPDATE shop_bets
|
||||||
|
SET cashout_id = $2,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateShopBetCashoutIDParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
CashoutID string `json:"cashout_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateShopBetCashoutID(ctx context.Context, arg UpdateShopBetCashoutIDParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateShopBetCashoutID, arg.ID, arg.CashoutID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateShopTransactionVerified = `-- name: UpdateShopTransactionVerified :exec
|
||||||
|
UPDATE shop_transactions
|
||||||
|
SET verified = $2,
|
||||||
|
approved_by = $3,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateShopTransactionVerifiedParams struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
ApprovedBy pgtype.Int8 `json:"approved_by"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateShopTransactionVerified(ctx context.Context, arg UpdateShopTransactionVerifiedParams) error {
|
||||||
|
_, err := q.db.Exec(ctx, UpdateShopTransactionVerified, arg.ID, arg.Verified, arg.ApprovedBy)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
@ -106,7 +106,6 @@ type CreateBetOutcomeReq struct {
|
||||||
type CreateBetReq struct {
|
type CreateBetReq struct {
|
||||||
Outcomes []CreateBetOutcomeReq `json:"outcomes"`
|
Outcomes []CreateBetOutcomeReq `json:"outcomes"`
|
||||||
Amount float32 `json:"amount" example:"100.0"`
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
Status OutcomeStatus `json:"status" example:"1"`
|
|
||||||
FullName string `json:"full_name" example:"John"`
|
FullName string `json:"full_name" example:"John"`
|
||||||
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
||||||
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
||||||
|
|
|
||||||
125
internal/domain/shop_bet.go
Normal file
125
internal/domain/shop_bet.go
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ShopBet struct {
|
||||||
|
ID int64
|
||||||
|
ShopTransactionID int64
|
||||||
|
CashoutID string
|
||||||
|
CashedOut bool
|
||||||
|
BetID int64
|
||||||
|
NumberOfOutcomes int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopBetFilter struct {
|
||||||
|
CompanyID ValidInt64
|
||||||
|
BranchID ValidInt64
|
||||||
|
Query ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateShopBet struct {
|
||||||
|
ShopTransactionID int64
|
||||||
|
CashoutID string
|
||||||
|
BetID int64
|
||||||
|
NumberOfOutcomes int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopBetDetail struct {
|
||||||
|
ID int64
|
||||||
|
ShopTransactionID int64
|
||||||
|
TotalOdds float32
|
||||||
|
BranchID int64
|
||||||
|
CompanyID int64
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
CashoutID string
|
||||||
|
CashedOut bool
|
||||||
|
BetID int64
|
||||||
|
NumberOfOutcomes int64
|
||||||
|
Status OutcomeStatus
|
||||||
|
Amount Currency
|
||||||
|
Outcomes []BetOutcome
|
||||||
|
TransactionVerified bool
|
||||||
|
UpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopBetReq struct {
|
||||||
|
Outcomes []CreateBetOutcomeReq `json:"outcomes"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
BetID int64 `json:"bet_id" example:"1"`
|
||||||
|
PaymentOption PaymentOption `json:"payment_option" example:"1"`
|
||||||
|
FullName string `json:"full_name" example:"John Smith"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"0911111111"`
|
||||||
|
BankCode string `json:"bank_code"`
|
||||||
|
BeneficiaryName string `json:"beneficiary_name"`
|
||||||
|
AccountName string `json:"account_name"`
|
||||||
|
AccountNumber string `json:"account_number"`
|
||||||
|
ReferenceNumber string `json:"reference_number"`
|
||||||
|
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CashoutReq struct {
|
||||||
|
CashoutID string `json:"cashout_id" example:"1234"`
|
||||||
|
PaymentOption PaymentOption `json:"payment_option" example:"1"`
|
||||||
|
BankCode string `json:"bank_code"`
|
||||||
|
BeneficiaryName string `json:"beneficiary_name"`
|
||||||
|
AccountName string `json:"account_name"`
|
||||||
|
AccountNumber string `json:"account_number"`
|
||||||
|
ReferenceNumber string `json:"reference_number"`
|
||||||
|
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopBetRes struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
|
BranchID int64 `json:"branch_id" example:"2"`
|
||||||
|
CompanyID int64 `json:"company_id" example:"2"`
|
||||||
|
FullName string `json:"full_name" example:"John"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
||||||
|
CashoutID string `json:"cashout_id" example:"21234"`
|
||||||
|
CashedOut bool `json:"cashed_out" example:"false"`
|
||||||
|
BetID int64 `json:"bet_id" example:"1"`
|
||||||
|
NumberOfOutcomes int64 `json:"number_of_outcomes" example:"1"`
|
||||||
|
Status OutcomeStatus `json:"status" example:"1"`
|
||||||
|
Amount Currency `json:"amount" example:"100.0"`
|
||||||
|
Outcomes []BetOutcome `json:"outcomes"`
|
||||||
|
TransactionVerified bool `json:"transaction_verified" example:"true"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at" example:"2025-04-08T12:00:00Z"`
|
||||||
|
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertShopBet(shopBet ShopBet) ShopBetRes {
|
||||||
|
return ShopBetRes{
|
||||||
|
ID: shopBet.ID,
|
||||||
|
ShopTransactionID: shopBet.ShopTransactionID,
|
||||||
|
CashoutID: shopBet.CashoutID,
|
||||||
|
CashedOut: shopBet.CashedOut,
|
||||||
|
BetID: shopBet.BetID,
|
||||||
|
NumberOfOutcomes: shopBet.NumberOfOutcomes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func ConvertShopBetDetail(shopBet ShopBetDetail) ShopBetRes {
|
||||||
|
return ShopBetRes{
|
||||||
|
ID: shopBet.ID,
|
||||||
|
ShopTransactionID: shopBet.ShopTransactionID,
|
||||||
|
TotalOdds: shopBet.TotalOdds,
|
||||||
|
BranchID: shopBet.BranchID,
|
||||||
|
CompanyID: shopBet.CompanyID,
|
||||||
|
FullName: shopBet.FullName,
|
||||||
|
PhoneNumber: shopBet.PhoneNumber,
|
||||||
|
CashoutID: shopBet.CashoutID,
|
||||||
|
CashedOut: shopBet.CashedOut,
|
||||||
|
BetID: shopBet.BetID,
|
||||||
|
NumberOfOutcomes: shopBet.NumberOfOutcomes,
|
||||||
|
Status: shopBet.Status,
|
||||||
|
Amount: shopBet.Amount,
|
||||||
|
Outcomes: shopBet.Outcomes,
|
||||||
|
TransactionVerified: shopBet.TransactionVerified,
|
||||||
|
UpdatedAt: shopBet.UpdatedAt,
|
||||||
|
CreatedAt: shopBet.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
68
internal/domain/shop_deposit.go
Normal file
68
internal/domain/shop_deposit.go
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ShopDeposit struct {
|
||||||
|
ID int64
|
||||||
|
ShopTransactionID int64
|
||||||
|
CustomerID int64
|
||||||
|
WalletTransferID int64
|
||||||
|
}
|
||||||
|
type CreateShopDeposit struct {
|
||||||
|
ShopTransactionID int64
|
||||||
|
CustomerID int64
|
||||||
|
WalletTransferID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDepositFilter struct {
|
||||||
|
CompanyID ValidInt64
|
||||||
|
BranchID ValidInt64
|
||||||
|
Query ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDepositDetail struct {
|
||||||
|
ID int64
|
||||||
|
ShopTransactionID int64
|
||||||
|
CustomerID int64
|
||||||
|
WalletTransferID int64
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
Amount Currency
|
||||||
|
BranchID int64
|
||||||
|
CompanyID int64
|
||||||
|
TransactionVerified bool
|
||||||
|
UpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDepositReq struct {
|
||||||
|
CustomerID int64 `json:"customer_id" example:"1"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
PaymentOption PaymentOption `json:"payment_option" example:"1"`
|
||||||
|
FullName string `json:"full_name" example:"John Smith"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"0911111111"`
|
||||||
|
BankCode string `json:"bank_code"`
|
||||||
|
BeneficiaryName string `json:"beneficiary_name"`
|
||||||
|
AccountName string `json:"account_name"`
|
||||||
|
AccountNumber string `json:"account_number"`
|
||||||
|
ReferenceNumber string `json:"reference_number"`
|
||||||
|
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopDepositRes struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
ShopTransactionID int64 `json:"shop_transaction_id"`
|
||||||
|
CustomerID int64 `json:"customer_id"`
|
||||||
|
WalletTransferID int64 `json:"wallet_transfer_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertShopDeposit(shopDeposit ShopDeposit) ShopDepositRes {
|
||||||
|
return ShopDepositRes{
|
||||||
|
ID: shopDeposit.ID,
|
||||||
|
ShopTransactionID: shopDeposit.ShopTransactionID,
|
||||||
|
CustomerID: shopDeposit.CustomerID,
|
||||||
|
WalletTransferID: shopDeposit.WalletTransferID,
|
||||||
|
}
|
||||||
|
}
|
||||||
189
internal/domain/shop_transaction.go
Normal file
189
internal/domain/shop_transaction.go
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ShopTransactionType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
TRANSACTION_CASHOUT ShopTransactionType = iota
|
||||||
|
TRANSACTION_DEPOSIT
|
||||||
|
TRANSACTION_BET
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaymentOption int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
CASH_TRANSACTION PaymentOption = iota
|
||||||
|
TELEBIRR_TRANSACTION
|
||||||
|
ARIFPAY_TRANSACTION
|
||||||
|
BANK
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShopTransaction only represents branch transactions
|
||||||
|
// This is only used for statistic data
|
||||||
|
type ShopTransaction struct {
|
||||||
|
ID int64
|
||||||
|
Amount Currency
|
||||||
|
BranchID int64
|
||||||
|
CompanyID int64
|
||||||
|
UserID int64
|
||||||
|
Type ShopTransactionType
|
||||||
|
PaymentOption PaymentOption
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
// Payment Details for bank
|
||||||
|
BankCode ValidString
|
||||||
|
BeneficiaryName ValidString
|
||||||
|
AccountName ValidString
|
||||||
|
AccountNumber ValidString
|
||||||
|
ReferenceNumber ValidString
|
||||||
|
Verified bool
|
||||||
|
ApprovedBy ValidInt64
|
||||||
|
UpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopTransactionRes struct {
|
||||||
|
ID int64 `json:"id" example:"1"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
BranchID int64 `json:"branch_id" example:"1"`
|
||||||
|
BranchName string `json:"branch_name" example:"Branch Name"`
|
||||||
|
BranchLocation string `json:"branch_location" example:"Branch Location"`
|
||||||
|
CompanyID int64 `json:"company_id" example:"1"`
|
||||||
|
UserID int64 `json:"user_id" example:"1"`
|
||||||
|
CreatorFirstName string `json:"creator_first_name" example:"John"`
|
||||||
|
CreatorLastName string `json:"creator_last_name" example:"Smith"`
|
||||||
|
CreatorPhoneNumber string `json:"creator_phone_number" example:"0911111111"`
|
||||||
|
CashierName string `json:"cashier_name" example:"John Smith"`
|
||||||
|
Type int64 `json:"type" example:"1"`
|
||||||
|
PaymentOption PaymentOption `json:"payment_option" example:"1"`
|
||||||
|
FullName string `json:"full_name" example:"John Smith"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"0911111111"`
|
||||||
|
BankCode string `json:"bank_code"`
|
||||||
|
BeneficiaryName string `json:"beneficiary_name"`
|
||||||
|
AccountName string `json:"account_name"`
|
||||||
|
AccountNumber string `json:"account_number"`
|
||||||
|
ReferenceNumber string `json:"reference_number"`
|
||||||
|
Verified bool `json:"verified" example:"true"`
|
||||||
|
ApprovedBy int64 `json:"approved_by" example:"1"`
|
||||||
|
ApproverFirstName string `json:"approver_first_name" example:"John"`
|
||||||
|
ApproverLastName string `json:"approver_last_name" example:"Smith"`
|
||||||
|
ApproverPhoneNumber string `json:"approver_phone_number" example:"0911111111"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopTransactionDetail struct {
|
||||||
|
ID int64
|
||||||
|
Amount Currency
|
||||||
|
BranchID int64
|
||||||
|
BranchName string
|
||||||
|
BranchLocation string
|
||||||
|
CompanyID int64
|
||||||
|
UserID int64
|
||||||
|
CreatorFirstName string
|
||||||
|
CreatorLastName string
|
||||||
|
CreatorPhoneNumber string
|
||||||
|
Type ShopTransactionType
|
||||||
|
PaymentOption PaymentOption
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
// Payment Details for bank
|
||||||
|
BankCode ValidString
|
||||||
|
BeneficiaryName ValidString
|
||||||
|
AccountName ValidString
|
||||||
|
AccountNumber ValidString
|
||||||
|
ReferenceNumber ValidString
|
||||||
|
Verified bool
|
||||||
|
ApprovedBy ValidInt64
|
||||||
|
ApproverFirstName ValidString
|
||||||
|
ApproverLastName ValidString
|
||||||
|
ApproverPhoneNumber ValidString
|
||||||
|
UpdatedAt time.Time
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShopTransactionFilter struct {
|
||||||
|
CompanyID ValidInt64
|
||||||
|
BranchID ValidInt64
|
||||||
|
UserID ValidInt64
|
||||||
|
Query ValidString
|
||||||
|
CreatedBefore ValidTime
|
||||||
|
CreatedAfter ValidTime
|
||||||
|
}
|
||||||
|
type CreateShopTransaction struct {
|
||||||
|
Amount Currency
|
||||||
|
BranchID int64
|
||||||
|
CompanyID int64
|
||||||
|
UserID int64
|
||||||
|
Type ShopTransactionType
|
||||||
|
PaymentOption PaymentOption
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
// Payment Details for bank
|
||||||
|
BankCode ValidString
|
||||||
|
BeneficiaryName ValidString
|
||||||
|
AccountName ValidString
|
||||||
|
AccountNumber ValidString
|
||||||
|
ReferenceNumber ValidString
|
||||||
|
Verified bool
|
||||||
|
ApprovedBy ValidInt64
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertShopTransaction(transaction ShopTransaction) ShopTransactionRes {
|
||||||
|
newTransaction := ShopTransactionRes{
|
||||||
|
ID: transaction.ID,
|
||||||
|
Amount: transaction.Amount.Float32(),
|
||||||
|
BranchID: transaction.BranchID,
|
||||||
|
CompanyID: transaction.CompanyID,
|
||||||
|
UserID: transaction.UserID,
|
||||||
|
Type: int64(transaction.Type),
|
||||||
|
PaymentOption: transaction.PaymentOption,
|
||||||
|
FullName: transaction.FullName,
|
||||||
|
PhoneNumber: transaction.PhoneNumber,
|
||||||
|
BankCode: transaction.BankCode.Value,
|
||||||
|
BeneficiaryName: transaction.BeneficiaryName.Value,
|
||||||
|
AccountName: transaction.AccountName.Value,
|
||||||
|
AccountNumber: transaction.AccountNumber.Value,
|
||||||
|
ReferenceNumber: transaction.ReferenceNumber.Value,
|
||||||
|
Verified: transaction.Verified,
|
||||||
|
ApprovedBy: transaction.ApprovedBy.Value,
|
||||||
|
CreatedAt: transaction.CreatedAt,
|
||||||
|
UpdatedAt: transaction.UpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return newTransaction
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertShopTransactionDetail(transaction ShopTransactionDetail) ShopTransactionRes {
|
||||||
|
newTransaction := ShopTransactionRes{
|
||||||
|
ID: transaction.ID,
|
||||||
|
Amount: transaction.Amount.Float32(),
|
||||||
|
BranchID: transaction.BranchID,
|
||||||
|
BranchName: transaction.BranchName,
|
||||||
|
BranchLocation: transaction.BranchLocation,
|
||||||
|
CompanyID: transaction.CompanyID,
|
||||||
|
UserID: transaction.UserID,
|
||||||
|
CreatorFirstName: transaction.CreatorFirstName,
|
||||||
|
CreatorLastName: transaction.CreatorLastName,
|
||||||
|
CreatorPhoneNumber: transaction.CreatorPhoneNumber,
|
||||||
|
Type: int64(transaction.Type),
|
||||||
|
PaymentOption: transaction.PaymentOption,
|
||||||
|
FullName: transaction.FullName,
|
||||||
|
PhoneNumber: transaction.PhoneNumber,
|
||||||
|
BankCode: transaction.BankCode.Value,
|
||||||
|
BeneficiaryName: transaction.BeneficiaryName.Value,
|
||||||
|
AccountName: transaction.AccountName.Value,
|
||||||
|
AccountNumber: transaction.AccountNumber.Value,
|
||||||
|
ReferenceNumber: transaction.ReferenceNumber.Value,
|
||||||
|
Verified: transaction.Verified,
|
||||||
|
ApprovedBy: transaction.ApprovedBy.Value,
|
||||||
|
ApproverFirstName: transaction.ApproverFirstName.Value,
|
||||||
|
ApproverLastName: transaction.ApproverLastName.Value,
|
||||||
|
ApproverPhoneNumber: transaction.ApproverPhoneNumber.Value,
|
||||||
|
CreatedAt: transaction.CreatedAt,
|
||||||
|
UpdatedAt: transaction.UpdatedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return newTransaction
|
||||||
|
}
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type ShopTransactionType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
TRANSACTION_CASHOUT ShopTransactionType = iota
|
|
||||||
TRANSACTION_DEPOSIT
|
|
||||||
)
|
|
||||||
|
|
||||||
type PaymentOption int64
|
|
||||||
|
|
||||||
const (
|
|
||||||
CASH_TRANSACTION PaymentOption = iota
|
|
||||||
TELEBIRR_TRANSACTION
|
|
||||||
ARIFPAY_TRANSACTION
|
|
||||||
BANK
|
|
||||||
)
|
|
||||||
|
|
||||||
// ShopTransaction only represents branch transactions
|
|
||||||
// This is only used for statistic data
|
|
||||||
type ShopTransaction struct {
|
|
||||||
ID int64
|
|
||||||
Amount Currency
|
|
||||||
BranchID int64
|
|
||||||
BranchName string
|
|
||||||
BranchLocation string
|
|
||||||
CompanyID int64
|
|
||||||
CashierID int64
|
|
||||||
CashierName string
|
|
||||||
BetID int64
|
|
||||||
NumberOfOutcomes int64
|
|
||||||
Type ShopTransactionType
|
|
||||||
PaymentOption PaymentOption
|
|
||||||
FullName string
|
|
||||||
PhoneNumber string
|
|
||||||
// Payment Details for bank
|
|
||||||
BankCode string
|
|
||||||
BeneficiaryName string
|
|
||||||
AccountName string
|
|
||||||
AccountNumber string
|
|
||||||
ReferenceNumber string
|
|
||||||
Verified bool
|
|
||||||
ApprovedBy ValidInt64
|
|
||||||
ApproverName ValidString
|
|
||||||
UpdatedAt time.Time
|
|
||||||
CreatedAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShopTransactionFilter struct {
|
|
||||||
CompanyID ValidInt64
|
|
||||||
BranchID ValidInt64
|
|
||||||
CashierID ValidInt64
|
|
||||||
Query ValidString
|
|
||||||
CreatedBefore ValidTime
|
|
||||||
CreatedAfter ValidTime
|
|
||||||
}
|
|
||||||
type CreateShopTransaction struct {
|
|
||||||
Amount Currency
|
|
||||||
BranchID int64
|
|
||||||
CashierID int64
|
|
||||||
BetID int64
|
|
||||||
NumberOfOutcomes int64
|
|
||||||
Type ShopTransactionType
|
|
||||||
PaymentOption PaymentOption
|
|
||||||
FullName string
|
|
||||||
PhoneNumber string
|
|
||||||
BankCode string
|
|
||||||
BeneficiaryName string
|
|
||||||
AccountName string
|
|
||||||
AccountNumber string
|
|
||||||
ReferenceNumber string
|
|
||||||
BranchName string
|
|
||||||
BranchLocation string
|
|
||||||
CompanyID int64
|
|
||||||
CashierName string
|
|
||||||
}
|
|
||||||
155
internal/repository/shop_bet.go
Normal file
155
internal/repository/shop_bet.go
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertDBShopBet(bet dbgen.ShopBet) domain.ShopBet {
|
||||||
|
return domain.ShopBet{
|
||||||
|
ID: bet.ID,
|
||||||
|
ShopTransactionID: bet.ShopTransactionID,
|
||||||
|
CashoutID: bet.CashoutID,
|
||||||
|
CashedOut: bet.CashedOut,
|
||||||
|
BetID: bet.BetID,
|
||||||
|
NumberOfOutcomes: bet.NumberOfOutcomes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertDBShopBetDetail(bet dbgen.ShopBetDetail) domain.ShopBetDetail {
|
||||||
|
var outcomes []domain.BetOutcome = make([]domain.BetOutcome, 0, len(bet.Outcomes))
|
||||||
|
|
||||||
|
for _, outcome := range bet.Outcomes {
|
||||||
|
outcomes = append(outcomes, convertDBBetOutcomes(outcome))
|
||||||
|
}
|
||||||
|
return domain.ShopBetDetail{
|
||||||
|
ID: bet.ID,
|
||||||
|
ShopTransactionID: bet.ShopTransactionID,
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
BranchID: bet.BranchID,
|
||||||
|
CompanyID: bet.CompanyID,
|
||||||
|
FullName: bet.CustomerFullName,
|
||||||
|
PhoneNumber: bet.CustomerPhoneNumber,
|
||||||
|
CashoutID: bet.CashoutID,
|
||||||
|
CashedOut: bet.CashedOut,
|
||||||
|
BetID: bet.BetID,
|
||||||
|
NumberOfOutcomes: bet.NumberOfOutcomes,
|
||||||
|
Status: domain.OutcomeStatus(bet.Status),
|
||||||
|
Amount: domain.Currency(bet.Amount),
|
||||||
|
Outcomes: outcomes,
|
||||||
|
TransactionVerified: bet.TransactionVerified,
|
||||||
|
UpdatedAt: bet.UpdatedAt.Time,
|
||||||
|
CreatedAt: bet.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertCreateShopBet(bet domain.CreateShopBet) dbgen.CreateShopBetParams {
|
||||||
|
return dbgen.CreateShopBetParams{
|
||||||
|
ShopTransactionID: bet.ShopTransactionID,
|
||||||
|
CashoutID: bet.CashoutID,
|
||||||
|
BetID: bet.BetID,
|
||||||
|
NumberOfOutcomes: bet.NumberOfOutcomes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (domain.ShopBet, error) {
|
||||||
|
newShopBet, err := s.queries.CreateShopBet(ctx, convertCreateShopBet(bet))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertDBShopBet(newShopBet), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllShopBet(ctx context.Context, filter domain.ShopBetFilter) ([]domain.ShopBetDetail, error) {
|
||||||
|
bets, err := s.queries.GetAllShopBets(ctx, dbgen.GetAllShopBetsParams{
|
||||||
|
BranchID: pgtype.Int8{
|
||||||
|
Int64: filter.BranchID.Value,
|
||||||
|
Valid: filter.BranchID.Valid,
|
||||||
|
},
|
||||||
|
CompanyID: pgtype.Int8{
|
||||||
|
Int64: filter.CompanyID.Value,
|
||||||
|
Valid: filter.CompanyID.Valid,
|
||||||
|
},
|
||||||
|
Query: pgtype.Text{
|
||||||
|
String: filter.Query.Value,
|
||||||
|
Valid: filter.Query.Valid,
|
||||||
|
},
|
||||||
|
CreatedBefore: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedBefore.Value,
|
||||||
|
Valid: filter.CreatedBefore.Valid,
|
||||||
|
},
|
||||||
|
CreatedAfter: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedAfter.Value,
|
||||||
|
Valid: filter.CreatedAfter.Valid,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []domain.ShopBetDetail = make([]domain.ShopBetDetail, 0, len(bets))
|
||||||
|
for _, bet := range bets {
|
||||||
|
result = append(result, convertDBShopBetDetail(bet))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDetail, error) {
|
||||||
|
bet, err := s.queries.GetShopBetByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBetDetail{}, err
|
||||||
|
}
|
||||||
|
return convertDBShopBetDetail(bet), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetShopBetByBetID(ctx context.Context, betID int64) (domain.ShopBetDetail, error) {
|
||||||
|
bet, err := s.queries.GetShopBetByBetID(ctx, betID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBetDetail{}, err
|
||||||
|
}
|
||||||
|
return convertDBShopBetDetail(bet), nil
|
||||||
|
}
|
||||||
|
func (s *Store) GetShopBetByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopBetDetail, error) {
|
||||||
|
bet, err := s.queries.GetShopBetByShopTransactionID(ctx, shopTransactionID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBetDetail{}, err
|
||||||
|
}
|
||||||
|
return convertDBShopBetDetail(bet), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateShopBetCashOut(ctx context.Context, id int64, cashedOut bool) error {
|
||||||
|
err := s.queries.UpdateShopBetCashOut(ctx, dbgen.UpdateShopBetCashOutParams{
|
||||||
|
ID: id,
|
||||||
|
CashedOut: cashedOut,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Error("failed to update cashout",
|
||||||
|
zap.Int64("id", id),
|
||||||
|
zap.Bool("cashed_out", cashedOut),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) UpdateShopBetCashoutID(ctx context.Context, id int64, cashoutID string) error {
|
||||||
|
err := s.queries.UpdateShopBetCashoutID(ctx, dbgen.UpdateShopBetCashoutIDParams{
|
||||||
|
ID: id,
|
||||||
|
CashoutID: cashoutID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
domain.MongoDBLogger.Error("failed to update cashout_id",
|
||||||
|
zap.Int64("id", id),
|
||||||
|
zap.String("cashout_id", cashoutID),
|
||||||
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
104
internal/repository/shop_deposit.go
Normal file
104
internal/repository/shop_deposit.go
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertShopDeposit(deposit dbgen.ShopDeposit) domain.ShopDeposit {
|
||||||
|
return domain.ShopDeposit{
|
||||||
|
ID: deposit.ID,
|
||||||
|
ShopTransactionID: deposit.ShopTransactionID,
|
||||||
|
CustomerID: deposit.CustomerID,
|
||||||
|
WalletTransferID: deposit.WalletTransferID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertShopDepositDetail(deposit dbgen.ShopDepositDetail) domain.ShopDepositDetail {
|
||||||
|
return domain.ShopDepositDetail{
|
||||||
|
ID: deposit.ID,
|
||||||
|
ShopTransactionID: deposit.ShopTransactionID,
|
||||||
|
CustomerID: deposit.CustomerID,
|
||||||
|
WalletTransferID: deposit.WalletTransferID,
|
||||||
|
FullName: deposit.FullName,
|
||||||
|
PhoneNumber: deposit.PhoneNumber,
|
||||||
|
Amount: domain.Currency(deposit.Amount),
|
||||||
|
BranchID: deposit.BranchID,
|
||||||
|
CompanyID: deposit.CompanyID,
|
||||||
|
TransactionVerified: deposit.TransactionVerified,
|
||||||
|
UpdatedAt: deposit.UpdatedAt.Time,
|
||||||
|
CreatedAt: deposit.CreatedAt.Time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func convertCreateShopDeposit(deposit domain.CreateShopDeposit) dbgen.CreateShopDepositParams {
|
||||||
|
return dbgen.CreateShopDepositParams{
|
||||||
|
ShopTransactionID: deposit.ShopTransactionID,
|
||||||
|
CustomerID: deposit.CustomerID,
|
||||||
|
WalletTransferID: deposit.WalletTransferID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) CreateShopDeposit(ctx context.Context, deposit domain.CreateShopDeposit) (domain.ShopDeposit, error) {
|
||||||
|
newShopDeposit, err := s.queries.CreateShopDeposit(ctx, convertCreateShopDeposit(deposit))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopDeposit{}, err
|
||||||
|
}
|
||||||
|
return convertShopDeposit(newShopDeposit), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetAllShopDeposit(ctx context.Context, filter domain.ShopDepositFilter) ([]domain.ShopDepositDetail, error) {
|
||||||
|
deposits, err := s.queries.GetAllShopDeposit(ctx, dbgen.GetAllShopDepositParams{
|
||||||
|
BranchID: pgtype.Int8{
|
||||||
|
Int64: filter.BranchID.Value,
|
||||||
|
Valid: filter.BranchID.Valid,
|
||||||
|
},
|
||||||
|
CompanyID: pgtype.Int8{
|
||||||
|
Int64: filter.CompanyID.Value,
|
||||||
|
Valid: filter.CompanyID.Valid,
|
||||||
|
},
|
||||||
|
Query: pgtype.Text{
|
||||||
|
String: filter.Query.Value,
|
||||||
|
Valid: filter.Query.Valid,
|
||||||
|
},
|
||||||
|
CreatedBefore: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedBefore.Value,
|
||||||
|
Valid: filter.CreatedBefore.Valid,
|
||||||
|
},
|
||||||
|
CreatedAfter: pgtype.Timestamp{
|
||||||
|
Time: filter.CreatedAfter.Value,
|
||||||
|
Valid: filter.CreatedAfter.Valid,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []domain.ShopDepositDetail = make([]domain.ShopDepositDetail, 0, len(deposits))
|
||||||
|
|
||||||
|
for _, deposit := range deposits {
|
||||||
|
result = append(result, convertShopDepositDetail(deposit))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetShopDepositByID(ctx context.Context, id int64) (domain.ShopDepositDetail, error) {
|
||||||
|
deposit, err := s.queries.GetShopDepositByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopDepositDetail{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertShopDepositDetail(deposit), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetShopDepositByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopDepositDetail, error) {
|
||||||
|
deposit, err := s.queries.GetShopDepositByShopTransactionID(ctx, shopTransactionID)
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopDepositDetail{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertShopDepositDetail(deposit), err
|
||||||
|
}
|
||||||
|
|
@ -14,18 +14,31 @@ func convertDBShopTransaction(transaction dbgen.ShopTransaction) domain.ShopTran
|
||||||
ID: transaction.ID,
|
ID: transaction.ID,
|
||||||
Amount: domain.Currency(transaction.Amount),
|
Amount: domain.Currency(transaction.Amount),
|
||||||
BranchID: transaction.BranchID,
|
BranchID: transaction.BranchID,
|
||||||
CashierID: transaction.CashierID.Int64,
|
UserID: transaction.UserID,
|
||||||
BetID: transaction.BetID.Int64,
|
Type: domain.ShopTransactionType(transaction.Type),
|
||||||
NumberOfOutcomes: transaction.NumberOfOutcomes.Int64,
|
PaymentOption: domain.PaymentOption(transaction.PaymentOption),
|
||||||
Type: domain.ShopTransactionType(transaction.Type.Int64),
|
FullName: transaction.FullName,
|
||||||
PaymentOption: domain.PaymentOption(transaction.PaymentOption.Int64),
|
PhoneNumber: transaction.PhoneNumber,
|
||||||
FullName: transaction.FullName.String,
|
BankCode: domain.ValidString{
|
||||||
PhoneNumber: transaction.PhoneNumber.String,
|
Value: transaction.BankCode.String,
|
||||||
BankCode: transaction.BankCode.String,
|
Valid: transaction.BankCode.Valid,
|
||||||
BeneficiaryName: transaction.BeneficiaryName.String,
|
},
|
||||||
AccountName: transaction.AccountName.String,
|
BeneficiaryName: domain.ValidString{
|
||||||
AccountNumber: transaction.AccountNumber.String,
|
Value: transaction.BeneficiaryName.String,
|
||||||
ReferenceNumber: transaction.ReferenceNumber.String,
|
Valid: transaction.BeneficiaryName.Valid,
|
||||||
|
},
|
||||||
|
AccountName: domain.ValidString{
|
||||||
|
Value: transaction.AccountName.String,
|
||||||
|
Valid: transaction.AccountName.Valid,
|
||||||
|
},
|
||||||
|
AccountNumber: domain.ValidString{
|
||||||
|
Value: transaction.AccountName.String,
|
||||||
|
Valid: transaction.AccountNumber.Valid,
|
||||||
|
},
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: transaction.ReferenceNumber.String,
|
||||||
|
Valid: transaction.ReferenceNumber.Valid,
|
||||||
|
},
|
||||||
ApprovedBy: domain.ValidInt64{
|
ApprovedBy: domain.ValidInt64{
|
||||||
Value: transaction.ApprovedBy.Int64,
|
Value: transaction.ApprovedBy.Int64,
|
||||||
Valid: transaction.ApprovedBy.Valid,
|
Valid: transaction.ApprovedBy.Valid,
|
||||||
|
|
@ -33,59 +46,105 @@ func convertDBShopTransaction(transaction dbgen.ShopTransaction) domain.ShopTran
|
||||||
CreatedAt: transaction.CreatedAt.Time,
|
CreatedAt: transaction.CreatedAt.Time,
|
||||||
UpdatedAt: transaction.UpdatedAt.Time,
|
UpdatedAt: transaction.UpdatedAt.Time,
|
||||||
Verified: transaction.Verified,
|
Verified: transaction.Verified,
|
||||||
BranchName: transaction.BranchName.String,
|
CompanyID: transaction.CompanyID,
|
||||||
BranchLocation: transaction.BranchLocation.String,
|
|
||||||
CashierName: transaction.CashierName.String,
|
|
||||||
CompanyID: transaction.CompanyID.Int64,
|
|
||||||
ApproverName: domain.ValidString{
|
|
||||||
Value: transaction.ApproverName.String,
|
|
||||||
Valid: transaction.ApprovedBy.Valid,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertCreateTransaction(transaction domain.CreateShopTransaction) dbgen.CreateShopTransactionParams {
|
func convertDBShopTransactionDetail(transaction dbgen.ShopTransactionDetail) domain.ShopTransactionDetail {
|
||||||
|
return domain.ShopTransactionDetail{
|
||||||
|
ID: transaction.ID,
|
||||||
|
Amount: domain.Currency(transaction.Amount),
|
||||||
|
BranchID: transaction.BranchID,
|
||||||
|
UserID: transaction.UserID,
|
||||||
|
CreatorFirstName: transaction.CreatorFirstName.String,
|
||||||
|
CreatorLastName: transaction.CreatorLastName.String,
|
||||||
|
CreatorPhoneNumber: transaction.CreatorPhoneNumber.String,
|
||||||
|
Type: domain.ShopTransactionType(transaction.Type),
|
||||||
|
PaymentOption: domain.PaymentOption(transaction.PaymentOption),
|
||||||
|
FullName: transaction.FullName,
|
||||||
|
PhoneNumber: transaction.PhoneNumber,
|
||||||
|
BankCode: domain.ValidString{
|
||||||
|
Value: transaction.BankCode.String,
|
||||||
|
Valid: transaction.BankCode.Valid,
|
||||||
|
},
|
||||||
|
BeneficiaryName: domain.ValidString{
|
||||||
|
Value: transaction.BeneficiaryName.String,
|
||||||
|
Valid: transaction.BeneficiaryName.Valid,
|
||||||
|
},
|
||||||
|
AccountName: domain.ValidString{
|
||||||
|
Value: transaction.AccountName.String,
|
||||||
|
Valid: transaction.AccountName.Valid,
|
||||||
|
},
|
||||||
|
AccountNumber: domain.ValidString{
|
||||||
|
Value: transaction.AccountName.String,
|
||||||
|
Valid: transaction.AccountNumber.Valid,
|
||||||
|
},
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: transaction.ReferenceNumber.String,
|
||||||
|
Valid: transaction.ReferenceNumber.Valid,
|
||||||
|
},
|
||||||
|
ApprovedBy: domain.ValidInt64{
|
||||||
|
Value: transaction.ApprovedBy.Int64,
|
||||||
|
Valid: transaction.ApprovedBy.Valid,
|
||||||
|
},
|
||||||
|
ApproverFirstName: domain.ValidString{
|
||||||
|
Value: transaction.ApproverFirstName.String,
|
||||||
|
Valid: transaction.ApproverFirstName.Valid,
|
||||||
|
},
|
||||||
|
ApproverLastName: domain.ValidString{
|
||||||
|
Value: transaction.ApproverLastName.String,
|
||||||
|
Valid: transaction.ApproverLastName.Valid,
|
||||||
|
},
|
||||||
|
ApproverPhoneNumber: domain.ValidString{
|
||||||
|
Value: transaction.ApproverPhoneNumber.String,
|
||||||
|
Valid: transaction.ApproverPhoneNumber.Valid,
|
||||||
|
},
|
||||||
|
CreatedAt: transaction.CreatedAt.Time,
|
||||||
|
UpdatedAt: transaction.UpdatedAt.Time,
|
||||||
|
Verified: transaction.Verified,
|
||||||
|
CompanyID: transaction.CompanyID,
|
||||||
|
BranchName: transaction.BranchName.String,
|
||||||
|
BranchLocation: transaction.BranchLocation.String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertCreateShopTransaction(transaction domain.CreateShopTransaction) dbgen.CreateShopTransactionParams {
|
||||||
return dbgen.CreateShopTransactionParams{
|
return dbgen.CreateShopTransactionParams{
|
||||||
Amount: int64(transaction.Amount),
|
Amount: int64(transaction.Amount),
|
||||||
BranchID: transaction.BranchID,
|
BranchID: transaction.BranchID,
|
||||||
CashierID: pgtype.Int8{Int64: transaction.CashierID, Valid: true},
|
UserID: transaction.UserID,
|
||||||
BetID: pgtype.Int8{Int64: transaction.BetID, Valid: true},
|
Type: int64(transaction.Type),
|
||||||
Type: pgtype.Int8{Int64: int64(transaction.Type), Valid: true},
|
PaymentOption: int64(transaction.PaymentOption),
|
||||||
PaymentOption: pgtype.Int8{Int64: int64(transaction.PaymentOption), Valid: true},
|
FullName: transaction.FullName,
|
||||||
FullName: pgtype.Text{String: transaction.FullName, Valid: transaction.FullName != ""},
|
PhoneNumber: transaction.PhoneNumber,
|
||||||
PhoneNumber: pgtype.Text{String: transaction.PhoneNumber, Valid: transaction.PhoneNumber != ""},
|
CompanyID: transaction.CompanyID,
|
||||||
BankCode: pgtype.Text{String: transaction.BankCode, Valid: transaction.BankCode != ""},
|
BankCode: pgtype.Text{String: transaction.BankCode.Value, Valid: transaction.BankCode.Valid},
|
||||||
BeneficiaryName: pgtype.Text{String: transaction.BeneficiaryName, Valid: transaction.BeneficiaryName != ""},
|
BeneficiaryName: pgtype.Text{String: transaction.BeneficiaryName.Value, Valid: transaction.BeneficiaryName.Valid},
|
||||||
AccountName: pgtype.Text{String: transaction.AccountName, Valid: transaction.AccountName != ""},
|
AccountName: pgtype.Text{String: transaction.AccountName.Value, Valid: transaction.AccountName.Valid},
|
||||||
AccountNumber: pgtype.Text{String: transaction.AccountNumber, Valid: transaction.AccountNumber != ""},
|
AccountNumber: pgtype.Text{String: transaction.AccountNumber.Value, Valid: transaction.AccountNumber.Valid},
|
||||||
ReferenceNumber: pgtype.Text{String: transaction.ReferenceNumber, Valid: transaction.ReferenceNumber != ""},
|
ReferenceNumber: pgtype.Text{String: transaction.ReferenceNumber.Value, Valid: transaction.ReferenceNumber.Valid},
|
||||||
NumberOfOutcomes: pgtype.Int8{Int64: transaction.NumberOfOutcomes, Valid: true},
|
|
||||||
BranchName: pgtype.Text{String: transaction.BranchName, Valid: transaction.BranchName != ""},
|
|
||||||
BranchLocation: pgtype.Text{String: transaction.BranchLocation, Valid: transaction.BranchLocation != ""},
|
|
||||||
CashierName: pgtype.Text{String: transaction.CashierName, Valid: transaction.CashierName != ""},
|
|
||||||
CompanyID: pgtype.Int8{Int64: transaction.CompanyID, Valid: true},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
|
func (s *Store) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
|
||||||
|
|
||||||
newTransaction, err := s.queries.CreateShopTransaction(ctx, convertCreateTransaction(transaction))
|
newTransaction, err := s.queries.CreateShopTransaction(ctx, convertCreateShopTransaction(transaction))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.ShopTransaction{}, err
|
return domain.ShopTransaction{}, err
|
||||||
}
|
}
|
||||||
return convertDBShopTransaction(newTransaction), err
|
return convertDBShopTransaction(newTransaction), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransaction, error) {
|
func (s *Store) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error) {
|
||||||
transaction, err := s.queries.GetShopTransactionByID(ctx, id)
|
transaction, err := s.queries.GetShopTransactionByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.ShopTransaction{}, err
|
return domain.ShopTransactionDetail{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDBShopTransaction(transaction), nil
|
return convertDBShopTransactionDetail(transaction), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransaction, error) {
|
func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error) {
|
||||||
transaction, err := s.queries.GetAllShopTransactions(ctx, dbgen.GetAllShopTransactionsParams{
|
transaction, err := s.queries.GetAllShopTransactions(ctx, dbgen.GetAllShopTransactionsParams{
|
||||||
BranchID: pgtype.Int8{
|
BranchID: pgtype.Int8{
|
||||||
Int64: filter.BranchID.Value,
|
Int64: filter.BranchID.Value,
|
||||||
|
|
@ -95,9 +154,9 @@ func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTr
|
||||||
Int64: filter.CompanyID.Value,
|
Int64: filter.CompanyID.Value,
|
||||||
Valid: filter.CompanyID.Valid,
|
Valid: filter.CompanyID.Valid,
|
||||||
},
|
},
|
||||||
CashierID: pgtype.Int8{
|
UserID: pgtype.Int8{
|
||||||
Int64: filter.CashierID.Value,
|
Int64: filter.UserID.Value,
|
||||||
Valid: filter.CashierID.Valid,
|
Valid: filter.UserID.Valid,
|
||||||
},
|
},
|
||||||
Query: pgtype.Text{
|
Query: pgtype.Text{
|
||||||
String: filter.Query.Value,
|
String: filter.Query.Value,
|
||||||
|
|
@ -117,22 +176,22 @@ func (s *Store) GetAllShopTransactions(ctx context.Context, filter domain.ShopTr
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []domain.ShopTransaction = make([]domain.ShopTransaction, 0, len(transaction))
|
var result []domain.ShopTransactionDetail = make([]domain.ShopTransactionDetail, 0, len(transaction))
|
||||||
for _, ticket := range transaction {
|
for _, tAction := range transaction {
|
||||||
result = append(result, convertDBShopTransaction(ticket))
|
result = append(result, convertDBShopTransactionDetail(tAction))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
func (s *Store) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransaction, error) {
|
func (s *Store) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransactionDetail, error) {
|
||||||
transaction, err := s.queries.GetShopTransactionByBranch(ctx, id)
|
transaction, err := s.queries.GetShopTransactionByBranch(ctx, id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []domain.ShopTransaction = make([]domain.ShopTransaction, 0, len(transaction))
|
var result []domain.ShopTransactionDetail = make([]domain.ShopTransactionDetail, 0, len(transaction))
|
||||||
for _, ticket := range transaction {
|
for _, ticket := range transaction {
|
||||||
result = append(result, convertDBShopTransaction(ticket))
|
result = append(result, convertDBShopTransactionDetail(ticket))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
@ -145,14 +204,11 @@ func (s *Store) UpdateShopTransactionVerified(ctx context.Context, id int64, ver
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
Verified: verified,
|
Verified: verified,
|
||||||
ApproverName: pgtype.Text{
|
|
||||||
String: approverName,
|
|
||||||
Valid: true,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetTransactionTotals returns total deposits and withdrawals
|
// GetTransactionTotals returns total deposits and withdrawals
|
||||||
func (s *Store) GetTransactionTotals(ctx context.Context, filter domain.ReportFilter) (deposits, withdrawals domain.Currency, err error) {
|
func (s *Store) GetTransactionTotals(ctx context.Context, filter domain.ReportFilter) (deposits, withdrawals domain.Currency, err error) {
|
||||||
query := `SELECT
|
query := `SELECT
|
||||||
|
|
@ -172,7 +228,7 @@ func (s *Store) GetTransactionTotals(ctx context.Context, filter domain.ReportFi
|
||||||
args = append(args, filter.BranchID.Value)
|
args = append(args, filter.BranchID.Value)
|
||||||
argPos++
|
argPos++
|
||||||
} else if filter.UserID.Valid {
|
} else if filter.UserID.Valid {
|
||||||
query += fmt.Sprintf(" WHERE cashier_id = $%d", argPos)
|
query += fmt.Sprintf(" WHERE user_id = $%d", argPos)
|
||||||
args = append(args, filter.UserID.Value)
|
args = append(args, filter.UserID.Value)
|
||||||
argPos++
|
argPos++
|
||||||
}
|
}
|
||||||
|
|
@ -252,7 +252,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
|
||||||
newBet := domain.CreateBet{
|
newBet := domain.CreateBet{
|
||||||
Amount: domain.ToCurrency(req.Amount),
|
Amount: domain.ToCurrency(req.Amount),
|
||||||
TotalOdds: totalOdds,
|
TotalOdds: totalOdds,
|
||||||
Status: req.Status,
|
Status: domain.OUTCOME_STATUS_PENDING,
|
||||||
FullName: req.FullName,
|
FullName: req.FullName,
|
||||||
PhoneNumber: req.PhoneNumber,
|
PhoneNumber: req.PhoneNumber,
|
||||||
CashoutID: cashoutID,
|
CashoutID: cashoutID,
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,23 @@ import (
|
||||||
|
|
||||||
type TransactionStore interface {
|
type TransactionStore interface {
|
||||||
CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error)
|
CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error)
|
||||||
GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransaction, error)
|
GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error)
|
||||||
GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransaction, error)
|
GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error)
|
||||||
GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransaction, error)
|
GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransactionDetail, error)
|
||||||
UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error
|
UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error
|
||||||
|
|
||||||
GetTransactionTotals(ctx context.Context, filter domain.ReportFilter) (deposits, withdrawals domain.Currency, err error)
|
GetTransactionTotals(ctx context.Context, filter domain.ReportFilter) (deposits, withdrawals domain.Currency, err error)
|
||||||
GetBranchTransactionTotals(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.BranchTransactions, error)
|
GetBranchTransactionTotals(ctx context.Context, filter domain.ReportFilter) (map[int64]domain.BranchTransactions, error)
|
||||||
|
|
||||||
|
CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (domain.ShopBet, error)
|
||||||
|
GetAllShopBet(ctx context.Context, filter domain.ShopBetFilter) ([]domain.ShopBetDetail, error)
|
||||||
|
GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDetail, error)
|
||||||
|
GetShopBetByBetID(ctx context.Context, betID int64) (domain.ShopBetDetail, error)
|
||||||
|
GetShopBetByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopBetDetail, error)
|
||||||
|
UpdateShopBetCashOut(ctx context.Context, id int64, cashedOut bool) error
|
||||||
|
UpdateShopBetCashoutID(ctx context.Context, id int64, cashoutID string) error
|
||||||
|
|
||||||
|
CreateShopDeposit(ctx context.Context, deposit domain.CreateShopDeposit) (domain.ShopDeposit, error)
|
||||||
|
GetAllShopDeposit(ctx context.Context, filter domain.ShopDepositFilter) ([]domain.ShopDepositDetail, error)
|
||||||
|
GetShopDepositByID(ctx context.Context, id int64) (domain.ShopDepositDetail, error)
|
||||||
|
GetShopDepositByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopDepositDetail, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,91 @@ package transaction
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"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/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrBranchRequiredForRole = errors.New("branch_id is required to be passed for this role")
|
||||||
|
ErrInvalidBranchID = errors.New("invalid branch id")
|
||||||
|
ErrUnauthorizedCompanyID = errors.New("unauthorized company id")
|
||||||
|
ErrUnauthorizedBranchManager = errors.New("unauthorized branch manager")
|
||||||
|
ErrCustomerRoleNotAuthorized = errors.New("customer role not authorized")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
transactionStore TransactionStore
|
transactionStore TransactionStore
|
||||||
|
branchSvc branch.Service
|
||||||
|
betSvc bet.Service
|
||||||
|
walletSvc wallet.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(transactionStore TransactionStore) *Service {
|
func NewService(transactionStore TransactionStore, branchSvc branch.Service, betSvc bet.Service, walletSvc wallet.Service) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
transactionStore: transactionStore,
|
transactionStore: transactionStore,
|
||||||
|
branchSvc: branchSvc,
|
||||||
|
betSvc: betSvc,
|
||||||
|
walletSvc: walletSvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
|
func (s *Service) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
|
||||||
return s.transactionStore.CreateShopTransaction(ctx, transaction)
|
return s.transactionStore.CreateShopTransaction(ctx, transaction)
|
||||||
}
|
}
|
||||||
func (s *Service) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransaction, error) {
|
func (s *Service) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error) {
|
||||||
return s.transactionStore.GetShopTransactionByID(ctx, id)
|
return s.transactionStore.GetShopTransactionByID(ctx, id)
|
||||||
}
|
}
|
||||||
func (s *Service) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransaction, error) {
|
func (s *Service) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error) {
|
||||||
return s.transactionStore.GetAllShopTransactions(ctx, filter)
|
return s.transactionStore.GetAllShopTransactions(ctx, filter)
|
||||||
}
|
}
|
||||||
func (s *Service) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransaction, error) {
|
func (s *Service) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransactionDetail, error) {
|
||||||
return s.transactionStore.GetShopTransactionByBranch(ctx, id)
|
return s.transactionStore.GetShopTransactionByBranch(ctx, id)
|
||||||
}
|
}
|
||||||
func (s *Service) UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error {
|
func (s *Service) UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error {
|
||||||
return s.transactionStore.UpdateShopTransactionVerified(ctx, id, verified, approvedBy, approverName)
|
return s.transactionStore.UpdateShopTransactionVerified(ctx, id, verified, approvedBy, approverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetBranchByRole(ctx context.Context, branchID *int64, role domain.Role, userID int64, userCompanyID domain.ValidInt64) (*int64, *int64, error) {
|
||||||
|
// var branchID int64
|
||||||
|
// var companyID int64
|
||||||
|
|
||||||
|
if role == domain.RoleAdmin || role == domain.RoleBranchManager || role == domain.RoleSuperAdmin {
|
||||||
|
if branchID == nil {
|
||||||
|
// h.logger.Error("CashoutReq Branch ID is required for this user role")
|
||||||
|
return nil, nil, ErrBranchRequiredForRole
|
||||||
|
}
|
||||||
|
branch, err := s.branchSvc.GetBranchByID(ctx, *branchID)
|
||||||
|
if err != nil {
|
||||||
|
// h.logger.Error("CashoutReq no branches")
|
||||||
|
return nil, nil, ErrInvalidBetID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user has access to the company
|
||||||
|
if role != domain.RoleSuperAdmin {
|
||||||
|
if !userCompanyID.Valid || userCompanyID.Value != branch.CompanyID {
|
||||||
|
return nil, nil, ErrUnauthorizedCompanyID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if role == domain.RoleBranchManager {
|
||||||
|
if branch.BranchManagerID != userID {
|
||||||
|
return nil, nil, ErrUnauthorizedBranchManager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &branch.ID, &branch.CompanyID, nil
|
||||||
|
} else if role == domain.RoleCashier {
|
||||||
|
branch, err := s.branchSvc.GetBranchByCashier(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
// h.logger.Error("CashoutReq failed, branch id invalid")
|
||||||
|
return nil, nil, ErrInvalidBranchID
|
||||||
|
}
|
||||||
|
return &branch.ID, &branch.CompanyID, nil
|
||||||
|
} else {
|
||||||
|
return nil, nil, ErrCustomerRoleNotAuthorized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
207
internal/services/transaction/shop_bet.go
Normal file
207
internal/services/transaction/shop_bet.go
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
package transaction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidBetID = errors.New("invalid bet id")
|
||||||
|
ErrUserHasNotWonBet = errors.New("user has not won bet")
|
||||||
|
ErrUserHasAlreadyCashoutOut = errors.New("user has already cashout")
|
||||||
|
ErrTransactionNotVerified = errors.New("transaction hasn't been verified")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) GenerateCashoutID() (string, error) {
|
||||||
|
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
|
const length int = 13
|
||||||
|
charLen := big.NewInt(int64(len(chars)))
|
||||||
|
result := make([]byte, length)
|
||||||
|
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
index, err := rand.Int(rand.Reader, charLen)
|
||||||
|
if err != nil {
|
||||||
|
// s.mongoLogger.Error("failed to generate random index for cashout ID",
|
||||||
|
// zap.Int("position", i),
|
||||||
|
// zap.Error(err),
|
||||||
|
// )
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
result[i] = chars[index.Int64()]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) CreateShopBet(ctx context.Context, userID int64, role domain.Role, userCompanyID domain.ValidInt64, req domain.ShopBetReq) (domain.ShopBet, error) {
|
||||||
|
|
||||||
|
branchID, companyID, err := s.GetBranchByRole(ctx, req.BranchID, role, userID, userCompanyID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cashoutID, err := s.GenerateCashoutID()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newBet, err := s.betSvc.PlaceBet(ctx, domain.CreateBetReq{
|
||||||
|
Outcomes: req.Outcomes,
|
||||||
|
Amount: req.Amount,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
BranchID: branchID,
|
||||||
|
}, userID, role)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopBet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newTransaction, err := s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
||||||
|
Amount: domain.ToCurrency(req.Amount),
|
||||||
|
BranchID: *branchID,
|
||||||
|
CompanyID: *companyID,
|
||||||
|
UserID: userID,
|
||||||
|
Type: domain.TRANSACTION_BET,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
PaymentOption: req.PaymentOption,
|
||||||
|
BankCode: domain.ValidString{
|
||||||
|
Value: req.BankCode,
|
||||||
|
Valid: req.BankCode != "",
|
||||||
|
},
|
||||||
|
BeneficiaryName: domain.ValidString{
|
||||||
|
Value: req.BeneficiaryName,
|
||||||
|
Valid: req.BeneficiaryName != "",
|
||||||
|
},
|
||||||
|
AccountName: domain.ValidString{
|
||||||
|
Value: req.AccountName,
|
||||||
|
Valid: req.AccountName != "",
|
||||||
|
},
|
||||||
|
AccountNumber: domain.ValidString{
|
||||||
|
Value: req.AccountNumber,
|
||||||
|
Valid: req.AccountNumber != "",
|
||||||
|
},
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: req.ReferenceNumber,
|
||||||
|
Valid: req.ReferenceNumber != "",
|
||||||
|
},
|
||||||
|
Verified: false,
|
||||||
|
ApprovedBy: domain.ValidInt64{
|
||||||
|
Value: userID,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return s.transactionStore.CreateShopBet(ctx, domain.CreateShopBet{
|
||||||
|
ShopTransactionID: newTransaction.ID,
|
||||||
|
CashoutID: cashoutID,
|
||||||
|
BetID: newBet.ID,
|
||||||
|
NumberOfOutcomes: int64(len(req.Outcomes)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (s *Service) CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (domain.ShopBet, error) {
|
||||||
|
// return s.transactionStore.CreateShopBet(ctx, bet)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (s *Service) CashoutBet(ctx context.Context, betID int64, userID int64, role domain.Role, req domain.CashoutReq) (domain.ShopTransaction, error) {
|
||||||
|
branchID, companyID, err := s.GetBranchByRole(ctx, req.BranchID, role, userID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopTransaction{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
bet, err := s.GetShopBetByBetID(ctx, betID)
|
||||||
|
if err != nil {
|
||||||
|
// h.logger.Error("CashoutReq failed", "error", err)
|
||||||
|
return domain.ShopTransaction{}, ErrInvalidBetID
|
||||||
|
}
|
||||||
|
|
||||||
|
if bet.Status != domain.OUTCOME_STATUS_WIN {
|
||||||
|
// h.logger.Error("CashoutReq failed, bet has not won")
|
||||||
|
return domain.ShopTransaction{}, ErrUserHasNotWonBet
|
||||||
|
}
|
||||||
|
|
||||||
|
if bet.CashedOut {
|
||||||
|
// s.logger.Error(("Bet has already been cashed out"))
|
||||||
|
return domain.ShopTransaction{}, ErrUserHasAlreadyCashoutOut
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bet.TransactionVerified {
|
||||||
|
return domain.ShopTransaction{}, ErrTransactionNotVerified
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.UpdateShopBetCashOut(ctx, bet.ID, true)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopTransaction{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
||||||
|
Amount: bet.Amount,
|
||||||
|
BranchID: *branchID,
|
||||||
|
CompanyID: *companyID,
|
||||||
|
UserID: userID,
|
||||||
|
Type: domain.TRANSACTION_CASHOUT,
|
||||||
|
FullName: bet.FullName,
|
||||||
|
PhoneNumber: bet.PhoneNumber,
|
||||||
|
PaymentOption: req.PaymentOption,
|
||||||
|
BankCode: domain.ValidString{
|
||||||
|
Value: req.BankCode,
|
||||||
|
Valid: req.BankCode != "",
|
||||||
|
},
|
||||||
|
BeneficiaryName: domain.ValidString{
|
||||||
|
Value: req.BeneficiaryName,
|
||||||
|
Valid: req.BeneficiaryName != "",
|
||||||
|
},
|
||||||
|
AccountName: domain.ValidString{
|
||||||
|
Value: req.AccountName,
|
||||||
|
Valid: req.AccountName != "",
|
||||||
|
},
|
||||||
|
AccountNumber: domain.ValidString{
|
||||||
|
Value: req.AccountNumber,
|
||||||
|
Valid: req.AccountNumber != "",
|
||||||
|
},
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: req.ReferenceNumber,
|
||||||
|
Valid: req.ReferenceNumber != "",
|
||||||
|
},
|
||||||
|
Verified: false,
|
||||||
|
ApprovedBy: domain.ValidInt64{
|
||||||
|
Value: userID,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetAllShopBet(ctx context.Context, filter domain.ShopBetFilter) ([]domain.ShopBetDetail, error) {
|
||||||
|
return s.transactionStore.GetAllShopBet(ctx, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDetail, error) {
|
||||||
|
return s.transactionStore.GetShopBetByBetID(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetShopBetByBetID(ctx context.Context, betID int64) (domain.ShopBetDetail, error) {
|
||||||
|
return s.transactionStore.GetShopBetByBetID(ctx, betID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetShopBetByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopBetDetail, error) {
|
||||||
|
return s.transactionStore.GetShopBetByShopTransactionID(ctx, shopTransactionID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateShopBetCashOut(ctx context.Context, id int64, cashedOut bool) error {
|
||||||
|
return s.transactionStore.UpdateShopBetCashOut(ctx, id, cashedOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateShopBetCashoutID(ctx context.Context, id int64, cashoutID string) error {
|
||||||
|
return s.transactionStore.UpdateShopBetCashoutID(ctx, id, cashoutID)
|
||||||
|
}
|
||||||
114
internal/services/transaction/shop_deposit.go
Normal file
114
internal/services/transaction/shop_deposit.go
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
package transaction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) CreateShopDeposit(ctx context.Context, userID int64, role domain.Role, req domain.ShopDepositReq) (domain.ShopDeposit, error) {
|
||||||
|
var branchID int64
|
||||||
|
var companyID int64
|
||||||
|
var senderID int64
|
||||||
|
if role == domain.RoleAdmin || role == domain.RoleBranchManager || role == domain.RoleSuperAdmin {
|
||||||
|
if req.BranchID == nil {
|
||||||
|
// h.logger.Error("CashoutReq Branch ID is required for this user role")
|
||||||
|
return domain.ShopDeposit{}, ErrBranchRequiredForRole
|
||||||
|
}
|
||||||
|
branch, err := s.branchSvc.GetBranchByID(ctx, *req.BranchID)
|
||||||
|
if err != nil {
|
||||||
|
// h.logger.Error("CashoutReq no branches")
|
||||||
|
return domain.ShopDeposit{}, ErrInvalidBetID
|
||||||
|
}
|
||||||
|
|
||||||
|
branchID = branch.ID
|
||||||
|
companyID = branch.CompanyID
|
||||||
|
senderID = branch.WalletID
|
||||||
|
} else if role == domain.RoleCashier {
|
||||||
|
branch, err := s.branchSvc.GetBranchByCashier(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
// h.logger.Error("CashoutReq failed, branch id invalid")
|
||||||
|
return domain.ShopDeposit{}, ErrInvalidBranchID
|
||||||
|
}
|
||||||
|
branchID = branch.ID
|
||||||
|
companyID = branch.CompanyID
|
||||||
|
senderID = branch.WalletID
|
||||||
|
} else {
|
||||||
|
return domain.ShopDeposit{}, ErrCustomerRoleNotAuthorized
|
||||||
|
}
|
||||||
|
|
||||||
|
customerWallet, err := s.walletSvc.GetCustomerWallet(ctx, req.CustomerID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopDeposit{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
transfer, err := s.walletSvc.TransferToWallet(ctx,
|
||||||
|
senderID, customerWallet.RegularID, domain.ToCurrency(req.Amount), domain.TRANSFER_DIRECT,
|
||||||
|
domain.ValidInt64{Value: userID, Valid: true},
|
||||||
|
fmt.Sprintf("Transferred %v from customer wallet deposit", req.Amount),
|
||||||
|
)
|
||||||
|
|
||||||
|
newTransaction, err := s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
||||||
|
Amount: domain.Currency(req.Amount),
|
||||||
|
BranchID: branchID,
|
||||||
|
CompanyID: companyID,
|
||||||
|
UserID: userID,
|
||||||
|
Type: domain.TRANSACTION_DEPOSIT,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
PaymentOption: req.PaymentOption,
|
||||||
|
BankCode: domain.ValidString{
|
||||||
|
Value: req.BankCode,
|
||||||
|
Valid: req.BankCode != "",
|
||||||
|
},
|
||||||
|
BeneficiaryName: domain.ValidString{
|
||||||
|
Value: req.BeneficiaryName,
|
||||||
|
Valid: req.BeneficiaryName != "",
|
||||||
|
},
|
||||||
|
AccountName: domain.ValidString{
|
||||||
|
Value: req.AccountName,
|
||||||
|
Valid: req.AccountName != "",
|
||||||
|
},
|
||||||
|
AccountNumber: domain.ValidString{
|
||||||
|
Value: req.AccountNumber,
|
||||||
|
Valid: req.AccountNumber != "",
|
||||||
|
},
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: req.ReferenceNumber,
|
||||||
|
Valid: req.ReferenceNumber != "",
|
||||||
|
},
|
||||||
|
Verified: false,
|
||||||
|
ApprovedBy: domain.ValidInt64{
|
||||||
|
Value: userID,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.ShopDeposit{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.transactionStore.CreateShopDeposit(ctx, domain.CreateShopDeposit{
|
||||||
|
ShopTransactionID: newTransaction.ID,
|
||||||
|
CustomerID: req.CustomerID,
|
||||||
|
WalletTransferID: transfer.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (s *Service) CreateShopDeposit(ctx context.Context, deposit domain.CreateShopDeposit) (domain.ShopDeposit, error) {
|
||||||
|
// return s.transactionStore.CreateShopDeposit(ctx, deposit)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (s *Service) GetAllShopDeposit(ctx context.Context, filter domain.ShopDepositFilter) ([]domain.ShopDepositDetail, error) {
|
||||||
|
return s.transactionStore.GetAllShopDeposit(ctx, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetShopDepositByID(ctx context.Context, id int64) (domain.ShopDepositDetail, error) {
|
||||||
|
return s.transactionStore.GetShopDepositByID(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetShopDepositByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopDepositDetail, error) {
|
||||||
|
return s.transactionStore.GetShopDepositByShopTransactionID(ctx, shopTransactionID)
|
||||||
|
}
|
||||||
|
|
@ -115,7 +115,9 @@ func (c *Client) ProcessBet(ctx context.Context, req domain.BetRequest) (*domain
|
||||||
return &domain.BetResponse{}, err
|
return &domain.BetResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.walletSvc.DeductFromWallet(ctx, wallets[0].ID, domain.Currency(req.Amount.Amount), domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT)
|
c.walletSvc.DeductFromWallet(ctx, wallets[0].ID, domain.Currency(req.Amount.Amount), domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
|
||||||
|
fmt.Sprintf("Deducting %v from wallet for creating Veli Game Bet", req.Amount.Amount),
|
||||||
|
)
|
||||||
|
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +158,9 @@ func (c *Client) ProcessWin(ctx context.Context, req domain.WinRequest) (*domain
|
||||||
return &domain.WinResponse{}, err
|
return &domain.WinResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.walletSvc.AddToWallet(ctx, wallets[0].ID, domain.Currency(req.Amount.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
|
c.walletSvc.AddToWallet(ctx, wallets[0].ID, domain.Currency(req.Amount.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
|
||||||
|
fmt.Sprintf("Adding %v to wallet due to winning Veli Games bet", req.Amount),
|
||||||
|
)
|
||||||
|
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +203,9 @@ func (c *Client) ProcessCancel(ctx context.Context, req domain.CancelRequest) (*
|
||||||
return &domain.CancelResponse{}, err
|
return &domain.CancelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.walletSvc.AddToWallet(ctx, wallets[0].ID, domain.Currency(req.AdjustmentRefund.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
|
c.walletSvc.AddToWallet(ctx, wallets[0].ID, domain.Currency(req.AdjustmentRefund.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
|
||||||
|
fmt.Sprintf("Adding %v to wallet due to cancelling virtual game bet", req.AdjustmentRefund.Amount),
|
||||||
|
)
|
||||||
return &res, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
303
internal/web_server/handlers/shop_handler.go
Normal file
303
internal/web_server/handlers/shop_handler.go
Normal file
|
|
@ -0,0 +1,303 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateShopBet godoc
|
||||||
|
// @Summary Create bet at branch
|
||||||
|
// @Description Create bet at branch
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param createBet body domain.ShopBetReq true "create bet"
|
||||||
|
// @Success 200 {object} TransactionRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/bet [post]
|
||||||
|
func (h *Handler) CreateShopBet(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
userID := c.Locals("user_id").(int64)
|
||||||
|
role := c.Locals("role").(domain.Role)
|
||||||
|
company_id := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
|
||||||
|
var req domain.ShopBetReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("CreateBetReq failed to parse request", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := h.validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
h.logger.Error("CreateBetReq failed v", "error", valErrs)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
shopBet, err := h.transactionSvc.CreateShopBet(c.Context(), userID, role, company_id, req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to cashout bet", err, nil)
|
||||||
|
}
|
||||||
|
res := domain.ConvertShopBet(shopBet)
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CashoutBet godoc
|
||||||
|
// @Summary Cashout bet at branch
|
||||||
|
// @Description Cashout bet at branch
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param createBet body domain.CashoutReq true "cashout bet"
|
||||||
|
// @Success 200 {object} TransactionRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/bet/{id}/cashout [post]
|
||||||
|
func (h *Handler) CashoutBet(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
betIDStr := c.Params("id")
|
||||||
|
|
||||||
|
betID, err := strconv.ParseInt(betIDStr, 10, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("CashoutReq invalid bet id", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet id", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
userID := c.Locals("user_id").(int64)
|
||||||
|
role := c.Locals("role").(domain.Role)
|
||||||
|
|
||||||
|
var req domain.CashoutReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("CashoutReq failed to parse request", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := h.validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
h.logger.Error("CashoutReq failed v", "error", valErrs)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction, err := h.transactionSvc.CashoutBet(c.Context(), betID, userID, role, req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to cashout bet", err, nil)
|
||||||
|
}
|
||||||
|
res := domain.ConvertShopTransaction(transaction)
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepositForCustomer godoc
|
||||||
|
// @Summary Shop deposit into customer wallet
|
||||||
|
// @Description Transfers money from branch wallet to customer wallet
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param transferToWallet body domain.ShopDepositReq true "ShopDepositReq"
|
||||||
|
// @Success 200 {object} TransferWalletRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/deposit [post]
|
||||||
|
func (h *Handler) DepositForCustomer(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
// Get sender ID from the cashier
|
||||||
|
userID := c.Locals("user_id").(int64)
|
||||||
|
role := c.Locals("role").(domain.Role)
|
||||||
|
|
||||||
|
var req domain.ShopDepositReq
|
||||||
|
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("CreateTransferReq failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := h.validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
deposit, err := h.transactionSvc.CreateShopDeposit(c.Context(), userID, role, req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to create shop deposit", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := domain.ConvertShopDeposit(deposit)
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transfer Successful", res, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllTransactions godoc
|
||||||
|
// @Summary Gets all transactions
|
||||||
|
// @Description Gets all the transactions
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} TransactionRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/transaction [get]
|
||||||
|
func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
|
||||||
|
// Get user_id from middleware
|
||||||
|
// userID := c.Locals("user_id").(int64)
|
||||||
|
// role := c.Locals("role").(domain.Role)
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
branchID := c.Locals("branch_id").(domain.ValidInt64)
|
||||||
|
|
||||||
|
searchQuery := c.Query("query")
|
||||||
|
searchString := domain.ValidString{
|
||||||
|
Value: searchQuery,
|
||||||
|
Valid: searchQuery != "",
|
||||||
|
}
|
||||||
|
|
||||||
|
createdBeforeQuery := c.Query("created_before")
|
||||||
|
var createdBefore domain.ValidTime
|
||||||
|
if createdBeforeQuery != "" {
|
||||||
|
createdBeforeParsed, err := time.Parse(time.RFC3339, createdBeforeQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdBefore = domain.ValidTime{
|
||||||
|
Value: createdBeforeParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAfterQuery := c.Query("created_after")
|
||||||
|
var createdAfter domain.ValidTime
|
||||||
|
if createdAfterQuery != "" {
|
||||||
|
createdAfterParsed, err := time.Parse(time.RFC3339, createdAfterQuery)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("invalid start_time format", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
||||||
|
}
|
||||||
|
createdAfter = domain.ValidTime{
|
||||||
|
Value: createdAfterParsed,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check user role and fetch transactions accordingly
|
||||||
|
transactions, err := h.transactionSvc.GetAllShopTransactions(c.Context(), domain.ShopTransactionFilter{
|
||||||
|
CompanyID: companyID,
|
||||||
|
BranchID: branchID,
|
||||||
|
Query: searchString,
|
||||||
|
CreatedBefore: createdBefore,
|
||||||
|
CreatedAfter: createdAfter,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to get transactions", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve transactions", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]domain.ShopTransactionRes, len(transactions))
|
||||||
|
for i, transaction := range transactions {
|
||||||
|
res[i] = domain.ConvertShopTransactionDetail(transaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transactions retrieved successfully", res, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTransactionByID godoc
|
||||||
|
// @Summary Gets transaction by id
|
||||||
|
// @Description Gets a single transaction by id
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Transaction ID"
|
||||||
|
// @Success 200 {object} TransactionRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/transaction/{id} [get]
|
||||||
|
func (h *Handler) GetTransactionByID(c *fiber.Ctx) error {
|
||||||
|
transactionID := c.Params("id")
|
||||||
|
id, err := strconv.ParseInt(transactionID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to get transaction by ID", "transactionID", id, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve transaction")
|
||||||
|
}
|
||||||
|
|
||||||
|
res := domain.ConvertShopTransactionDetail(transaction)
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction retrieved successfully", res, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateTransactionVerifiedReq struct {
|
||||||
|
Verified bool `json:"verified" example:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTransactionVerified godoc
|
||||||
|
// @Summary Updates the verified field of a transaction
|
||||||
|
// @Description Updates the verified status of a transaction
|
||||||
|
// @Tags transaction
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Transaction ID"
|
||||||
|
// @Param updateVerified body UpdateTransactionVerifiedReq true "Updates Transaction Verification"
|
||||||
|
// @Success 200 {object} response.APIResponse
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /shop/transaction/{id} [put]
|
||||||
|
func (h *Handler) UpdateTransactionVerified(c *fiber.Ctx) error {
|
||||||
|
transactionID := c.Params("id")
|
||||||
|
userID := c.Locals("user_id").(int64)
|
||||||
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
||||||
|
role := c.Locals("role").(domain.Role)
|
||||||
|
|
||||||
|
id, err := strconv.ParseInt(transactionID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
var req UpdateTransactionVerifiedReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.logger.Info("Update Transaction Verified", slog.Bool("verified", req.Verified))
|
||||||
|
|
||||||
|
if valErrs, ok := h.validator.Validate(c, req); !ok {
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
||||||
|
if role != domain.RoleSuperAdmin {
|
||||||
|
if !companyID.Valid || companyID.Value != transaction.CompanyID {
|
||||||
|
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := h.userSvc.GetUserById(c.Context(), userID)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Invalid user ID", "userID", userID, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID")
|
||||||
|
}
|
||||||
|
err = h.transactionSvc.UpdateShopTransactionVerified(c.Context(), id, req.Verified, userID, user.FirstName+" "+user.LastName)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to update transaction verification", "transactionID", id, "error", err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update transaction verification")
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction updated successfully", nil, nil)
|
||||||
|
}
|
||||||
|
|
@ -1,498 +0,0 @@
|
||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log/slog"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ShopTransactionRes struct {
|
|
||||||
ID int64 `json:"id" example:"1"`
|
|
||||||
Amount float32 `json:"amount" example:"100.0"`
|
|
||||||
BranchID int64 `json:"branch_id" example:"1"`
|
|
||||||
BranchName string `json:"branch_name" example:"Branch Name"`
|
|
||||||
BranchLocation string `json:"branch_location" example:"Branch Location"`
|
|
||||||
CompanyID int64 `json:"company_id" example:"1"`
|
|
||||||
CashierID int64 `json:"cashier_id" example:"1"`
|
|
||||||
CashierName string `json:"cashier_name" example:"John Smith"`
|
|
||||||
BetID int64 `json:"bet_id" example:"1"`
|
|
||||||
NumberOfOutcomes int64 `json:"number_of_outcomes" example:"1"`
|
|
||||||
Type int64 `json:"type" example:"1"`
|
|
||||||
PaymentOption domain.PaymentOption `json:"payment_option" example:"1"`
|
|
||||||
FullName string `json:"full_name" example:"John Smith"`
|
|
||||||
PhoneNumber string `json:"phone_number" example:"0911111111"`
|
|
||||||
BankCode string `json:"bank_code"`
|
|
||||||
BeneficiaryName string `json:"beneficiary_name"`
|
|
||||||
AccountName string `json:"account_name"`
|
|
||||||
AccountNumber string `json:"account_number"`
|
|
||||||
ReferenceNumber string `json:"reference_number"`
|
|
||||||
Verified bool `json:"verified" example:"true"`
|
|
||||||
ApprovedBy *int64 `json:"approved_by" example:"1"`
|
|
||||||
ApproverName *string `json:"approver_name" example:"John Smith"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CashoutReq struct {
|
|
||||||
CashoutID string `json:"cashout_id" example:"191212"`
|
|
||||||
Amount float32 `json:"amount" example:"100.0"`
|
|
||||||
BetID int64 `json:"bet_id" example:"1"`
|
|
||||||
Type int64 `json:"type" example:"1"`
|
|
||||||
PaymentOption domain.PaymentOption `json:"payment_option" example:"1"`
|
|
||||||
FullName string `json:"full_name" example:"John Smith"`
|
|
||||||
PhoneNumber string `json:"phone_number" example:"0911111111"`
|
|
||||||
BankCode string `json:"bank_code"`
|
|
||||||
BeneficiaryName string `json:"beneficiary_name"`
|
|
||||||
AccountName string `json:"account_name"`
|
|
||||||
AccountNumber string `json:"account_number"`
|
|
||||||
ReferenceNumber string `json:"reference_number"`
|
|
||||||
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertShopTransaction(transaction domain.ShopTransaction) ShopTransactionRes {
|
|
||||||
newTransaction := ShopTransactionRes{
|
|
||||||
ID: transaction.ID,
|
|
||||||
Amount: transaction.Amount.Float32(),
|
|
||||||
BranchID: transaction.BranchID,
|
|
||||||
BranchName: transaction.BranchName,
|
|
||||||
BranchLocation: transaction.BranchLocation,
|
|
||||||
CompanyID: transaction.CompanyID,
|
|
||||||
CashierID: transaction.CashierID,
|
|
||||||
CashierName: transaction.CashierName,
|
|
||||||
BetID: transaction.BetID,
|
|
||||||
Type: int64(transaction.Type),
|
|
||||||
PaymentOption: transaction.PaymentOption,
|
|
||||||
FullName: transaction.FullName,
|
|
||||||
PhoneNumber: transaction.PhoneNumber,
|
|
||||||
BankCode: transaction.BankCode,
|
|
||||||
BeneficiaryName: transaction.BeneficiaryName,
|
|
||||||
AccountName: transaction.AccountName,
|
|
||||||
AccountNumber: transaction.AccountNumber,
|
|
||||||
ReferenceNumber: transaction.ReferenceNumber,
|
|
||||||
Verified: transaction.Verified,
|
|
||||||
NumberOfOutcomes: transaction.NumberOfOutcomes,
|
|
||||||
CreatedAt: transaction.CreatedAt,
|
|
||||||
UpdatedAt: transaction.UpdatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
if transaction.ApprovedBy.Valid {
|
|
||||||
newTransaction.ApprovedBy = &transaction.ApprovedBy.Value
|
|
||||||
newTransaction.ApproverName = &transaction.ApproverName.Value
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return newTransaction
|
|
||||||
}
|
|
||||||
|
|
||||||
// CashoutBet godoc
|
|
||||||
// @Summary Cashout bet at branch
|
|
||||||
// @Description Cashout bet at branch
|
|
||||||
// @Tags transaction
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param createBet body CashoutReq true "cashout bet"
|
|
||||||
// @Success 200 {object} TransactionRes
|
|
||||||
// @Failure 400 {object} response.APIResponse
|
|
||||||
// @Failure 500 {object} response.APIResponse
|
|
||||||
// @Router /shop/cashout [post]
|
|
||||||
func (h *Handler) CashoutBet(c *fiber.Ctx) error {
|
|
||||||
userID := c.Locals("user_id").(int64)
|
|
||||||
role := c.Locals("role").(domain.Role)
|
|
||||||
// user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
|
||||||
|
|
||||||
// TODO: Make a "Only Company" middleware auth and move this into that
|
|
||||||
if role == domain.RoleCustomer {
|
|
||||||
h.logger.Error("CashoutReq failed due to unauthorized access")
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
||||||
"error": "unauthorized access",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var req CashoutReq
|
|
||||||
if err := c.BodyParser(&req); err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed to parse request", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
valErrs, ok := h.validator.Validate(c, req)
|
|
||||||
if !ok {
|
|
||||||
h.logger.Error("CashoutReq failed v", "error", valErrs)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
var branchID int64
|
|
||||||
var branchName string
|
|
||||||
var branchLocation string
|
|
||||||
var companyID int64
|
|
||||||
if role == domain.RoleAdmin || role == domain.RoleBranchManager || role == domain.RoleSuperAdmin {
|
|
||||||
if req.BranchID == nil {
|
|
||||||
h.logger.Error("CashoutReq Branch ID is required for this user role")
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID is required for this user role", nil, nil)
|
|
||||||
}
|
|
||||||
branch, err := h.branchSvc.GetBranchByID(c.Context(), *req.BranchID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq no branches")
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "cannot find Branch ID", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
branchID = branch.ID
|
|
||||||
branchName = branch.Name
|
|
||||||
branchLocation = branch.Location
|
|
||||||
companyID = branch.CompanyID
|
|
||||||
} else {
|
|
||||||
branch, err := h.branchSvc.GetBranchByCashier(c.Context(), userID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed, branch id invalid")
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID invalid", err, nil)
|
|
||||||
}
|
|
||||||
branchID = branch.ID
|
|
||||||
branchName = branch.Name
|
|
||||||
branchLocation = branch.Location
|
|
||||||
companyID = branch.CompanyID
|
|
||||||
}
|
|
||||||
|
|
||||||
bet, err := h.betSvc.GetBetByID(c.Context(), req.BetID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Bet ID invalid", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if bet.Status != domain.OUTCOME_STATUS_WIN {
|
|
||||||
// h.logger.Error("CashoutReq failed, bet has not won")
|
|
||||||
// return response.WriteJSON(c, fiber.StatusBadRequest, "User has not won bet", err, nil)
|
|
||||||
// }
|
|
||||||
|
|
||||||
if bet.CashedOut {
|
|
||||||
h.logger.Error(("Bet has already been cashed out"))
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "This bet has already been cashed out", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed, user id invalid", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "User ID invalid", err, nil)
|
|
||||||
}
|
|
||||||
transaction, err := h.transactionSvc.CreateShopTransaction(c.Context(), domain.CreateShopTransaction{
|
|
||||||
BranchID: branchID,
|
|
||||||
CashierID: userID,
|
|
||||||
Amount: domain.ToCurrency(req.Amount),
|
|
||||||
BetID: bet.ID,
|
|
||||||
NumberOfOutcomes: int64(len(bet.Outcomes)),
|
|
||||||
Type: domain.ShopTransactionType(req.Type),
|
|
||||||
PaymentOption: domain.PaymentOption(req.PaymentOption),
|
|
||||||
FullName: req.FullName,
|
|
||||||
PhoneNumber: req.PhoneNumber,
|
|
||||||
BankCode: req.BankCode,
|
|
||||||
BeneficiaryName: req.BeneficiaryName,
|
|
||||||
AccountName: req.AccountName,
|
|
||||||
AccountNumber: req.AccountNumber,
|
|
||||||
ReferenceNumber: req.ReferenceNumber,
|
|
||||||
CashierName: user.FirstName + " " + user.LastName,
|
|
||||||
BranchName: branchName,
|
|
||||||
BranchLocation: branchLocation,
|
|
||||||
CompanyID: companyID,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.betSvc.UpdateCashOut(c.Context(), req.BetID, true)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq failed", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
res := convertShopTransaction(transaction)
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DepositForCustomerReq struct {
|
|
||||||
Amount float32 `json:"amount" example:"100.0"`
|
|
||||||
PaymentMethod string `json:"payment_method" example:"cash"`
|
|
||||||
BankCode string `json:"bank_code"`
|
|
||||||
BeneficiaryName string `json:"beneficiary_name"`
|
|
||||||
AccountName string `json:"account_name"`
|
|
||||||
AccountNumber string `json:"account_number"`
|
|
||||||
ReferenceNumber string `json:"reference_number"`
|
|
||||||
BranchID *int64 `json:"branch_id,omitempty" example:"1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DepositForCustomer godoc
|
|
||||||
// @Summary Shop deposit into customer wallet
|
|
||||||
// @Description Transfers money from branch wallet to customer wallet
|
|
||||||
// @Tags transaction
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param transferToWallet body DepositForCustomerReq true "DepositForCustomer"
|
|
||||||
// @Success 200 {object} TransferWalletRes
|
|
||||||
// @Failure 400 {object} response.APIResponse
|
|
||||||
// @Failure 500 {object} response.APIResponse
|
|
||||||
// @Router /shop/deposit/:id [post]
|
|
||||||
|
|
||||||
func (h *Handler) DepositForCustomer(c *fiber.Ctx) error {
|
|
||||||
customerIDString := c.Params("id")
|
|
||||||
customerID, err := strconv.ParseInt(customerIDString, 10, 64)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Invalid customer ID", "customerID", customerID, "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 := c.Locals("role").(domain.Role)
|
|
||||||
|
|
||||||
var req DepositForCustomerReq
|
|
||||||
|
|
||||||
if err := c.BodyParser(&req); err != nil {
|
|
||||||
h.logger.Error("CreateTransferReq failed", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
valErrs, ok := h.validator.Validate(c, req)
|
|
||||||
if !ok {
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
||||||
}
|
|
||||||
var senderID int64
|
|
||||||
switch role {
|
|
||||||
case domain.RoleCustomer:
|
|
||||||
h.logger.Error("Unauthorized access", "userID", userID, "role", role)
|
|
||||||
return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
|
|
||||||
case domain.RoleAdmin, domain.RoleSuperAdmin, domain.RoleBranchManager:
|
|
||||||
if req.BranchID == nil {
|
|
||||||
h.logger.Error("CashoutReq Branch ID is required for this user role")
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID is required for this user role", nil, nil)
|
|
||||||
}
|
|
||||||
branch, err := h.branchSvc.GetBranchByID(c.Context(), *req.BranchID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("CashoutReq no branches")
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "cannot find Branch ID", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
senderID = branch.WalletID
|
|
||||||
case domain.RoleCashier:
|
|
||||||
cashierBranch, err := h.branchSvc.GetBranchByCashier(c.Context(), userID)
|
|
||||||
if err != nil {
|
|
||||||
h.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
|
|
||||||
default:
|
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Unknown Role", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
customerWallet, err := h.walletSvc.GetCustomerWallet(c.Context(), customerID)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid customer id", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer, err := h.walletSvc.TransferToWallet(c.Context(),
|
|
||||||
senderID, customerWallet.RegularID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod),
|
|
||||||
domain.ValidInt64{Value: userID, Valid: true},
|
|
||||||
fmt.Sprintf("Transferred %v from wallet to customer wallet", req.Amount),
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
h.mongoLoggerSvc.Error("Failed to transfer money to wallet", zap.Error(err))
|
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction, err := h.transactionSvc.CreateShopTransaction(c.Context(), domain.CreateShopTransaction{
|
|
||||||
BranchID: branchID,
|
|
||||||
CashierID: userID,
|
|
||||||
Amount: domain.ToCurrency(req.Amount),
|
|
||||||
Type: domain.TRANSACTION_DEPOSIT,
|
|
||||||
PaymentOption: domain.PaymentOption(req.PaymentOption),
|
|
||||||
FullName: req.FullName,
|
|
||||||
PhoneNumber: req.PhoneNumber,
|
|
||||||
BankCode: req.BankCode,
|
|
||||||
BeneficiaryName: req.BeneficiaryName,
|
|
||||||
AccountName: req.AccountName,
|
|
||||||
AccountNumber: req.AccountNumber,
|
|
||||||
ReferenceNumber: req.ReferenceNumber,
|
|
||||||
CashierName: user.FirstName + " " + user.LastName,
|
|
||||||
BranchName: branchName,
|
|
||||||
BranchLocation: branchLocation,
|
|
||||||
CompanyID: companyID,
|
|
||||||
})
|
|
||||||
|
|
||||||
res := convertTransfer(transfer)
|
|
||||||
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Transfer Successful", res, nil)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllTransactions godoc
|
|
||||||
// @Summary Gets all transactions
|
|
||||||
// @Description Gets all the transactions
|
|
||||||
// @Tags transaction
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {array} TransactionRes
|
|
||||||
// @Failure 400 {object} response.APIResponse
|
|
||||||
// @Failure 500 {object} response.APIResponse
|
|
||||||
// @Router /shop/transaction [get]
|
|
||||||
func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
|
|
||||||
// Get user_id from middleware
|
|
||||||
// userID := c.Locals("user_id").(int64)
|
|
||||||
// role := c.Locals("role").(domain.Role)
|
|
||||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
||||||
branchID := c.Locals("branch_id").(domain.ValidInt64)
|
|
||||||
|
|
||||||
searchQuery := c.Query("query")
|
|
||||||
searchString := domain.ValidString{
|
|
||||||
Value: searchQuery,
|
|
||||||
Valid: searchQuery != "",
|
|
||||||
}
|
|
||||||
|
|
||||||
createdBeforeQuery := c.Query("created_before")
|
|
||||||
var createdBefore domain.ValidTime
|
|
||||||
if createdBeforeQuery != "" {
|
|
||||||
createdBeforeParsed, err := time.Parse(time.RFC3339, createdBeforeQuery)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("invalid start_time format", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
|
||||||
}
|
|
||||||
createdBefore = domain.ValidTime{
|
|
||||||
Value: createdBeforeParsed,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createdAfterQuery := c.Query("created_after")
|
|
||||||
var createdAfter domain.ValidTime
|
|
||||||
if createdAfterQuery != "" {
|
|
||||||
createdAfterParsed, err := time.Parse(time.RFC3339, createdAfterQuery)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("invalid start_time format", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
|
||||||
}
|
|
||||||
createdAfter = domain.ValidTime{
|
|
||||||
Value: createdAfterParsed,
|
|
||||||
Valid: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check user role and fetch transactions accordingly
|
|
||||||
transactions, err := h.transactionSvc.GetAllShopTransactions(c.Context(), domain.ShopTransactionFilter{
|
|
||||||
CompanyID: companyID,
|
|
||||||
BranchID: branchID,
|
|
||||||
Query: searchString,
|
|
||||||
CreatedBefore: createdBefore,
|
|
||||||
CreatedAfter: createdAfter,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Failed to get transactions", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve transactions", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]ShopTransactionRes, len(transactions))
|
|
||||||
for i, transaction := range transactions {
|
|
||||||
res[i] = convertShopTransaction(transaction)
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Transactions retrieved successfully", res, nil)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTransactionByID godoc
|
|
||||||
// @Summary Gets transaction by id
|
|
||||||
// @Description Gets a single transaction by id
|
|
||||||
// @Tags transaction
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path int true "Transaction ID"
|
|
||||||
// @Success 200 {object} TransactionRes
|
|
||||||
// @Failure 400 {object} response.APIResponse
|
|
||||||
// @Failure 500 {object} response.APIResponse
|
|
||||||
// @Router /shop/transaction/{id} [get]
|
|
||||||
func (h *Handler) GetTransactionByID(c *fiber.Ctx) error {
|
|
||||||
transactionID := c.Params("id")
|
|
||||||
id, err := strconv.ParseInt(transactionID, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Failed to get transaction by ID", "transactionID", id, "error", err)
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve transaction")
|
|
||||||
}
|
|
||||||
|
|
||||||
res := convertShopTransaction(transaction)
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Transaction retrieved successfully", res, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateTransactionVerifiedReq struct {
|
|
||||||
Verified bool `json:"verified" example:"true"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateTransactionVerified godoc
|
|
||||||
// @Summary Updates the verified field of a transaction
|
|
||||||
// @Description Updates the verified status of a transaction
|
|
||||||
// @Tags transaction
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path int true "Transaction ID"
|
|
||||||
// @Param updateVerified body UpdateTransactionVerifiedReq true "Updates Transaction Verification"
|
|
||||||
// @Success 200 {object} response.APIResponse
|
|
||||||
// @Failure 400 {object} response.APIResponse
|
|
||||||
// @Failure 500 {object} response.APIResponse
|
|
||||||
// @Router /shop/transaction/{id} [put]
|
|
||||||
func (h *Handler) UpdateTransactionVerified(c *fiber.Ctx) error {
|
|
||||||
transactionID := c.Params("id")
|
|
||||||
userID := c.Locals("user_id").(int64)
|
|
||||||
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
||||||
role := c.Locals("role").(domain.Role)
|
|
||||||
|
|
||||||
id, err := strconv.ParseInt(transactionID, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
var req UpdateTransactionVerifiedReq
|
|
||||||
if err := c.BodyParser(&req); err != nil {
|
|
||||||
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.logger.Info("Update Transaction Verified", slog.Bool("verified", req.Verified))
|
|
||||||
|
|
||||||
if valErrs, ok := h.validator.Validate(c, req); !ok {
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
|
||||||
if role != domain.RoleSuperAdmin {
|
|
||||||
if !companyID.Valid || companyID.Value != transaction.CompanyID {
|
|
||||||
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
|
||||||
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := h.userSvc.GetUserById(c.Context(), userID)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Invalid user ID", "userID", userID, "error", err)
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID")
|
|
||||||
}
|
|
||||||
err = h.transactionSvc.UpdateShopTransactionVerified(c.Context(), id, req.Verified, userID, user.FirstName+" "+user.LastName)
|
|
||||||
if err != nil {
|
|
||||||
h.logger.Error("Failed to update transaction verification", "transactionID", id, "error", err)
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update transaction verification")
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.WriteJSON(c, fiber.StatusOK, "Transaction updated successfully", nil, nil)
|
|
||||||
}
|
|
||||||
|
|
@ -273,7 +273,9 @@ func (a *App) initAppRoutes() {
|
||||||
// group.Get("/virtual-games/recommendations/:userID", h.GetRecommendations)
|
// group.Get("/virtual-games/recommendations/:userID", h.GetRecommendations)
|
||||||
|
|
||||||
// Transactions /shop/transactions
|
// Transactions /shop/transactions
|
||||||
a.fiber.Post("/shop/cashout", a.authMiddleware, h.CashoutBet)
|
a.fiber.Post("/shop/bet", a.authMiddleware, a.CompanyOnly, h.CreateShopBet)
|
||||||
|
a.fiber.Post("/shop/bet/:id/cashout", a.authMiddleware, a.CompanyOnly, h.CashoutBet)
|
||||||
|
a.fiber.Post("/shop/deposit", a.authMiddleware, a.CompanyOnly, h.DepositForCustomer)
|
||||||
a.fiber.Get("/shop/transaction", a.authMiddleware, h.GetAllTransactions)
|
a.fiber.Get("/shop/transaction", a.authMiddleware, h.GetAllTransactions)
|
||||||
a.fiber.Get("/shop/transaction/:id", a.authMiddleware, h.GetTransactionByID)
|
a.fiber.Get("/shop/transaction/:id", a.authMiddleware, h.GetTransactionByID)
|
||||||
a.fiber.Put("/shop/transaction/:id", a.authMiddleware, h.UpdateTransactionVerified)
|
a.fiber.Put("/shop/transaction/:id", a.authMiddleware, h.UpdateTransactionVerified)
|
||||||
|
|
|
||||||
5
makefile
5
makefile
|
|
@ -43,7 +43,8 @@ migrations/up:
|
||||||
postgres:
|
postgres:
|
||||||
@echo 'Running postgres db...'
|
@echo 'Running postgres db...'
|
||||||
docker compose -f docker-compose.yml exec postgres psql -U root -d gh
|
docker compose -f docker-compose.yml exec postgres psql -U root -d gh
|
||||||
|
postgres_log:
|
||||||
|
docker logs fortunebet-backend-postgres-1
|
||||||
.PHONY: swagger
|
.PHONY: swagger
|
||||||
swagger:
|
swagger:
|
||||||
@swag init -g cmd/main.go
|
@swag init -g cmd/main.go
|
||||||
|
|
@ -51,7 +52,7 @@ swagger:
|
||||||
.PHONY: db-up
|
.PHONY: db-up
|
||||||
db-up:
|
db-up:
|
||||||
@docker compose up -d postgres migrate mongo redis
|
@docker compose up -d postgres migrate mongo redis
|
||||||
|
@docker logs fortunebet-backend-postgres-1 > logs/postgres.log 2>&1 &
|
||||||
.PHONY: db-down
|
.PHONY: db-down
|
||||||
db-down:
|
db-down:
|
||||||
@docker compose down
|
@docker compose down
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user