fix: added message to transfer and more filter routes

This commit is contained in:
Samuel Tariku 2025-06-29 18:00:23 +03:00
parent 56bcdeffaa
commit 10a49b4571
29 changed files with 453 additions and 126 deletions

View File

@ -119,15 +119,20 @@ CREATE TABLE IF NOT EXISTS banks (
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
acct_length INT NOT NULL, acct_length INT NOT NULL,
country_id INT NOT NULL, country_id INT NOT NULL,
is_mobilemoney INT, -- nullable integer (0 or 1) is_mobilemoney INT,
is_active INT NOT NULL, -- 0 or 1 -- nullable integer (0 or 1)
is_rtgs INT NOT NULL, -- 0 or 1 is_active INT NOT NULL,
active INT NOT NULL, -- 0 or 1 -- 0 or 1
is_24hrs INT, -- nullable integer (0 or 1) is_rtgs INT NOT NULL,
-- 0 or 1
active INT NOT NULL,
-- 0 or 1
is_24hrs INT,
-- nullable integer (0 or 1)
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
currency VARCHAR(10) NOT NULL, currency VARCHAR(10) NOT NULL,
bank_logo TEXT -- URL or base64 string bank_logo TEXT -- URL or base64 string
); );
CREATE TABLE IF NOT EXISTS wallets ( CREATE TABLE IF NOT EXISTS wallets (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
@ -151,6 +156,7 @@ CREATE TABLE IF NOT EXISTS customer_wallets (
CREATE TABLE IF NOT EXISTS wallet_transfer ( CREATE TABLE IF NOT EXISTS wallet_transfer (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
amount BIGINT, amount BIGINT,
message VARCHAR(255) NOT NULL,
type VARCHAR(255), type VARCHAR(255),
receiver_wallet_id BIGINT, receiver_wallet_id BIGINT,
sender_wallet_id BIGINT, sender_wallet_id BIGINT,

View File

@ -12,7 +12,20 @@ SELECT users.*,
branches.location As branch_location branches.location As branch_location
FROM branch_cashiers FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id JOIN users ON branch_cashiers.user_id = users.id
JOIN branches ON branches.id = branch_id; JOIN branches ON branches.id = branch_id
WHERE (
full_name ILIKE '%' || sqlc.narg('query') || '%'
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
OR sqlc.narg('query') IS NULL
)
AND (
users.created_at > sqlc.narg('created_before')
OR sqlc.narg('created_before') IS NULL
)
AND (
users.created_at < sqlc.narg('created_after')
OR sqlc.narg('created_after') IS NULL
);
-- name: GetCashierByID :one -- name: GetCashierByID :one
SELECT users.*, SELECT users.*,
branch_id, branch_id,

View File

@ -54,6 +54,19 @@ wHERE (
AND ( AND (
cashier_id = sqlc.narg('cashier_id') cashier_id = sqlc.narg('cashier_id')
OR sqlc.narg('cashier_id') IS NULL 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: GetTransactionByID :one -- name: GetTransactionByID :one
SELECT * SELECT *

View File

@ -1,6 +1,7 @@
-- name: CreateTransfer :one -- name: CreateTransfer :one
INSERT INTO wallet_transfer ( INSERT INTO wallet_transfer (
amount, amount,
message,
type, type,
receiver_wallet_id, receiver_wallet_id,
sender_wallet_id, sender_wallet_id,
@ -10,7 +11,7 @@ INSERT INTO wallet_transfer (
status, status,
payment_method payment_method
) )
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING *; RETURNING *;
-- name: GetAllTransfers :many -- name: GetAllTransfers :many
SELECT * SELECT *
@ -33,18 +34,15 @@ UPDATE wallet_transfer
SET verified = $1, SET verified = $1,
updated_at = CURRENT_TIMESTAMP updated_at = CURRENT_TIMESTAMP
WHERE id = $2; WHERE id = $2;
-- name: UpdateTransferStatus :exec -- name: UpdateTransferStatus :exec
UPDATE wallet_transfer UPDATE wallet_transfer
SET status = $1, SET status = $1,
updated_at = CURRENT_TIMESTAMP updated_at = CURRENT_TIMESTAMP
WHERE id = $2; WHERE id = $2;
-- name: GetWalletTransactionsInRange :many -- name: GetWalletTransactionsInRange :many
SELECT type, COUNT(*) as count, SUM(amount) as total_amount SELECT type,
COUNT(*) as count,
SUM(amount) as total_amount
FROM wallet_transfer FROM wallet_transfer
WHERE created_at BETWEEN $1 AND $2 WHERE created_at BETWEEN $1 AND $2
GROUP BY type; GROUP BY type;

View File

@ -1,22 +1,32 @@
-- name: CreateUser :one -- name: CreateUser :one
INSERT INTO users ( INSERT INTO users (
first_name, first_name,
last_name, last_name,
email, email,
phone_number, phone_number,
role, role,
password, password,
email_verified, email_verified,
phone_verified, phone_verified,
created_at, created_at,
updated_at, updated_at,
suspended, suspended,
company_id company_id
) )
VALUES ( VALUES (
$1, $2, $3, $4, $5, $6, $1,
$7, $8, $9, $10, $11, $12 $2,
) $3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12
)
RETURNING id, RETURNING id,
first_name, first_name,
last_name, last_name,
@ -29,7 +39,6 @@ RETURNING id,
updated_at, updated_at,
suspended, suspended,
company_id; company_id;
-- name: GetUserByID :one -- name: GetUserByID :one
SELECT * SELECT *
FROM users FROM users
@ -57,6 +66,19 @@ wHERE (
company_id = $2 company_id = $2
OR $2 IS NULL OR $2 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
)
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
-- name: GetTotalUsers :one -- name: GetTotalUsers :one
SELECT COUNT(*) SELECT COUNT(*)

View File

@ -20,8 +20,27 @@ SELECT users.id, users.first_name, users.last_name, users.email, users.phone_num
FROM branch_cashiers FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id JOIN users ON branch_cashiers.user_id = users.id
JOIN branches ON branches.id = branch_id JOIN branches ON branches.id = branch_id
WHERE (
full_name ILIKE '%' || $1 || '%'
OR phone_number ILIKE '%' || $1 || '%'
OR $1 IS NULL
)
AND (
users.created_at > $2
OR $2 IS NULL
)
AND (
users.created_at < $3
OR $3 IS NULL
)
` `
type GetAllCashiersParams struct {
Query pgtype.Text `json:"query"`
CreatedBefore pgtype.Timestamptz `json:"created_before"`
CreatedAfter pgtype.Timestamptz `json:"created_after"`
}
type GetAllCashiersRow struct { type GetAllCashiersRow struct {
ID int64 `json:"id"` ID int64 `json:"id"`
FirstName string `json:"first_name"` FirstName string `json:"first_name"`
@ -45,8 +64,8 @@ type GetAllCashiersRow struct {
BranchLocation string `json:"branch_location"` BranchLocation string `json:"branch_location"`
} }
func (q *Queries) GetAllCashiers(ctx context.Context) ([]GetAllCashiersRow, error) { func (q *Queries) GetAllCashiers(ctx context.Context, arg GetAllCashiersParams) ([]GetAllCashiersRow, error) {
rows, err := q.db.Query(ctx, GetAllCashiers) rows, err := q.db.Query(ctx, GetAllCashiers, arg.Query, arg.CreatedBefore, arg.CreatedAfter)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -580,6 +580,7 @@ type WalletThresholdNotification struct {
type WalletTransfer struct { type WalletTransfer struct {
ID int64 `json:"id"` ID int64 `json:"id"`
Amount pgtype.Int8 `json:"amount"` Amount pgtype.Int8 `json:"amount"`
Message string `json:"message"`
Type pgtype.Text `json:"type"` Type pgtype.Text `json:"type"`
ReceiverWalletID pgtype.Int8 `json:"receiver_wallet_id"` ReceiverWalletID pgtype.Int8 `json:"receiver_wallet_id"`
SenderWalletID pgtype.Int8 `json:"sender_wallet_id"` SenderWalletID pgtype.Int8 `json:"sender_wallet_id"`

View File

@ -142,16 +142,39 @@ wHERE (
cashier_id = $3 cashier_id = $3
OR $3 IS NULL 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 GetAllTransactionsParams struct { type GetAllTransactionsParams struct {
BranchID pgtype.Int8 `json:"branch_id"` BranchID pgtype.Int8 `json:"branch_id"`
CompanyID pgtype.Int8 `json:"company_id"` CompanyID pgtype.Int8 `json:"company_id"`
CashierID pgtype.Int8 `json:"cashier_id"` CashierID pgtype.Int8 `json:"cashier_id"`
Query pgtype.Text `json:"query"`
CreatedBefore pgtype.Timestamp `json:"created_before"`
CreatedAfter pgtype.Timestamp `json:"created_after"`
} }
func (q *Queries) GetAllTransactions(ctx context.Context, arg GetAllTransactionsParams) ([]Transaction, error) { func (q *Queries) GetAllTransactions(ctx context.Context, arg GetAllTransactionsParams) ([]Transaction, error) {
rows, err := q.db.Query(ctx, GetAllTransactions, arg.BranchID, arg.CompanyID, arg.CashierID) rows, err := q.db.Query(ctx, GetAllTransactions,
arg.BranchID,
arg.CompanyID,
arg.CashierID,
arg.Query,
arg.CreatedBefore,
arg.CreatedAfter,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -14,6 +14,7 @@ import (
const CreateTransfer = `-- name: CreateTransfer :one const CreateTransfer = `-- name: CreateTransfer :one
INSERT INTO wallet_transfer ( INSERT INTO wallet_transfer (
amount, amount,
message,
type, type,
receiver_wallet_id, receiver_wallet_id,
sender_wallet_id, sender_wallet_id,
@ -23,12 +24,13 @@ INSERT INTO wallet_transfer (
status, status,
payment_method payment_method
) )
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at RETURNING id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at
` `
type CreateTransferParams struct { type CreateTransferParams struct {
Amount pgtype.Int8 `json:"amount"` Amount pgtype.Int8 `json:"amount"`
Message string `json:"message"`
Type pgtype.Text `json:"type"` Type pgtype.Text `json:"type"`
ReceiverWalletID pgtype.Int8 `json:"receiver_wallet_id"` ReceiverWalletID pgtype.Int8 `json:"receiver_wallet_id"`
SenderWalletID pgtype.Int8 `json:"sender_wallet_id"` SenderWalletID pgtype.Int8 `json:"sender_wallet_id"`
@ -42,6 +44,7 @@ type CreateTransferParams struct {
func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams) (WalletTransfer, error) { func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams) (WalletTransfer, error) {
row := q.db.QueryRow(ctx, CreateTransfer, row := q.db.QueryRow(ctx, CreateTransfer,
arg.Amount, arg.Amount,
arg.Message,
arg.Type, arg.Type,
arg.ReceiverWalletID, arg.ReceiverWalletID,
arg.SenderWalletID, arg.SenderWalletID,
@ -55,6 +58,7 @@ func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams)
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.Message,
&i.Type, &i.Type,
&i.ReceiverWalletID, &i.ReceiverWalletID,
&i.SenderWalletID, &i.SenderWalletID,
@ -70,7 +74,7 @@ func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams)
} }
const GetAllTransfers = `-- name: GetAllTransfers :many const GetAllTransfers = `-- name: GetAllTransfers :many
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at
FROM wallet_transfer FROM wallet_transfer
` `
@ -86,6 +90,7 @@ func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error)
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.Message,
&i.Type, &i.Type,
&i.ReceiverWalletID, &i.ReceiverWalletID,
&i.SenderWalletID, &i.SenderWalletID,
@ -108,7 +113,7 @@ func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error)
} }
const GetTransferByID = `-- name: GetTransferByID :one const GetTransferByID = `-- name: GetTransferByID :one
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at
FROM wallet_transfer FROM wallet_transfer
WHERE id = $1 WHERE id = $1
` `
@ -119,6 +124,7 @@ func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.Message,
&i.Type, &i.Type,
&i.ReceiverWalletID, &i.ReceiverWalletID,
&i.SenderWalletID, &i.SenderWalletID,
@ -134,7 +140,7 @@ func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer
} }
const GetTransferByReference = `-- name: GetTransferByReference :one const GetTransferByReference = `-- name: GetTransferByReference :one
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at
FROM wallet_transfer FROM wallet_transfer
WHERE reference_number = $1 WHERE reference_number = $1
` `
@ -145,6 +151,7 @@ func (q *Queries) GetTransferByReference(ctx context.Context, referenceNumber st
err := row.Scan( err := row.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.Message,
&i.Type, &i.Type,
&i.ReceiverWalletID, &i.ReceiverWalletID,
&i.SenderWalletID, &i.SenderWalletID,
@ -160,7 +167,7 @@ func (q *Queries) GetTransferByReference(ctx context.Context, referenceNumber st
} }
const GetTransfersByWallet = `-- name: GetTransfersByWallet :many const GetTransfersByWallet = `-- name: GetTransfersByWallet :many
SELECT id, amount, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at
FROM wallet_transfer FROM wallet_transfer
WHERE receiver_wallet_id = $1 WHERE receiver_wallet_id = $1
OR sender_wallet_id = $1 OR sender_wallet_id = $1
@ -178,6 +185,7 @@ func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID pgt
if err := rows.Scan( if err := rows.Scan(
&i.ID, &i.ID,
&i.Amount, &i.Amount,
&i.Message,
&i.Type, &i.Type,
&i.ReceiverWalletID, &i.ReceiverWalletID,
&i.SenderWalletID, &i.SenderWalletID,
@ -200,7 +208,9 @@ func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID pgt
} }
const GetWalletTransactionsInRange = `-- name: GetWalletTransactionsInRange :many const GetWalletTransactionsInRange = `-- name: GetWalletTransactionsInRange :many
SELECT type, COUNT(*) as count, SUM(amount) as total_amount SELECT type,
COUNT(*) as count,
SUM(amount) as total_amount
FROM wallet_transfer FROM wallet_transfer
WHERE created_at BETWEEN $1 AND $2 WHERE created_at BETWEEN $1 AND $2
GROUP BY type GROUP BY type

View File

@ -45,23 +45,33 @@ func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailE
const CreateUser = `-- name: CreateUser :one const CreateUser = `-- name: CreateUser :one
INSERT INTO users ( INSERT INTO users (
first_name, first_name,
last_name, last_name,
email, email,
phone_number, phone_number,
role, role,
password, password,
email_verified, email_verified,
phone_verified, phone_verified,
created_at, created_at,
updated_at, updated_at,
suspended, suspended,
company_id company_id
) )
VALUES ( VALUES (
$1, $2, $3, $4, $5, $6, $1,
$7, $8, $9, $10, $11, $12 $2,
) $3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12
)
RETURNING id, RETURNING id,
first_name, first_name,
last_name, last_name,
@ -172,14 +182,30 @@ wHERE (
company_id = $2 company_id = $2
OR $2 IS NULL OR $2 IS NULL
) )
LIMIT $4 OFFSET $3 AND (
full_name ILIKE '%' || $3 || '%'
OR phone_number ILIKE '%' || $3 || '%'
OR $3 IS NULL
)
AND (
created_at > $4
OR $4 IS NULL
)
AND (
created_at < $5
OR $5 IS NULL
)
LIMIT $7 OFFSET $6
` `
type GetAllUsersParams struct { type GetAllUsersParams struct {
Role string `json:"role"` Role string `json:"role"`
CompanyID pgtype.Int8 `json:"company_id"` CompanyID pgtype.Int8 `json:"company_id"`
Offset pgtype.Int4 `json:"offset"` Query pgtype.Text `json:"query"`
Limit pgtype.Int4 `json:"limit"` CreatedBefore pgtype.Timestamptz `json:"created_before"`
CreatedAfter pgtype.Timestamptz `json:"created_after"`
Offset pgtype.Int4 `json:"offset"`
Limit pgtype.Int4 `json:"limit"`
} }
type GetAllUsersRow struct { type GetAllUsersRow struct {
@ -202,6 +228,9 @@ func (q *Queries) GetAllUsers(ctx context.Context, arg GetAllUsersParams) ([]Get
rows, err := q.db.Query(ctx, GetAllUsers, rows, err := q.db.Query(ctx, GetAllUsers,
arg.Role, arg.Role,
arg.CompanyID, arg.CompanyID,
arg.Query,
arg.CreatedBefore,
arg.CreatedAfter,
arg.Offset, arg.Offset,
arg.Limit, arg.Limit,
) )

View File

@ -49,9 +49,12 @@ type Transaction struct {
} }
type TransactionFilter struct { type TransactionFilter struct {
CompanyID ValidInt64 CompanyID ValidInt64
BranchID ValidInt64 BranchID ValidInt64
CashierID ValidInt64 CashierID ValidInt64
Query ValidString
CreatedBefore ValidTime
CreatedAfter ValidTime
} }
type CreateTransaction struct { type CreateTransaction struct {
Amount Currency Amount Currency
@ -63,13 +66,13 @@ type CreateTransaction struct {
PaymentOption PaymentOption PaymentOption PaymentOption
FullName string FullName string
PhoneNumber string PhoneNumber string
BankCode string BankCode string
BeneficiaryName string BeneficiaryName string
AccountName string AccountName string
AccountNumber string AccountNumber string
ReferenceNumber string ReferenceNumber string
BranchName string BranchName string
BranchLocation string BranchLocation string
CompanyID int64 CompanyID int64
CashierName string CashierName string
} }

View File

@ -36,6 +36,7 @@ type Transfer struct {
ID int64 `json:"id"` ID int64 `json:"id"`
Amount Currency `json:"amount"` Amount Currency `json:"amount"`
Verified bool `json:"verified"` Verified bool `json:"verified"`
Message string `json:"message"`
Type TransferType `json:"type"` Type TransferType `json:"type"`
PaymentMethod PaymentMethod `json:"payment_method"` PaymentMethod PaymentMethod `json:"payment_method"`
ReceiverWalletID ValidInt64 `json:"receiver_wallet_id"` ReceiverWalletID ValidInt64 `json:"receiver_wallet_id"`
@ -50,6 +51,7 @@ type Transfer struct {
type CreateTransfer struct { type CreateTransfer struct {
Amount Currency `json:"amount"` Amount Currency `json:"amount"`
Verified bool `json:"verified"` Verified bool `json:"verified"`
Message string `json:"message"`
Type TransferType `json:"type"` Type TransferType `json:"type"`
PaymentMethod PaymentMethod `json:"payment_method"` PaymentMethod PaymentMethod `json:"payment_method"`
ReceiverWalletID ValidInt64 `json:"receiver_wallet_id"` ReceiverWalletID ValidInt64 `json:"receiver_wallet_id"`

View File

@ -30,6 +30,20 @@ type User struct {
CompanyID ValidInt64 CompanyID ValidInt64
} }
type UserFilter struct {
Role string
CompanyID ValidInt64
Page ValidInt
PageSize ValidInt
Query ValidString
CreatedBefore ValidTime
CreatedAfter ValidTime
}
type ValidRole struct {
Value Role
Valid bool
}
type RegisterUserReq struct { type RegisterUserReq struct {
FirstName string FirstName string
LastName string LastName string

View File

@ -99,6 +99,18 @@ func (s *Store) GetAllTransactions(ctx context.Context, filter domain.Transactio
Int64: filter.CashierID.Value, Int64: filter.CashierID.Value,
Valid: filter.CashierID.Valid, Valid: filter.CashierID.Valid,
}, },
Query: pgtype.Text{
String: filter.Query.Value,
Valid: filter.Query.Valid,
},
CreatedBefore: pgtype.Timestamp{
Time: filter.CreatedBefore.Value,
Valid: filter.CreatedBefore.Valid,
},
CreatedAfter: pgtype.Timestamp{
Time: filter.CreatedAfter.Value,
Valid: filter.CreatedAfter.Valid,
},
}) })
if err != nil { if err != nil {

View File

@ -36,8 +36,9 @@ func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
func convertCreateTransfer(transfer domain.CreateTransfer) dbgen.CreateTransferParams { func convertCreateTransfer(transfer domain.CreateTransfer) dbgen.CreateTransferParams {
return dbgen.CreateTransferParams{ return dbgen.CreateTransferParams{
Amount: pgtype.Int8{Int64: int64(transfer.Amount), Valid: true}, Message: transfer.Message,
Type: pgtype.Text{String: string(transfer.Type), Valid: true}, Amount: pgtype.Int8{Int64: int64(transfer.Amount), Valid: true},
Type: pgtype.Text{String: string(transfer.Type), Valid: true},
ReceiverWalletID: pgtype.Int8{ ReceiverWalletID: pgtype.Int8{
Int64: transfer.ReceiverWalletID.Value, Int64: transfer.ReceiverWalletID.Value,
Valid: transfer.ReceiverWalletID.Valid, Valid: transfer.ReceiverWalletID.Valid,

View File

@ -9,7 +9,6 @@ import (
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
) )
@ -88,7 +87,7 @@ func (s *Store) GetUserByID(ctx context.Context, id int64) (domain.User, error)
}, },
}, nil }, nil
} }
func (s *Store) GetAllUsers(ctx context.Context, filter user.Filter) ([]domain.User, int64, error) { func (s *Store) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error) {
users, err := s.queries.GetAllUsers(ctx, dbgen.GetAllUsersParams{ users, err := s.queries.GetAllUsers(ctx, dbgen.GetAllUsersParams{
Role: filter.Role, Role: filter.Role,
CompanyID: pgtype.Int8{ CompanyID: pgtype.Int8{
@ -103,6 +102,18 @@ func (s *Store) GetAllUsers(ctx context.Context, filter user.Filter) ([]domain.U
Int32: int32(filter.Page.Value), Int32: int32(filter.Page.Value),
Valid: filter.Page.Valid, Valid: filter.Page.Valid,
}, },
Query: pgtype.Text{
String: filter.Query.Value,
Valid: filter.Query.Valid,
},
CreatedBefore: pgtype.Timestamptz{
Time: filter.CreatedBefore.Value,
Valid: filter.CreatedBefore.Valid,
},
CreatedAfter: pgtype.Timestamptz{
Time: filter.CreatedAfter.Value,
Valid: filter.CreatedAfter.Valid,
},
}) })
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err

View File

@ -275,7 +275,8 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
branch.WalletID, domain.ToCurrency(deductedAmount), domain.BranchWalletType, domain.ValidInt64{ branch.WalletID, domain.ToCurrency(deductedAmount), domain.BranchWalletType, domain.ValidInt64{
Value: userID, Value: userID,
Valid: true, Valid: true,
}, domain.TRANSFER_DIRECT) }, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", deductedAmount))
if err != nil { if err != nil {
s.mongoLogger.Error("failed to deduct from wallet", s.mongoLogger.Error("failed to deduct from wallet",
zap.Int64("wallet_id", branch.WalletID), zap.Int64("wallet_id", branch.WalletID),
@ -311,7 +312,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
_, err = s.walletSvc.DeductFromWallet(ctx, branch.WalletID, domain.ToCurrency(deductedAmount), domain.BranchWalletType, domain.ValidInt64{ _, err = s.walletSvc.DeductFromWallet(ctx, branch.WalletID, domain.ToCurrency(deductedAmount), domain.BranchWalletType, domain.ValidInt64{
Value: userID, Value: userID,
Valid: true, Valid: true,
}, domain.TRANSFER_DIRECT) }, domain.TRANSFER_DIRECT, fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", deductedAmount))
if err != nil { if err != nil {
s.mongoLogger.Error("wallet deduction failed", s.mongoLogger.Error("wallet deduction failed",
zap.Int64("wallet_id", branch.WalletID), zap.Int64("wallet_id", branch.WalletID),
@ -337,7 +338,8 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
} }
if req.Amount < wallets.RegularBalance.Float32() { if req.Amount < wallets.RegularBalance.Float32() {
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID, _, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID,
domain.ToCurrency(req.Amount), domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT) domain.ToCurrency(req.Amount), domain.CustomerWalletType, domain.ValidInt64{},
domain.TRANSFER_DIRECT, fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", req.Amount))
if err != nil { if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer regular wallet", s.mongoLogger.Error("wallet deduction failed for customer regular wallet",
zap.Int64("customer_id", wallets.CustomerID), zap.Int64("customer_id", wallets.CustomerID),
@ -355,7 +357,8 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
} }
// Empty the regular balance // Empty the regular balance
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID, _, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID,
wallets.RegularBalance, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT) wallets.RegularBalance, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", wallets.RegularBalance.Float32()))
if err != nil { if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer regular wallet", s.mongoLogger.Error("wallet deduction failed for customer regular wallet",
zap.Int64("customer_id", wallets.CustomerID), zap.Int64("customer_id", wallets.CustomerID),
@ -369,7 +372,8 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
// Empty remaining from static balance // Empty remaining from static balance
remainingAmount := wallets.RegularBalance - domain.Currency(req.Amount) remainingAmount := wallets.RegularBalance - domain.Currency(req.Amount)
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.StaticID, _, err = s.walletSvc.DeductFromWallet(ctx, wallets.StaticID,
remainingAmount, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT) remainingAmount, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", remainingAmount.Float32()))
if err != nil { if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer static wallet", s.mongoLogger.Error("wallet deduction failed for customer static wallet",
zap.Int64("customer_id", wallets.CustomerID), zap.Int64("customer_id", wallets.CustomerID),
@ -754,7 +758,8 @@ func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.Outc
amount = bet.Amount amount = bet.Amount
} }
_, err = s.walletSvc.AddToWallet(ctx, customerWallet.RegularID, amount, domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}) _, err = s.walletSvc.AddToWallet(ctx, customerWallet.RegularID, amount, domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{}, fmt.Sprintf("Added %d to wallet by system for winning a bet", amount.Float32()))
if err != nil { if err != nil {
s.mongoLogger.Error("failed to add winnings to wallet", s.mongoLogger.Error("failed to add winnings to wallet",

View File

@ -83,6 +83,7 @@ func (s *Service) InitiateDeposit(ctx context.Context, userID int64, amount doma
// Create payment record // Create payment record
transfer := domain.CreateTransfer{ transfer := domain.CreateTransfer{
Message: fmt.Sprintf("Depositing %d into wallet using chapa. Reference Number %s", amount, reference),
Amount: amount, Amount: amount,
Type: domain.DEPOSIT, Type: domain.DEPOSIT,
PaymentMethod: domain.TRANSFER_CHAPA, PaymentMethod: domain.TRANSFER_CHAPA,
@ -167,8 +168,9 @@ func (s *Service) InitiateWithdrawal(ctx context.Context, userID int64, req doma
reference := uuid.New().String() reference := uuid.New().String()
createTransfer := domain.CreateTransfer{ createTransfer := domain.CreateTransfer{
Amount: domain.Currency(amount), Message: fmt.Sprintf("Withdrawing %d into wallet using chapa. Reference Number %s", amount, reference),
Type: domain.WITHDRAW, Amount: domain.Currency(amount),
Type: domain.WITHDRAW,
SenderWalletID: domain.ValidInt64{ SenderWalletID: domain.ValidInt64{
Value: withdrawWallet.ID, Value: withdrawWallet.ID,
Valid: true, Valid: true,
@ -265,7 +267,10 @@ func (s *Service) ManuallyVerify(ctx context.Context, txRef string) (*domain.Cha
} }
// Credit wallet // Credit wallet
if _, err := s.walletStore.AddToWallet(ctx, transfer.SenderWalletID.Value, transfer.Amount, domain.ValidInt64{}, domain.TRANSFER_CHAPA, domain.PaymentDetails{}); err != nil { _, err := s.walletStore.AddToWallet(ctx, transfer.SenderWalletID.Value,
transfer.Amount, domain.ValidInt64{}, domain.TRANSFER_CHAPA, domain.PaymentDetails{},
fmt.Sprintf("Added %d to wallet using Chapa", transfer.Amount.Float32()))
if err != nil {
return nil, fmt.Errorf("failed to credit wallet: %w", err) return nil, fmt.Errorf("failed to credit wallet: %w", err)
} }
} }
@ -325,7 +330,7 @@ func (s *Service) HandleVerifyDepositWebhook(ctx context.Context, transfer domai
ReferenceNumber: domain.ValidString{ ReferenceNumber: domain.ValidString{
Value: transfer.Reference, Value: transfer.Reference,
}, },
}); err != nil { }, fmt.Sprintf("Added %d to wallet using Chapa")); err != nil {
return fmt.Errorf("failed to credit user wallet: %w", err) return fmt.Errorf("failed to credit user wallet: %w", err)
} }
} }
@ -361,7 +366,10 @@ func (s *Service) HandleVerifyWithdrawWebhook(ctx context.Context, payment domai
return fmt.Errorf("failed to update payment status: %w", err) return fmt.Errorf("failed to update payment status: %w", err)
} // If payment is completed, credit user's walle } // If payment is completed, credit user's walle
} else { } else {
if _, err := s.walletStore.AddToWallet(ctx, transfer.SenderWalletID.Value, transfer.Amount, domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil { _, err := s.walletStore.AddToWallet(ctx, transfer.SenderWalletID.Value, transfer.Amount, domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %d to wallet by system because chapa withdraw is unsuccessful"))
if err != nil {
return fmt.Errorf("failed to credit user wallet: %w", err) return fmt.Errorf("failed to credit user wallet: %w", err)
} }
} }

View File

@ -43,22 +43,9 @@ func (s *Service) DeleteUser(ctx context.Context, id int64) error {
return s.userStore.DeleteUser(ctx, id) return s.userStore.DeleteUser(ctx, id)
} }
type Filter struct {
Role string
CompanyID domain.ValidInt64
Page domain.ValidInt
PageSize domain.ValidInt
}
type ValidRole struct {
Value domain.Role
Valid bool
}
type ValidBranchId struct {
Value int64
Valid bool
}
func (s *Service) GetAllUsers(ctx context.Context, filter Filter) ([]domain.User, int64, error) {
func (s *Service) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error) {
// Get all Users // Get all Users
return s.userStore.GetAllUsers(ctx, filter) return s.userStore.GetAllUsers(ctx, filter)
} }

View File

@ -206,8 +206,10 @@ func (s *service) ProcessBet(ctx context.Context, req *domain.PopOKBetRequest) (
if err != nil { if err != nil {
return &domain.PopOKBetResponse{}, fmt.Errorf("Failed to read user wallets") return &domain.PopOKBetResponse{}, fmt.Errorf("Failed to read user wallets")
} }
_, err = s.walletSvc.DeductFromWallet(ctx, claims.UserID, domain.Currency(amountCents),
if _, err := s.walletSvc.DeductFromWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT); err != nil { domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing virtual game bet", amountCents))
if err != nil {
return nil, fmt.Errorf("insufficient balance") return nil, fmt.Errorf("insufficient balance")
} }

View File

@ -42,7 +42,6 @@ func (s *Service) UpdateTransferStatus(ctx context.Context, id int64, status str
return s.transferStore.UpdateTransferStatus(ctx, id, status) return s.transferStore.UpdateTransferStatus(ctx, id, status)
} }
func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiverID int64, func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiverID int64,
amount domain.Currency, paymentMethod domain.PaymentMethod, amount domain.Currency, paymentMethod domain.PaymentMethod,
cashierID domain.ValidInt64) (domain.Transfer, error) { cashierID domain.ValidInt64) (domain.Transfer, error) {
@ -85,6 +84,7 @@ func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiver
// Log the transfer so that if there is a mistake, it can be reverted // Log the transfer so that if there is a mistake, it can be reverted
transfer, err := s.CreateTransfer(ctx, domain.CreateTransfer{ transfer, err := s.CreateTransfer(ctx, domain.CreateTransfer{
Message: fmt.Sprintf("Transferring %d to another wallet", amount),
SenderWalletID: domain.ValidInt64{ SenderWalletID: domain.ValidInt64{
Value: senderID, Value: senderID,
Valid: true, Valid: true,
@ -119,7 +119,7 @@ func (s *Service) SendTransferNotification(ctx context.Context, senderWallet dom
DeliveryChannel: domain.DeliveryChannelInApp, DeliveryChannel: domain.DeliveryChannelInApp,
Payload: domain.NotificationPayload{ Payload: domain.NotificationPayload{
Headline: "Wallet has been deducted", Headline: "Wallet has been deducted",
Message: fmt.Sprintf(`%s %d has been transferred from your wallet`,senderWallet.Currency, amount), Message: fmt.Sprintf(`%s %d has been transferred from your wallet`, senderWallet.Currency, amount),
}, },
Priority: 2, Priority: 2,
Metadata: []byte(fmt.Sprintf(`{ Metadata: []byte(fmt.Sprintf(`{
@ -148,7 +148,7 @@ func (s *Service) SendTransferNotification(ctx context.Context, senderWallet dom
DeliveryChannel: domain.DeliveryChannelInApp, DeliveryChannel: domain.DeliveryChannelInApp,
Payload: domain.NotificationPayload{ Payload: domain.NotificationPayload{
Headline: "Wallet has been credited", Headline: "Wallet has been credited",
Message: fmt.Sprintf(`%s %d has been transferred to your wallet`,receiverWallet.Currency, amount), Message: fmt.Sprintf(`%s %d has been transferred to your wallet`, receiverWallet.Currency, amount),
}, },
Priority: 2, Priority: 2,
Metadata: []byte(fmt.Sprintf(`{ Metadata: []byte(fmt.Sprintf(`{

View File

@ -84,7 +84,7 @@ func (s *Service) UpdateBalance(ctx context.Context, id int64, balance domain.Cu
} }
func (s *Service) AddToWallet( func (s *Service) AddToWallet(
ctx context.Context, id int64, amount domain.Currency, cashierID domain.ValidInt64, paymentMethod domain.PaymentMethod, paymentDetails domain.PaymentDetails) (domain.Transfer, error) { ctx context.Context, id int64, amount domain.Currency, cashierID domain.ValidInt64, paymentMethod domain.PaymentMethod, paymentDetails domain.PaymentDetails, message string) (domain.Transfer, error) {
wallet, err := s.GetWalletByID(ctx, id) wallet, err := s.GetWalletByID(ctx, id)
if err != nil { if err != nil {
return domain.Transfer{}, err return domain.Transfer{}, err
@ -99,6 +99,7 @@ func (s *Service) AddToWallet(
// Log the transfer here for reference // Log the transfer here for reference
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{ newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
Message: message,
Amount: amount, Amount: amount,
Verified: true, Verified: true,
ReceiverWalletID: domain.ValidInt64{ ReceiverWalletID: domain.ValidInt64{
@ -114,7 +115,7 @@ func (s *Service) AddToWallet(
return newTransfer, err return newTransfer, err
} }
func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.Currency, walletType domain.WalletType, cashierID domain.ValidInt64, paymentMethod domain.PaymentMethod) (domain.Transfer, error) { func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.Currency, walletType domain.WalletType, cashierID domain.ValidInt64, paymentMethod domain.PaymentMethod, message string) (domain.Transfer, error) {
wallet, err := s.GetWalletByID(ctx, id) wallet, err := s.GetWalletByID(ctx, id)
if err != nil { if err != nil {
return domain.Transfer{}, err return domain.Transfer{}, err
@ -138,6 +139,7 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
// Log the transfer here for reference // Log the transfer here for reference
newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{ newTransfer, err := s.transferStore.CreateTransfer(ctx, domain.CreateTransfer{
Message: message,
Amount: amount, Amount: amount,
Verified: true, Verified: true,
SenderWalletID: domain.ValidInt64{ SenderWalletID: domain.ValidInt64{

View File

@ -66,7 +66,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
} }
for _, job := range schedule { for _, job := range schedule {
// job.task() job.task()
if _, err := c.AddFunc(job.spec, job.task); err != nil { if _, err := c.AddFunc(job.spec, job.task); err != nil {
log.Fatalf("Failed to schedule cron job: %v", err) log.Fatalf("Failed to schedule cron job: %v", err)
} }

View File

@ -6,7 +6,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"go.uber.org/zap" "go.uber.org/zap"
@ -155,7 +154,41 @@ type AdminRes struct {
// @Failure 500 {object} response.APIResponse // @Failure 500 {object} response.APIResponse
// @Router /admin [get] // @Router /admin [get]
func (h *Handler) GetAllAdmins(c *fiber.Ctx) error { func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
filter := user.Filter{
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,
}
}
filter := domain.UserFilter{
Role: string(domain.RoleAdmin), Role: string(domain.RoleAdmin),
CompanyID: domain.ValidInt64{ CompanyID: domain.ValidInt64{
Value: int64(c.QueryInt("company_id")), Value: int64(c.QueryInt("company_id")),
@ -169,6 +202,9 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error {
Value: c.QueryInt("page_size", 10), Value: c.QueryInt("page_size", 10),
Valid: true, Valid: true,
}, },
Query: searchString,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
} }
valErrs, ok := h.validator.Validate(c, filter) valErrs, ok := h.validator.Validate(c, filter)

View File

@ -124,7 +124,40 @@ func (h *Handler) GetAllCashiers(c *fiber.Ctx) error {
if role != domain.RoleSuperAdmin && !companyId.Valid { if role != domain.RoleSuperAdmin && !companyId.Valid {
return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID") return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID")
} }
filter := user.Filter{ 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,
}
}
filter := domain.UserFilter{
Role: string(domain.RoleCashier), Role: string(domain.RoleCashier),
CompanyID: companyId, CompanyID: companyId,
Page: domain.ValidInt{ Page: domain.ValidInt{
@ -135,6 +168,9 @@ func (h *Handler) GetAllCashiers(c *fiber.Ctx) error {
Value: c.QueryInt("page_size", 10), Value: c.QueryInt("page_size", 10),
Valid: true, Valid: true,
}, },
Query: searchString,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
} }
valErrs, ok := h.validator.Validate(c, filter) valErrs, ok := h.validator.Validate(c, filter)

View File

@ -111,12 +111,47 @@ type ManagersRes struct {
func (h *Handler) GetAllManagers(c *fiber.Ctx) error { func (h *Handler) GetAllManagers(c *fiber.Ctx) error {
role := c.Locals("role").(domain.Role) role := c.Locals("role").(domain.Role)
companyId := c.Locals("company_id").(domain.ValidInt64) companyId := c.Locals("company_id").(domain.ValidInt64)
// Checking to make sure that admin user has a company id in the token // Checking to make sure that admin user has a company id in the token
if role != domain.RoleSuperAdmin && !companyId.Valid { if role != domain.RoleSuperAdmin && !companyId.Valid {
return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID") return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID")
} }
filter := user.Filter{
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,
}
}
filter := domain.UserFilter{
Role: string(domain.RoleBranchManager), Role: string(domain.RoleBranchManager),
CompanyID: companyId, CompanyID: companyId,
Page: domain.ValidInt{ Page: domain.ValidInt{
@ -127,6 +162,9 @@ func (h *Handler) GetAllManagers(c *fiber.Ctx) error {
Value: c.QueryInt("page_size", 10), Value: c.QueryInt("page_size", 10),
Valid: true, Valid: true,
}, },
Query: searchString,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
} }
valErrs, ok := h.validator.Validate(c, filter) valErrs, ok := h.validator.Validate(c, filter)
if !ok { if !ok {

View File

@ -230,12 +230,47 @@ func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
companyID := c.Locals("company_id").(domain.ValidInt64) companyID := c.Locals("company_id").(domain.ValidInt64)
branchID := c.Locals("branch_id").(domain.ValidInt64) branchID := c.Locals("branch_id").(domain.ValidInt64)
var transactions []domain.Transaction 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 // Check user role and fetch transactions accordingly
transactions, err := h.transactionSvc.GetAllTransactions(c.Context(), domain.TransactionFilter{ transactions, err := h.transactionSvc.GetAllTransactions(c.Context(), domain.TransactionFilter{
CompanyID: companyID, CompanyID: companyID,
BranchID: branchID, BranchID: branchID,
Query: searchString,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
}) })
if err != nil { if err != nil {

View File

@ -233,7 +233,7 @@ func (h *Handler) RefillWallet(c *fiber.Ctx) error {
c.Context(), receiverID, domain.ToCurrency(req.Amount), domain.ValidInt64{ c.Context(), receiverID, domain.ToCurrency(req.Amount), domain.ValidInt64{
Value: userID, Value: userID,
Valid: true, Valid: true,
}, domain.TRANSFER_BANK, domain.PaymentDetails{}) }, domain.TRANSFER_BANK, domain.PaymentDetails{}, fmt.Sprintf("Added %d to wallet directly by super-admin", req.Amount))
if !ok { if !ok {
return response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil) return response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)

View File

@ -189,7 +189,8 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error {
// TODO: Remove later // TODO: Remove later
_, err = h.walletSvc.AddToWallet( _, err = h.walletSvc.AddToWallet(
c.Context(), newWallet.RegularID, domain.ToCurrency(100.0), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}) c.Context(), newWallet.RegularID, domain.ToCurrency(100.0), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
"Added 100.0 to wallet only as test for deployment")
if err != nil { if err != nil {
h.logger.Error("Failed to update wallet for user", "userID", newUser.ID, "error", err) h.logger.Error("Failed to update wallet for user", "userID", newUser.ID, "error", err)