fixed company-id, admin-id optional parameters for creating company and branch

This commit is contained in:
Samuel Tariku 2025-04-30 18:43:46 +03:00
parent f25f6a3f85
commit ae571d51a6
34 changed files with 480 additions and 145 deletions

View File

@ -1,5 +1,7 @@
{
"cSpell.words": [
"Cashout"
"Cashout",
"narg",
"sqlc"
]
}

View File

@ -99,18 +99,6 @@ CREATE TABLE IF NOT EXISTS ticket_outcomes (
status INT NOT NULL DEFAULT 0,
expires TIMESTAMP NOT NULL
);
CREATE VIEW bet_with_outcomes AS
SELECT bets.*,
JSON_AGG(bet_outcomes.*) AS outcomes
FROM bets
LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id
GROUP BY bets.id;
CREATE VIEW ticket_with_outcomes AS
SELECT tickets.*,
JSON_AGG(ticket_outcomes.*) AS outcomes
FROM tickets
LEFT JOIN ticket_outcomes ON tickets.id = ticket_outcomes.ticket_id
GROUP BY tickets.id;
CREATE TABLE IF NOT EXISTS wallets (
id BIGSERIAL PRIMARY KEY,
balance BIGINT NOT NULL DEFAULT 0,
@ -148,7 +136,9 @@ CREATE TABLE IF NOT EXISTS transactions (
id BIGSERIAL PRIMARY KEY,
amount BIGINT NOT NULL,
branch_id BIGINT NOT NULL,
company_id BIGINT NOT NULL,
cashier_id BIGINT NOT NULL,
cashier_name VARCHAR(255) NOT NULL,
bet_id BIGINT NOT NULL,
number_of_outcomes BIGINT NOT NULL,
type BIGINT NOT NULL,
@ -162,6 +152,9 @@ CREATE TABLE IF NOT EXISTS transactions (
reference_number VARCHAR(255) NOT NULL,
verified BOOLEAN NOT NULL DEFAULT false,
approved_by BIGINT,
approver_name VARCHAR(255),
branch_location VARCHAR(255) NOT NULL,
branch_name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
@ -176,17 +169,6 @@ CREATE TABLE IF NOT EXISTS branches (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE VIEW branch_details AS
SELECT branches.*,
CONCAT(users.first_name, ' ', users.last_name) AS manager_name,
users.phone_number AS manager_phone_number
FROM branches
LEFT JOIN users ON branches.branch_manager_id = users.id;
CREATE TABLE IF NOT EXISTS supported_operations (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS branch_operations (
id BIGSERIAL PRIMARY KEY,
operation_id BIGINT NOT NULL,
@ -250,12 +232,37 @@ CREATE TABLE companies (
admin_id BIGINT NOT NULL,
wallet_id BIGINT NOT NULL
);
-- Views
CREATE VIEW companies_with_wallets AS
SELECT companies.*,
wallets.balance,
wallets.is_active
FROM companies
JOIN wallets ON wallets.id = companies.wallet_id;
CREATE VIEW branch_details AS
SELECT branches.*,
CONCAT(users.first_name, ' ', users.last_name) AS manager_name,
users.phone_number AS manager_phone_number
FROM branches
LEFT JOIN users ON branches.branch_manager_id = users.id;
CREATE TABLE IF NOT EXISTS supported_operations (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL
);
CREATE VIEW bet_with_outcomes AS
SELECT bets.*,
JSON_AGG(bet_outcomes.*) AS outcomes
FROM bets
LEFT JOIN bet_outcomes ON bets.id = bet_outcomes.bet_id
GROUP BY bets.id;
CREATE VIEW ticket_with_outcomes AS
SELECT tickets.*,
JSON_AGG(ticket_outcomes.*) AS outcomes
FROM tickets
LEFT JOIN ticket_outcomes ON tickets.id = ticket_outcomes.ticket_id
GROUP BY tickets.id;
-- Foreign Keys
ALTER TABLE refresh_tokens
ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE bets
@ -279,8 +286,8 @@ ALTER TABLE branches
ADD CONSTRAINT fk_branches_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id),
ADD CONSTRAINT fk_branches_manager FOREIGN KEY (branch_manager_id) REFERENCES users(id);
ALTER TABLE branch_operations
ADD CONSTRAINT fk_branch_operations_operations FOREIGN KEY (operation_id) REFERENCES supported_operations(id),
ADD CONSTRAINT fk_branch_operations_branches FOREIGN KEY (branch_id) REFERENCES branches(id);
ADD CONSTRAINT fk_branch_operations_operations FOREIGN KEY (operation_id) REFERENCES supported_operations(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_branch_operations_branches FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE;
ALTER TABLE branch_cashiers
ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(id),
ADD CONSTRAINT fk_branch_cashiers_branches FOREIGN KEY (branch_id) REFERENCES branches(id);

View File

@ -24,7 +24,6 @@ RETURNING *;
-- name: GetAllBranches :many
SELECT *
FROM branch_details;
-- name: GetBranchByID :one
SELECT *
FROM branch_details
@ -67,12 +66,12 @@ FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id;
-- name: UpdateBranch :one
UPDATE branches
SET name = $1,
location = $2,
branch_manager_id = $3,
company_id = $4,
is_self_owned = $5
WHERE id = $6
SET name = COALESCE(sqlc.narg(name), name),
location = COALESCE(sqlc.narg(location), location),
branch_manager_id = COALESCE(sqlc.narg(branch_manager_id), branch_manager_id),
company_id = COALESCE(sqlc.narg(company_id), company_id),
is_self_owned = COALESCE(sqlc.narg(is_self_owned), is_self_owned)
WHERE id = $1
RETURNING *;
-- name: DeleteBranch :exec
DELETE FROM branches

View File

@ -19,9 +19,9 @@ FROM companies_with_wallets
WHERE name ILIKE '%' || $1 || '%';
-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
SET name = COALESCE(sqlc.narg(name), name),
admin_id = COALESCE(sqlc.narg(admin_id), admin_id)
WHERE id = $1
RETURNING *;
-- name: DeleteCompany :exec
DELETE FROM companies

View File

@ -13,7 +13,11 @@ INSERT INTO transactions (
account_name,
account_number,
reference_number,
number_of_outcomes
number_of_outcomes,
branch_name,
branch_location,
company_id,
cashier_name
)
VALUES (
$1,
@ -29,7 +33,11 @@ VALUES (
$11,
$12,
$13,
$14
$14,
$15,
$16,
$17,
$18
)
RETURNING *;
-- name: GetAllTransactions :many
@ -47,5 +55,6 @@ WHERE branch_id = $1;
UPDATE transactions
SET verified = $2,
approved_by = $3,
approver_name = $4,
updated_at = CURRENT_TIMESTAMP
WHERE id = $1;

View File

@ -1,14 +1,29 @@
-- name: CreateTransfer :one
INSERT INTO wallet_transfer (amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *;
INSERT INTO wallet_transfer (
amount,
type,
receiver_wallet_id,
sender_wallet_id,
cashier_id,
verified,
payment_method
)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: GetAllTransfers :many
SELECT * FROM wallet_transfer;
SELECT *
FROM wallet_transfer;
-- name: GetTransfersByWallet :many
SELECT * FROM wallet_transfer WHERE receiver_wallet_id = $1 OR sender_wallet_id = $1;
SELECT *
FROM wallet_transfer
WHERE receiver_wallet_id = $1
OR sender_wallet_id = $1;
-- name: GetTransferByID :one
SELECT * FROM wallet_transfer WHERE id = $1;
SELECT *
FROM wallet_transfer
WHERE id = $1;
-- name: UpdateTransferVerification :exec
UPDATE wallet_transfer SET verified = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2;
UPDATE wallet_transfer
SET verified = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2;

View File

@ -105,6 +105,11 @@ SET first_name = $1,
role = $5,
updated_at = $6
WHERE id = $7;
-- name: UpdateUserCompany :exec
UPDATE users
SET company_id = $1
WHERE id = $2;
-- name: SuspendUser :exec
UPDATE users
SET suspended = $1,

View File

@ -514,32 +514,32 @@ func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text)
const UpdateBranch = `-- name: UpdateBranch :one
UPDATE branches
SET name = $1,
location = $2,
branch_manager_id = $3,
company_id = $4,
is_self_owned = $5
WHERE id = $6
SET name = COALESCE($2, name),
location = COALESCE($3, location),
branch_manager_id = COALESCE($4, branch_manager_id),
company_id = COALESCE($5, company_id),
is_self_owned = COALESCE($6, is_self_owned)
WHERE id = $1
RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at
`
type UpdateBranchParams struct {
Name string `json:"name"`
Location string `json:"location"`
BranchManagerID int64 `json:"branch_manager_id"`
CompanyID int64 `json:"company_id"`
IsSelfOwned bool `json:"is_self_owned"`
ID int64 `json:"id"`
Name pgtype.Text `json:"name"`
Location pgtype.Text `json:"location"`
BranchManagerID pgtype.Int8 `json:"branch_manager_id"`
CompanyID pgtype.Int8 `json:"company_id"`
IsSelfOwned pgtype.Bool `json:"is_self_owned"`
}
func (q *Queries) UpdateBranch(ctx context.Context, arg UpdateBranchParams) (Branch, error) {
row := q.db.QueryRow(ctx, UpdateBranch,
arg.ID,
arg.Name,
arg.Location,
arg.BranchManagerID,
arg.CompanyID,
arg.IsSelfOwned,
arg.ID,
)
var i Branch
err := row.Scan(

View File

@ -136,20 +136,20 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text)
const UpdateCompany = `-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
SET name = COALESCE($2, name),
admin_id = COALESCE($3, admin_id)
WHERE id = $1
RETURNING id, name, admin_id, wallet_id
`
type UpdateCompanyParams struct {
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
ID int64 `json:"id"`
Name pgtype.Text `json:"name"`
AdminID pgtype.Int8 `json:"admin_id"`
}
func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (Company, error) {
row := q.db.QueryRow(ctx, UpdateCompany, arg.Name, arg.AdminID, arg.ID)
row := q.db.QueryRow(ctx, UpdateCompany, arg.ID, arg.Name, arg.AdminID)
var i Company
err := row.Scan(
&i.ID,

View File

@ -337,7 +337,9 @@ type Transaction struct {
ID int64 `json:"id"`
Amount int64 `json:"amount"`
BranchID int64 `json:"branch_id"`
CompanyID int64 `json:"company_id"`
CashierID int64 `json:"cashier_id"`
CashierName string `json:"cashier_name"`
BetID int64 `json:"bet_id"`
NumberOfOutcomes int64 `json:"number_of_outcomes"`
Type int64 `json:"type"`
@ -351,6 +353,9 @@ type Transaction struct {
ReferenceNumber string `json:"reference_number"`
Verified bool `json:"verified"`
ApprovedBy pgtype.Int8 `json:"approved_by"`
ApproverName pgtype.Text `json:"approver_name"`
BranchLocation string `json:"branch_location"`
BranchName string `json:"branch_name"`
CreatedAt pgtype.Timestamp `json:"created_at"`
UpdatedAt pgtype.Timestamp `json:"updated_at"`
}

View File

@ -26,7 +26,11 @@ INSERT INTO transactions (
account_name,
account_number,
reference_number,
number_of_outcomes
number_of_outcomes,
branch_name,
branch_location,
company_id,
cashier_name
)
VALUES (
$1,
@ -42,9 +46,13 @@ VALUES (
$11,
$12,
$13,
$14
$14,
$15,
$16,
$17,
$18
)
RETURNING id, amount, branch_id, cashier_id, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, created_at, updated_at
RETURNING id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, approver_name, branch_location, branch_name, created_at, updated_at
`
type CreateTransactionParams struct {
@ -62,6 +70,10 @@ type CreateTransactionParams struct {
AccountNumber string `json:"account_number"`
ReferenceNumber string `json:"reference_number"`
NumberOfOutcomes int64 `json:"number_of_outcomes"`
BranchName string `json:"branch_name"`
BranchLocation string `json:"branch_location"`
CompanyID int64 `json:"company_id"`
CashierName string `json:"cashier_name"`
}
func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionParams) (Transaction, error) {
@ -80,13 +92,19 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa
arg.AccountNumber,
arg.ReferenceNumber,
arg.NumberOfOutcomes,
arg.BranchName,
arg.BranchLocation,
arg.CompanyID,
arg.CashierName,
)
var i Transaction
err := row.Scan(
&i.ID,
&i.Amount,
&i.BranchID,
&i.CompanyID,
&i.CashierID,
&i.CashierName,
&i.BetID,
&i.NumberOfOutcomes,
&i.Type,
@ -100,6 +118,9 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa
&i.ReferenceNumber,
&i.Verified,
&i.ApprovedBy,
&i.ApproverName,
&i.BranchLocation,
&i.BranchName,
&i.CreatedAt,
&i.UpdatedAt,
)
@ -107,7 +128,7 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa
}
const GetAllTransactions = `-- name: GetAllTransactions :many
SELECT id, amount, branch_id, cashier_id, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, created_at, updated_at
SELECT id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, approver_name, branch_location, branch_name, created_at, updated_at
FROM transactions
`
@ -124,7 +145,9 @@ func (q *Queries) GetAllTransactions(ctx context.Context) ([]Transaction, error)
&i.ID,
&i.Amount,
&i.BranchID,
&i.CompanyID,
&i.CashierID,
&i.CashierName,
&i.BetID,
&i.NumberOfOutcomes,
&i.Type,
@ -138,6 +161,9 @@ func (q *Queries) GetAllTransactions(ctx context.Context) ([]Transaction, error)
&i.ReferenceNumber,
&i.Verified,
&i.ApprovedBy,
&i.ApproverName,
&i.BranchLocation,
&i.BranchName,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
@ -152,7 +178,7 @@ func (q *Queries) GetAllTransactions(ctx context.Context) ([]Transaction, error)
}
const GetTransactionByBranch = `-- name: GetTransactionByBranch :many
SELECT id, amount, branch_id, cashier_id, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, created_at, updated_at
SELECT id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, approver_name, branch_location, branch_name, created_at, updated_at
FROM transactions
WHERE branch_id = $1
`
@ -170,7 +196,9 @@ func (q *Queries) GetTransactionByBranch(ctx context.Context, branchID int64) ([
&i.ID,
&i.Amount,
&i.BranchID,
&i.CompanyID,
&i.CashierID,
&i.CashierName,
&i.BetID,
&i.NumberOfOutcomes,
&i.Type,
@ -184,6 +212,9 @@ func (q *Queries) GetTransactionByBranch(ctx context.Context, branchID int64) ([
&i.ReferenceNumber,
&i.Verified,
&i.ApprovedBy,
&i.ApproverName,
&i.BranchLocation,
&i.BranchName,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
@ -198,7 +229,7 @@ func (q *Queries) GetTransactionByBranch(ctx context.Context, branchID int64) ([
}
const GetTransactionByID = `-- name: GetTransactionByID :one
SELECT id, amount, branch_id, cashier_id, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, created_at, updated_at
SELECT id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, number_of_outcomes, type, payment_option, full_name, phone_number, bank_code, beneficiary_name, account_name, account_number, reference_number, verified, approved_by, approver_name, branch_location, branch_name, created_at, updated_at
FROM transactions
WHERE id = $1
`
@ -210,7 +241,9 @@ func (q *Queries) GetTransactionByID(ctx context.Context, id int64) (Transaction
&i.ID,
&i.Amount,
&i.BranchID,
&i.CompanyID,
&i.CashierID,
&i.CashierName,
&i.BetID,
&i.NumberOfOutcomes,
&i.Type,
@ -224,6 +257,9 @@ func (q *Queries) GetTransactionByID(ctx context.Context, id int64) (Transaction
&i.ReferenceNumber,
&i.Verified,
&i.ApprovedBy,
&i.ApproverName,
&i.BranchLocation,
&i.BranchName,
&i.CreatedAt,
&i.UpdatedAt,
)
@ -234,6 +270,7 @@ const UpdateTransactionVerified = `-- name: UpdateTransactionVerified :exec
UPDATE transactions
SET verified = $2,
approved_by = $3,
approver_name = $4,
updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`
@ -242,9 +279,15 @@ type UpdateTransactionVerifiedParams struct {
ID int64 `json:"id"`
Verified bool `json:"verified"`
ApprovedBy pgtype.Int8 `json:"approved_by"`
ApproverName pgtype.Text `json:"approver_name"`
}
func (q *Queries) UpdateTransactionVerified(ctx context.Context, arg UpdateTransactionVerifiedParams) error {
_, err := q.db.Exec(ctx, UpdateTransactionVerified, arg.ID, arg.Verified, arg.ApprovedBy)
_, err := q.db.Exec(ctx, UpdateTransactionVerified,
arg.ID,
arg.Verified,
arg.ApprovedBy,
arg.ApproverName,
)
return err
}

View File

@ -12,7 +12,17 @@ import (
)
const CreateTransfer = `-- name: CreateTransfer :one
INSERT INTO wallet_transfer (amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at
INSERT INTO wallet_transfer (
amount,
type,
receiver_wallet_id,
sender_wallet_id,
cashier_id,
verified,
payment_method
)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at
`
type CreateTransferParams struct {
@ -52,7 +62,8 @@ func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams)
}
const GetAllTransfers = `-- name: GetAllTransfers :many
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at FROM wallet_transfer
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at
FROM wallet_transfer
`
func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error) {
@ -87,7 +98,9 @@ func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error)
}
const GetTransferByID = `-- name: GetTransferByID :one
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at FROM wallet_transfer WHERE id = $1
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at
FROM wallet_transfer
WHERE id = $1
`
func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer, error) {
@ -109,7 +122,10 @@ func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer
}
const GetTransfersByWallet = `-- name: GetTransfersByWallet :many
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at FROM wallet_transfer WHERE receiver_wallet_id = $1 OR sender_wallet_id = $1
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, payment_method, created_at, updated_at
FROM wallet_transfer
WHERE receiver_wallet_id = $1
OR sender_wallet_id = $1
`
func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID int64) ([]WalletTransfer, error) {
@ -144,7 +160,10 @@ func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID int
}
const UpdateTransferVerification = `-- name: UpdateTransferVerification :exec
UPDATE wallet_transfer SET verified = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2
UPDATE wallet_transfer
SET verified = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2
`
type UpdateTransferVerificationParams struct {

View File

@ -561,3 +561,19 @@ func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) error {
)
return err
}
const UpdateUserCompany = `-- name: UpdateUserCompany :exec
UPDATE users
SET company_id = $1
WHERE id = $2
`
type UpdateUserCompanyParams struct {
CompanyID pgtype.Int8 `json:"company_id"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateUserCompany(ctx context.Context, arg UpdateUserCompanyParams) error {
_, err := q.db.Exec(ctx, UpdateUserCompany, arg.CompanyID, arg.ID)
return err
}

View File

@ -44,11 +44,12 @@ type CreateBranch struct {
}
type UpdateBranch struct {
Name string
Location string
BranchManagerID int64
CompanyID int64
IsSelfOwned bool
ID int64
Name *string
Location *string
BranchManagerID *int64
CompanyID *int64
IsSelfOwned *bool
}
type CreateSupportedOperation struct {

View File

@ -26,6 +26,7 @@ type CreateCompany struct {
}
type UpdateCompany struct {
Name string
AdminID int64
ID int64
Name *string
AdminID *int64
}

View File

@ -24,7 +24,11 @@ type Transaction struct {
ID int64
Amount Currency
BranchID int64
BranchName string
BranchLocation string
CompanyID int64
CashierID int64
CashierName string
BetID int64
NumberOfOutcomes int64
Type TransactionType
@ -39,10 +43,10 @@ type Transaction struct {
ReferenceNumber string
Verified bool
ApprovedBy ValidInt64
ApproverName ValidString
UpdatedAt time.Time
CreatedAt time.Time
}
type CreateTransaction struct {
Amount Currency
BranchID int64
@ -59,4 +63,8 @@ type CreateTransaction struct {
AccountName string
AccountNumber string
ReferenceNumber string
BranchName string
BranchLocation string
CompanyID int64
CashierName string
}

View File

@ -45,6 +45,46 @@ func convertDBBranch(dbBranch dbgen.Branch) domain.Branch {
}
}
func convertUpdateBranch(updateBranch domain.UpdateBranch) dbgen.UpdateBranchParams {
var newUpdateBranch dbgen.UpdateBranchParams
newUpdateBranch.ID = updateBranch.ID
if updateBranch.Name != nil {
newUpdateBranch.Name = pgtype.Text{
String: *updateBranch.Name,
Valid: true,
}
}
if updateBranch.Location != nil {
newUpdateBranch.Location = pgtype.Text{
String: *updateBranch.Location,
Valid: true,
}
}
if updateBranch.BranchManagerID != nil {
newUpdateBranch.BranchManagerID = pgtype.Int8{
Int64: *updateBranch.BranchManagerID,
Valid: true,
}
}
if updateBranch.CompanyID != nil {
newUpdateBranch.CompanyID = pgtype.Int8{
Int64: *updateBranch.CompanyID,
Valid: true,
}
}
if updateBranch.IsSelfOwned != nil {
newUpdateBranch.IsSelfOwned = pgtype.Bool{
Bool: *updateBranch.IsSelfOwned,
Valid: true,
}
}
return newUpdateBranch
}
func (s *Store) CreateBranch(ctx context.Context, branch domain.CreateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.CreateBranch(ctx, convertCreateBranch(branch))
@ -111,14 +151,9 @@ func (s *Store) SearchBranchByName(ctx context.Context, name string) ([]domain.B
return branches, nil
}
func (s *Store) UpdateBranch(ctx context.Context, id int64, branch domain.UpdateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.UpdateBranch(ctx, dbgen.UpdateBranchParams{
ID: id,
Name: branch.Name,
Location: branch.Location,
BranchManagerID: branch.BranchManagerID,
IsSelfOwned: branch.IsSelfOwned,
})
func (s *Store) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) {
dbBranch, err := s.queries.UpdateBranch(ctx, convertUpdateBranch(branch))
if err != nil {
return domain.Branch{}, err
}
@ -209,7 +244,6 @@ func (s *Store) GetBranchByCashier(ctx context.Context, userID int64) (domain.Br
return convertDBBranch(branch), err
}
func (s *Store) DeleteBranchOperation(ctx context.Context, branchID int64, operationID int64) error {
err := s.queries.DeleteBranchOperation(ctx, dbgen.DeleteBranchOperationParams{
BranchID: branchID,

View File

@ -36,6 +36,28 @@ func convertDBCompanyWithWallet(dbCompany dbgen.CompaniesWithWallet) domain.GetC
}
}
func convertUpdateCompany(updateCompany domain.UpdateCompany) dbgen.UpdateCompanyParams {
var newUpdateCompany dbgen.UpdateCompanyParams
newUpdateCompany.ID = updateCompany.ID
if updateCompany.Name != nil {
newUpdateCompany.Name = pgtype.Text{
String: *updateCompany.Name,
Valid: true,
}
}
if updateCompany.AdminID != nil {
newUpdateCompany.AdminID = pgtype.Int8{
Int64: *updateCompany.AdminID,
Valid: true,
}
}
return newUpdateCompany
}
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
dbCompany, err := s.queries.CreateCompany(ctx, convertCreateCompany(company))
if err != nil {
@ -84,12 +106,8 @@ func (s *Store) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany
return convertDBCompanyWithWallet(dbCompany), nil
}
func (s *Store) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
dbCompany, err := s.queries.UpdateCompany(ctx, dbgen.UpdateCompanyParams{
ID: id,
Name: company.Name,
AdminID: company.AdminID,
})
func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
dbCompany, err := s.queries.UpdateCompany(ctx, convertUpdateCompany(company))
if err != nil {
return domain.Company{}, err

View File

@ -32,6 +32,14 @@ func convertDBTransaction(transaction dbgen.Transaction) domain.Transaction {
CreatedAt: transaction.CreatedAt.Time,
UpdatedAt: transaction.UpdatedAt.Time,
Verified: transaction.Verified,
BranchName: transaction.BranchName,
BranchLocation: transaction.BranchLocation,
CashierName: transaction.CashierName,
CompanyID: transaction.CompanyID,
ApproverName: domain.ValidString{
Value: transaction.ApproverName.String,
Valid: transaction.ApprovedBy.Valid,
},
}
}
@ -51,6 +59,10 @@ func convertCreateTransaction(transaction domain.CreateTransaction) dbgen.Create
AccountNumber: transaction.AccountNumber,
ReferenceNumber: transaction.ReferenceNumber,
NumberOfOutcomes: transaction.NumberOfOutcomes,
BranchName: transaction.BranchName,
BranchLocation: transaction.BranchLocation,
CashierName: transaction.CashierName,
CompanyID: transaction.CompanyID,
}
}
@ -99,7 +111,7 @@ func (s *Store) GetTransactionByBranch(ctx context.Context, id int64) ([]domain.
return result, nil
}
func (s *Store) UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64) error {
func (s *Store) UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error {
err := s.queries.UpdateTransactionVerified(ctx, dbgen.UpdateTransactionVerifiedParams{
ID: id,
ApprovedBy: pgtype.Int8{
@ -107,6 +119,10 @@ func (s *Store) UpdateTransactionVerified(ctx context.Context, id int64, verifie
Valid: true,
},
Verified: verified,
ApproverName: pgtype.Text{
String: approverName,
Valid: true,
},
})
return err
}

View File

@ -216,6 +216,20 @@ func (s *Store) UpdateUser(ctx context.Context, user domain.UpdateUserReq) error
}
return nil
}
func (s *Store) UpdateUserCompany(ctx context.Context, id int64, companyID int64) error {
err := s.queries.UpdateUserCompany(ctx, dbgen.UpdateUserCompanyParams{
CompanyID: pgtype.Int8{
Int64: companyID,
Valid: true,
},
ID: id,
})
if err != nil {
return err
}
return nil
}
func (s *Store) DeleteUser(ctx context.Context, id int64) error {
err := s.queries.DeleteUser(ctx, id)
if err != nil {

View File

@ -13,7 +13,7 @@ type BranchStore interface {
GetBranchByCompanyID(ctx context.Context, companyID int64) ([]domain.BranchDetail, error)
GetAllBranches(ctx context.Context) ([]domain.BranchDetail, error)
SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error)
UpdateBranch(ctx context.Context, id int64, branch domain.UpdateBranch) (domain.Branch, error)
UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error)
DeleteBranch(ctx context.Context, id int64) error
CreateBranchOperation(ctx context.Context, branchOperation domain.CreateBranchOperation) error
CreateSupportedOperation(ctx context.Context, supportedOperation domain.CreateSupportedOperation) (domain.SupportedOperation, error)

View File

@ -57,8 +57,8 @@ func (s *Service) GetAllSupportedOperations(ctx context.Context) ([]domain.Suppo
func (s *Service) SearchBranchByName(ctx context.Context, name string) ([]domain.BranchDetail, error) {
return s.branchStore.SearchBranchByName(ctx, name)
}
func (s *Service) UpdateBranch(ctx context.Context, id int64, branch domain.UpdateBranch) (domain.Branch, error) {
return s.branchStore.UpdateBranch(ctx, id, branch)
func (s *Service) UpdateBranch(ctx context.Context, branch domain.UpdateBranch) (domain.Branch, error) {
return s.branchStore.UpdateBranch(ctx, branch)
}
func (s *Service) DeleteBranch(ctx context.Context, id int64) error {
return s.branchStore.DeleteBranch(ctx, id)

View File

@ -11,6 +11,6 @@ type CompanyStore interface {
GetAllCompanies(ctx context.Context) ([]domain.GetCompany, error)
SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error)
GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error)
UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error)
UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error)
DeleteCompany(ctx context.Context, id int64) error
}

View File

@ -31,8 +31,8 @@ func (s *Service) SearchCompanyByName(ctx context.Context, name string) ([]domai
return s.companyStore.SearchCompanyByName(ctx, name)
}
func (s *Service) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
return s.companyStore.UpdateCompany(ctx, id, company)
func (s *Service) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) {
return s.companyStore.UpdateCompany(ctx, company)
}
func (s *Service) DeleteCompany(ctx context.Context, id int64) error {
return s.companyStore.DeleteCompany(ctx, id)

View File

@ -99,11 +99,12 @@ func (s *service) FetchLiveEvents(ctx context.Context) error {
func (s *service) FetchUpcomingEvents(ctx context.Context) error {
sportIDs := []int{1}
for _, sportID := range sportIDs {
var totalPages int = 1
var page int = 0
var limit int = 100
var count int = 0
for _, sportID := range sportIDs {
for page != totalPages {
time.Sleep(3 * time.Second) //This will restrict the fetching to 1200 requests per hour

View File

@ -11,5 +11,5 @@ type TransactionStore interface {
GetTransactionByID(ctx context.Context, id int64) (domain.Transaction, error)
GetAllTransactions(ctx context.Context) ([]domain.Transaction, error)
GetTransactionByBranch(ctx context.Context, id int64) ([]domain.Transaction, error)
UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64) error
UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error
}

View File

@ -28,6 +28,6 @@ func (s *Service) GetAllTransactions(ctx context.Context) ([]domain.Transaction,
func (s *Service) GetTransactionByBranch(ctx context.Context, id int64) ([]domain.Transaction, error) {
return s.transactionStore.GetTransactionByBranch(ctx, id)
}
func (s *Service) UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64) error {
return s.transactionStore.UpdateTransactionVerified(ctx, id, verified, approvedBy)
func (s *Service) UpdateTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, approverName string) error {
return s.transactionStore.UpdateTransactionVerified(ctx, id, verified, approvedBy, approverName)
}

View File

@ -14,6 +14,7 @@ type UserStore interface {
GetAllCashiers(ctx context.Context) ([]domain.User, error)
GetCashiersByBranch(ctx context.Context, branchID int64) ([]domain.User, error)
UpdateUser(ctx context.Context, user domain.UpdateUserReq) error
UpdateUserCompany(ctx context.Context, id int64, companyID int64) error
DeleteUser(ctx context.Context, id int64) error
CheckPhoneEmailExist(ctx context.Context, phoneNum, email string) (bool, bool, error)
GetUserByEmail(ctx context.Context, email string) (domain.User, error)

View File

@ -6,9 +6,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func (s *Service) SearchUserByNameOrPhone(ctx context.Context, searchString string) ([]domain.User, error) {
// Search user
return s.userStore.SearchUserByNameOrPhone(ctx, searchString)
@ -18,6 +15,12 @@ func (s *Service) UpdateUser(ctx context.Context, user domain.UpdateUserReq) err
// update user
return s.userStore.UpdateUser(ctx, user)
}
func (s *Service) UpdateUserCompany(ctx context.Context, id int64, companyID int64) error {
// update user
return s.userStore.UpdateUserCompany(ctx, id, companyID)
}
func (s *Service) GetUserByID(ctx context.Context, id int64) (domain.User, error) {
return s.userStore.GetUserByID(ctx, id)

View File

@ -1,6 +1,7 @@
package handlers
import (
"log/slog"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
@ -51,6 +52,11 @@ func (h *Handler) CreateAdmin(c *fiber.Ctx) error {
Valid: false,
}
} else {
_, err := h.companySvc.GetCompanyByID(c.Context(), *req.CompanyID)
if err != nil {
h.logger.Error("CreateAdmin company id is invalid", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Company ID is invalid", nil, nil)
}
companyID = domain.ValidInt64{
Value: *req.CompanyID,
Valid: true,
@ -66,11 +72,25 @@ func (h *Handler) CreateAdmin(c *fiber.Ctx) error {
Role: string(domain.RoleAdmin),
CompanyID: companyID,
}
_, err := h.userSvc.CreateUser(c.Context(), user, true)
h.logger.Info("CreateAdmin", slog.Bool("company id", req.CompanyID == nil))
newUser, err := h.userSvc.CreateUser(c.Context(), user, true)
if err != nil {
h.logger.Error("CreateAdmin failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create admin", nil, nil)
}
if req.CompanyID != nil {
_, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
ID: *req.CompanyID,
AdminID: &newUser.ID,
})
if err != nil {
h.logger.Error("CreateAdmin failed to update company", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update company", nil, nil)
}
}
return response.WriteJSON(c, fiber.StatusOK, "Admin created successfully", nil, nil)
}

View File

@ -9,12 +9,20 @@ import (
)
type CreateBranchReq struct {
Name string `json:"name" example:"4-kilo Branch"`
Location string `json:"location" example:"Addis Ababa"`
BranchManagerID int64 `json:"branch_manager_id" example:"1"`
CompanyID int64 `json:"company_id" example:"1"`
IsSelfOwned bool `json:"is_self_owned" example:"false"`
Operations []int64 `json:"operations"`
Name string `json:"name" validate:"required,min=3,max=100" example:"4-kilo Branch"`
Location string `json:"location" validate:"required,min=3,max=100" example:"Addis Ababa"`
BranchManagerID int64 `json:"branch_manager_id" validate:"required,gt=0" example:"1"`
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
IsSelfOwned *bool `json:"is_self_owned,omitempty" example:"false"`
Operations []int64 `json:"operations" validate:"required,dive,gt=0"`
}
type UpdateBranchReq struct {
Name *string `json:"name,omitempty" example:"4-kilo Branch"`
Location *string `json:"location,omitempty" example:"Addis Ababa"`
BranchManagerID *int64 `json:"branch_manager_id,omitempty" example:"1"`
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
IsSelfOwned *bool `json:"is_self_owned,omitempty" example:"false"`
}
type CreateSupportedOperationReq struct {
@ -106,6 +114,9 @@ func (h *Handler) CreateBranch(c *fiber.Ctx) error {
// return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
// }
role := c.Locals("role").(domain.Role)
companyID := c.Locals("company_id").(domain.ValidInt64)
var req CreateBranchReq
if err := c.BodyParser(&req); err != nil {
@ -117,6 +128,21 @@ func (h *Handler) CreateBranch(c *fiber.Ctx) error {
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
var IsSelfOwned bool
var checkedCompanyID int64
if role == domain.RoleSuperAdmin {
if req.IsSelfOwned == nil {
return response.WriteJSON(c, fiber.StatusBadRequest, "is_self_owned is required for super admin", nil, nil)
}
if req.CompanyID == nil {
return response.WriteJSON(c, fiber.StatusBadRequest, "company_id is required for super admin", nil, nil)
}
IsSelfOwned = *req.IsSelfOwned
checkedCompanyID = *req.CompanyID
} else {
IsSelfOwned = false
checkedCompanyID = companyID.Value //the company id is always valid when its not a super admin
}
// Create Branch Wallet
newWallet, err := h.walletSvc.CreateWallet(c.Context(), domain.CreateWallet{
@ -136,8 +162,8 @@ func (h *Handler) CreateBranch(c *fiber.Ctx) error {
Location: req.Location,
WalletID: newWallet.ID,
BranchManagerID: req.BranchManagerID,
CompanyID: req.CompanyID,
IsSelfOwned: req.IsSelfOwned,
CompanyID: checkedCompanyID,
IsSelfOwned: IsSelfOwned,
})
if err != nil {
@ -519,7 +545,7 @@ func (h *Handler) UpdateBranch(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid branch ID", err, nil)
}
var req CreateBranchReq
var req UpdateBranchReq
if err := c.BodyParser(&req); err != nil {
h.logger.Error("CreateBranchReq failed", "error", err)
@ -530,7 +556,8 @@ func (h *Handler) UpdateBranch(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
branch, err := h.branchSvc.UpdateBranch(c.Context(), id, domain.UpdateBranch{
branch, err := h.branchSvc.UpdateBranch(c.Context(), domain.UpdateBranch{
ID: id,
Name: req.Name,
Location: req.Location,
BranchManagerID: req.BranchManagerID,

View File

@ -12,6 +12,10 @@ type CreateCompanyReq struct {
Name string `json:"name" example:"CompanyName"`
AdminID int64 `json:"admin_id" example:"1"`
}
type UpdateCompanyReq struct {
Name *string `json:"name,omitempty" example:"CompanyName"`
AdminID *int64 `json:"admin_id,omitempty" example:"1"`
}
type CompanyRes struct {
ID int64 `json:"id" example:"1"`
@ -71,7 +75,14 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error {
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// Create Branch Wallet
user, err := h.userSvc.GetUserByID(c.Context(), req.AdminID)
if err != nil {
h.logger.Error("Error fetching user", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get user", err, nil)
}
// Create Company Wallet
newWallet, err := h.walletSvc.CreateWallet(c.Context(), domain.CreateWallet{
IsWithdraw: false,
IsBettable: true,
@ -86,7 +97,7 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error {
company, err := h.companySvc.CreateCompany(c.Context(), domain.CreateCompany{
Name: req.Name,
AdminID: req.AdminID,
AdminID: user.ID,
WalletID: newWallet.ID,
})
@ -97,6 +108,13 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error {
})
}
err = h.userSvc.UpdateUserCompany(c.Context(), user.ID, company.ID)
if err != nil {
h.logger.Error("CreateCompanyReq failed", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusCreated, "Company Created", res, nil)
@ -201,7 +219,7 @@ func (h *Handler) SearchCompany(c *fiber.Ctx) error {
// @Accept json
// @Produce json
// @Param id path int true "Company ID"
// @Param updateCompany body CreateCompanyReq true "Update Company"
// @Param updateCompany body UpdateCompanyReq true "Update Company"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
@ -215,7 +233,7 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company ID", err, nil)
}
var req CreateCompanyReq
var req UpdateCompanyReq
if err := c.BodyParser(&req); err != nil {
h.logger.Error("CreateCompanyReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
@ -225,7 +243,8 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
company, err := h.companySvc.UpdateCompany(c.Context(), id, domain.UpdateCompany{
company, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{
ID: id,
Name: req.Name,
AdminID: req.AdminID,
})

View File

@ -14,7 +14,11 @@ type TransactionRes 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"`
@ -28,6 +32,7 @@ type TransactionRes struct {
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"`
}
@ -53,7 +58,11 @@ func convertTransaction(transaction domain.Transaction) TransactionRes {
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,
@ -72,6 +81,8 @@ func convertTransaction(transaction domain.Transaction) TransactionRes {
if transaction.ApprovedBy.Valid {
newTransaction.ApprovedBy = &transaction.ApprovedBy.Value
newTransaction.ApproverName = &transaction.ApproverName.Value
}
return newTransaction
@ -114,6 +125,9 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
}
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("CreateTransactionReq Branch ID is required for this user role")
@ -126,7 +140,9 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
}
branchID = branch.ID
branchName = branch.Name
branchLocation = branch.Location
companyID = branch.CompanyID
} else {
branch, err := h.branchSvc.GetBranchByCashier(c.Context(), userID)
if err != nil {
@ -134,6 +150,9 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
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)
@ -152,6 +171,8 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "This bet has already been cashed out", err, nil)
}
user, err := h.userSvc.GetUserByID(c.Context(), userID)
transaction, err := h.transactionSvc.CreateTransaction(c.Context(), domain.CreateTransaction{
BranchID: branchID,
CashierID: userID,
@ -167,6 +188,10 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
AccountName: req.AccountName,
AccountNumber: req.AccountNumber,
ReferenceNumber: req.ReferenceNumber,
CashierName: user.FirstName + " " + user.LastName,
BranchName: branchName,
BranchLocation: branchLocation,
CompanyID: companyID,
})
if err != nil {
@ -289,7 +314,8 @@ type UpdateTransactionVerifiedReq struct {
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)
companyID := c.Locals("company_id").(domain.ValidInt64)
role := c.Locals("role").(domain.Role)
id, err := strconv.ParseInt(transactionID, 10, 64)
if err != nil {
@ -309,8 +335,20 @@ func (h *Handler) UpdateTransactionVerified(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// TODO: make it so that only people within the company can verify a transaction
err = h.transactionSvc.UpdateTransactionVerified(c.Context(), id, req.Verified, userID)
transaction, err := h.transactionSvc.GetTransactionByID(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.UpdateTransactionVerified(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")

View File

@ -41,6 +41,12 @@ func (a *App) authMiddleware(c *fiber.Ctx) error {
// refreshToken = c.Cookies("refresh_token", "")
// return fiber.NewError(fiber.StatusUnauthorized, "Refresh token missing")
}
// Asserting to make sure that there is no company role without a valid company id
if claim.Role != domain.RoleSuperAdmin && !claim.CompanyID.Valid {
fmt.Println("Company Role without Company ID")
return fiber.NewError(fiber.StatusInternalServerError, "Company Role without Company ID")
}
c.Locals("user_id", claim.UserId)
c.Locals("role", claim.Role)
@ -57,3 +63,11 @@ func (a *App) SuperAdminOnly(c *fiber.Ctx) error {
}
return c.Next()
}
func (a *App) CompanyOnly(c *fiber.Ctx) error {
userRole := c.Locals("role").(domain.Role)
if userRole == domain.RoleCustomer {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid access token")
}
return c.Next()
}