fix: added message to wallet_transfers and gave it a detailed view

This commit is contained in:
Samuel Tariku 2025-06-29 21:51:23 +03:00
parent 74941bc535
commit 3e4e9eead7
28 changed files with 324 additions and 142 deletions

View File

@ -354,6 +354,13 @@ FROM customer_wallets cw
JOIN wallets rw ON cw.regular_wallet_id = rw.id
JOIN wallets sw ON cw.static_wallet_id = sw.id
JOIN users ON users.id = cw.customer_id;
CREATE VIEW wallet_transfer_details AS
SELECT wt.*,
users.first_name,
users.last_name,
users.phone_number
FROM wallet_transfer wt
LEFT JOIN users ON users.id = wt.cashier_id;
-- Foreign Keys
ALTER TABLE users
ADD CONSTRAINT unique_email UNIQUE (email),

View File

@ -14,7 +14,8 @@ FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id
JOIN branches ON branches.id = branch_id
WHERE (
full_name ILIKE '%' || sqlc.narg('query') || '%'
first_name ILIKE '%' || sqlc.narg('query') || '%'
OR last_name ILIKE '%' || sqlc.narg('query') || '%'
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
OR sqlc.narg('query') IS NULL
)

View File

@ -15,19 +15,19 @@ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING *;
-- name: GetAllTransfers :many
SELECT *
FROM wallet_transfer;
FROM wallet_transfer_details;
-- name: GetTransfersByWallet :many
SELECT *
FROM wallet_transfer
FROM wallet_transfer_details
WHERE receiver_wallet_id = $1
OR sender_wallet_id = $1;
-- name: GetTransferByID :one
SELECT *
FROM wallet_transfer
FROM wallet_transfer_details
WHERE id = $1;
-- name: GetTransferByReference :one
SELECT *
FROM wallet_transfer
FROM wallet_transfer_details
WHERE reference_number = $1;
-- name: UpdateTransferVerification :exec
UPDATE wallet_transfer

View File

@ -67,7 +67,8 @@ wHERE (
OR $2 IS NULL
)
AND (
full_name ILIKE '%' || sqlc.narg('query') || '%'
first_name ILIKE '%' || sqlc.narg('query') || '%'
OR last_name ILIKE '%' || sqlc.narg('query') || '%'
OR phone_number ILIKE '%' || sqlc.narg('query') || '%'
OR sqlc.narg('query') IS NULL
)

View File

@ -21,7 +21,8 @@ FROM branch_cashiers
JOIN users ON branch_cashiers.user_id = users.id
JOIN branches ON branches.id = branch_id
WHERE (
full_name ILIKE '%' || $1 || '%'
first_name ILIKE '%' || $1 || '%'
OR last_name ILIKE '%' || $1 || '%'
OR phone_number ILIKE '%' || $1 || '%'
OR $1 IS NULL
)

View File

@ -597,3 +597,22 @@ type WalletTransfer struct {
CreatedAt pgtype.Timestamp `json:"created_at"`
UpdatedAt pgtype.Timestamp `json:"updated_at"`
}
type WalletTransferDetail struct {
ID int64 `json:"id"`
Amount pgtype.Int8 `json:"amount"`
Message string `json:"message"`
Type pgtype.Text `json:"type"`
ReceiverWalletID pgtype.Int8 `json:"receiver_wallet_id"`
SenderWalletID pgtype.Int8 `json:"sender_wallet_id"`
CashierID pgtype.Int8 `json:"cashier_id"`
Verified pgtype.Bool `json:"verified"`
ReferenceNumber string `json:"reference_number"`
Status pgtype.Text `json:"status"`
PaymentMethod pgtype.Text `json:"payment_method"`
CreatedAt pgtype.Timestamp `json:"created_at"`
UpdatedAt pgtype.Timestamp `json:"updated_at"`
FirstName pgtype.Text `json:"first_name"`
LastName pgtype.Text `json:"last_name"`
PhoneNumber pgtype.Text `json:"phone_number"`
}

View File

@ -74,19 +74,19 @@ func (q *Queries) CreateTransfer(ctx context.Context, arg CreateTransferParams)
}
const GetAllTransfers = `-- name: GetAllTransfers :many
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
SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at, first_name, last_name, phone_number
FROM wallet_transfer_details
`
func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error) {
func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransferDetail, error) {
rows, err := q.db.Query(ctx, GetAllTransfers)
if err != nil {
return nil, err
}
defer rows.Close()
var items []WalletTransfer
var items []WalletTransferDetail
for rows.Next() {
var i WalletTransfer
var i WalletTransferDetail
if err := rows.Scan(
&i.ID,
&i.Amount,
@ -101,6 +101,9 @@ func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error)
&i.PaymentMethod,
&i.CreatedAt,
&i.UpdatedAt,
&i.FirstName,
&i.LastName,
&i.PhoneNumber,
); err != nil {
return nil, err
}
@ -113,14 +116,14 @@ func (q *Queries) GetAllTransfers(ctx context.Context) ([]WalletTransfer, error)
}
const GetTransferByID = `-- name: GetTransferByID :one
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
SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at, first_name, last_name, phone_number
FROM wallet_transfer_details
WHERE id = $1
`
func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer, error) {
func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransferDetail, error) {
row := q.db.QueryRow(ctx, GetTransferByID, id)
var i WalletTransfer
var i WalletTransferDetail
err := row.Scan(
&i.ID,
&i.Amount,
@ -135,19 +138,22 @@ func (q *Queries) GetTransferByID(ctx context.Context, id int64) (WalletTransfer
&i.PaymentMethod,
&i.CreatedAt,
&i.UpdatedAt,
&i.FirstName,
&i.LastName,
&i.PhoneNumber,
)
return i, err
}
const GetTransferByReference = `-- name: GetTransferByReference :one
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
SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at, first_name, last_name, phone_number
FROM wallet_transfer_details
WHERE reference_number = $1
`
func (q *Queries) GetTransferByReference(ctx context.Context, referenceNumber string) (WalletTransfer, error) {
func (q *Queries) GetTransferByReference(ctx context.Context, referenceNumber string) (WalletTransferDetail, error) {
row := q.db.QueryRow(ctx, GetTransferByReference, referenceNumber)
var i WalletTransfer
var i WalletTransferDetail
err := row.Scan(
&i.ID,
&i.Amount,
@ -162,26 +168,29 @@ func (q *Queries) GetTransferByReference(ctx context.Context, referenceNumber st
&i.PaymentMethod,
&i.CreatedAt,
&i.UpdatedAt,
&i.FirstName,
&i.LastName,
&i.PhoneNumber,
)
return i, err
}
const GetTransfersByWallet = `-- name: GetTransfersByWallet :many
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
SELECT id, amount, message, type, receiver_wallet_id, sender_wallet_id, cashier_id, verified, reference_number, status, payment_method, created_at, updated_at, first_name, last_name, phone_number
FROM wallet_transfer_details
WHERE receiver_wallet_id = $1
OR sender_wallet_id = $1
`
func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID pgtype.Int8) ([]WalletTransfer, error) {
func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID pgtype.Int8) ([]WalletTransferDetail, error) {
rows, err := q.db.Query(ctx, GetTransfersByWallet, receiverWalletID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []WalletTransfer
var items []WalletTransferDetail
for rows.Next() {
var i WalletTransfer
var i WalletTransferDetail
if err := rows.Scan(
&i.ID,
&i.Amount,
@ -196,6 +205,9 @@ func (q *Queries) GetTransfersByWallet(ctx context.Context, receiverWalletID pgt
&i.PaymentMethod,
&i.CreatedAt,
&i.UpdatedAt,
&i.FirstName,
&i.LastName,
&i.PhoneNumber,
); err != nil {
return nil, err
}

View File

@ -183,7 +183,8 @@ wHERE (
OR $2 IS NULL
)
AND (
full_name ILIKE '%' || $3 || '%'
first_name ILIKE '%' || $3 || '%'
OR last_name ILIKE '%' || $3 || '%'
OR phone_number ILIKE '%' || $3 || '%'
OR $3 IS NULL
)

View File

@ -18,8 +18,7 @@ const (
BANK
)
// Transaction only represents when the user cashes out a bet in the shop
// It probably would be better to call it a CashOut or ShopWithdrawal
// Transaction only represents branch transactions
type Transaction struct {
ID int64
Amount Currency

View File

@ -43,10 +43,28 @@ type Transfer struct {
SenderWalletID ValidInt64 `json:"sender_wallet_id"`
ReferenceNumber string `json:"reference_number"` // <-- needed
Status string `json:"status"`
CashierID ValidInt64 `json:"cashier_id"`
DepositorID ValidInt64 `json:"depositor_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type TransferDetail struct {
ID int64 `json:"id"`
Amount Currency `json:"amount"`
Verified bool `json:"verified"`
Message string `json:"message"`
Type TransferType `json:"type"`
PaymentMethod PaymentMethod `json:"payment_method"`
ReceiverWalletID ValidInt64 `json:"receiver_wallet_id"`
SenderWalletID ValidInt64 `json:"sender_wallet_id"`
ReferenceNumber string `json:"reference_number"` // <-- needed
Status string `json:"status"`
DepositorID ValidInt64 `json:"depositor_id"`
DepositorFirstName string `json:"depositor_first_name"`
DepositorLastName string `json:"depositor_last_name"`
DepositorPhoneNumber string `json:"depositor_phone_number"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type CreateTransfer struct {
Amount Currency `json:"amount"`

View File

@ -8,12 +8,13 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
return domain.Transfer{
func convertDBTransferDetail(transfer dbgen.WalletTransferDetail) domain.TransferDetail {
return domain.TransferDetail{
ID: transfer.ID,
Amount: domain.Currency(transfer.Amount.Int64),
Type: domain.TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: domain.ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
@ -22,7 +23,36 @@ func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
CashierID: domain.ValidInt64{
DepositorID: domain.ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
DepositorFirstName: transfer.FirstName.String,
DepositorLastName: transfer.LastName.String,
DepositorPhoneNumber: transfer.PhoneNumber.String,
PaymentMethod: domain.PaymentMethod(transfer.PaymentMethod.String),
ReferenceNumber: transfer.ReferenceNumber,
Status: transfer.Status.String,
CreatedAt: transfer.CreatedAt.Time,
UpdatedAt: transfer.UpdatedAt.Time,
}
}
func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
return domain.Transfer{
ID: transfer.ID,
Amount: domain.Currency(transfer.Amount.Int64),
Type: domain.TransferType(transfer.Type.String),
Verified: transfer.Verified.Bool,
Message: transfer.Message,
ReceiverWalletID: domain.ValidInt64{
Value: transfer.ReceiverWalletID.Int64,
Valid: transfer.ReceiverWalletID.Valid,
},
SenderWalletID: domain.ValidInt64{
Value: transfer.SenderWalletID.Int64,
Valid: transfer.SenderWalletID.Valid,
},
DepositorID: domain.ValidInt64{
Value: transfer.CashierID.Int64,
Valid: transfer.CashierID.Valid,
},
@ -54,6 +84,10 @@ func convertCreateTransfer(transfer domain.CreateTransfer) dbgen.CreateTransferP
ReferenceNumber: string(transfer.ReferenceNumber),
PaymentMethod: pgtype.Text{String: string(transfer.PaymentMethod), Valid: true},
Verified: pgtype.Bool{
Bool: transfer.Verified,
Valid: true,
},
}
}
@ -65,47 +99,47 @@ func (s *Store) CreateTransfer(ctx context.Context, transfer domain.CreateTransf
return convertDBTransfer(newTransfer), nil
}
func (s *Store) GetAllTransfers(ctx context.Context) ([]domain.Transfer, error) {
func (s *Store) GetAllTransfers(ctx context.Context) ([]domain.TransferDetail, error) {
transfers, err := s.queries.GetAllTransfers(ctx)
if err != nil {
return nil, err
}
var result []domain.Transfer = make([]domain.Transfer, 0, len(transfers))
var result []domain.TransferDetail = make([]domain.TransferDetail, 0, len(transfers))
for _, transfer := range transfers {
result = append(result, convertDBTransfer(transfer))
result = append(result, convertDBTransferDetail(transfer))
}
return result, nil
}
func (s *Store) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.Transfer, error) {
func (s *Store) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.TransferDetail, error) {
transfers, err := s.queries.GetTransfersByWallet(ctx, pgtype.Int8{Int64: walletID, Valid: true})
if err != nil {
return nil, err
}
var result []domain.Transfer = make([]domain.Transfer, 0, len(transfers))
var result []domain.TransferDetail = make([]domain.TransferDetail, 0, len(transfers))
for _, transfer := range transfers {
result = append(result, convertDBTransfer(transfer))
result = append(result, convertDBTransferDetail(transfer))
}
return result, nil
}
func (s *Store) GetTransferByReference(ctx context.Context, reference string) (domain.Transfer, error) {
func (s *Store) GetTransferByReference(ctx context.Context, reference string) (domain.TransferDetail, error) {
transfer, err := s.queries.GetTransferByReference(ctx, reference)
if err != nil {
return domain.Transfer{}, nil
return domain.TransferDetail{}, nil
}
return convertDBTransfer(transfer), nil
return convertDBTransferDetail(transfer), nil
}
func (s *Store) GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error) {
func (s *Store) GetTransferByID(ctx context.Context, id int64) (domain.TransferDetail, error) {
transfer, err := s.queries.GetTransferByID(ctx, id)
if err != nil {
return domain.Transfer{}, nil
return domain.TransferDetail{}, nil
}
return convertDBTransfer(transfer), nil
return convertDBTransferDetail(transfer), nil
}
func (s *Store) UpdateTransferVerification(ctx context.Context, id int64, verified bool) error {

View File

@ -149,8 +149,21 @@ func (s *Store) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]do
return userList, totalCount, nil
}
func (s *Store) GetAllCashiers(ctx context.Context) ([]domain.GetCashier, int64, error) {
users, err := s.queries.GetAllCashiers(ctx)
func (s *Store) GetAllCashiers(ctx context.Context, filter domain.UserFilter) ([]domain.GetCashier, int64, error) {
users, err := s.queries.GetAllCashiers(ctx, dbgen.GetAllCashiersParams{
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 {
return nil, 0, err
}

View File

@ -276,7 +276,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
Value: userID,
Valid: true,
}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", deductedAmount))
fmt.Sprintf("Deducted %v amount from wallet by system while placing bet", deductedAmount))
if err != nil {
s.mongoLogger.Error("failed to deduct from wallet",
zap.Int64("wallet_id", branch.WalletID),
@ -312,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{
Value: userID,
Valid: true,
}, domain.TRANSFER_DIRECT, fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", deductedAmount))
}, domain.TRANSFER_DIRECT, fmt.Sprintf("Deducted %v amount from wallet by system while placing bet", deductedAmount))
if err != nil {
s.mongoLogger.Error("wallet deduction failed",
zap.Int64("wallet_id", branch.WalletID),
@ -339,7 +339,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
if req.Amount < wallets.RegularBalance.Float32() {
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID,
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))
domain.TRANSFER_DIRECT, fmt.Sprintf("Deducted %v amount from wallet by system while placing bet", req.Amount))
if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer regular wallet",
zap.Int64("customer_id", wallets.CustomerID),
@ -358,7 +358,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
// Empty the regular balance
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.RegularID,
wallets.RegularBalance, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", wallets.RegularBalance.Float32()))
fmt.Sprintf("Deducted %v amount from wallet by system while placing bet", wallets.RegularBalance.Float32()))
if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer regular wallet",
zap.Int64("customer_id", wallets.CustomerID),
@ -373,7 +373,7 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
remainingAmount := wallets.RegularBalance - domain.Currency(req.Amount)
_, err = s.walletSvc.DeductFromWallet(ctx, wallets.StaticID,
remainingAmount, domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing bet", remainingAmount.Float32()))
fmt.Sprintf("Deducted %v amount from wallet by system while placing bet", remainingAmount.Float32()))
if err != nil {
s.mongoLogger.Error("wallet deduction failed for customer static wallet",
zap.Int64("customer_id", wallets.CustomerID),
@ -759,7 +759,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.Outc
}
_, 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()))
domain.TRANSFER_DIRECT, domain.PaymentDetails{}, fmt.Sprintf("Added %v to wallet by system for winning a bet", amount.Float32()))
if err != nil {
s.mongoLogger.Error("failed to add winnings to wallet",

View File

@ -83,7 +83,7 @@ func (s *Service) InitiateDeposit(ctx context.Context, userID int64, amount doma
// Create payment record
transfer := domain.CreateTransfer{
Message: fmt.Sprintf("Depositing %d into wallet using chapa. Reference Number %s", amount, reference),
Message: fmt.Sprintf("Depositing %v into wallet using chapa. Reference Number %v", amount.Float32(), reference),
Amount: amount,
Type: domain.DEPOSIT,
PaymentMethod: domain.TRANSFER_CHAPA,
@ -269,7 +269,7 @@ func (s *Service) ManuallyVerify(ctx context.Context, txRef string) (*domain.Cha
// Credit wallet
_, 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()))
fmt.Sprintf("Added %v to wallet using Chapa", transfer.Amount.Float32()))
if err != nil {
return nil, fmt.Errorf("failed to credit wallet: %w", err)
}
@ -330,7 +330,7 @@ func (s *Service) HandleVerifyDepositWebhook(ctx context.Context, transfer domai
ReferenceNumber: domain.ValidString{
Value: transfer.Reference,
},
}, fmt.Sprintf("Added %d to wallet using Chapa")); err != nil {
}, fmt.Sprintf("Added %v to wallet using Chapa")); err != nil {
return fmt.Errorf("failed to credit user wallet: %w", err)
}
}
@ -368,7 +368,7 @@ func (s *Service) HandleVerifyWithdrawWebhook(ctx context.Context, payment domai
} else {
_, 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"))
fmt.Sprintf("Added %v to wallet by system because chapa withdraw is unsuccessful"))
if err != nil {
return fmt.Errorf("failed to credit user wallet: %w", err)
}

View File

@ -127,7 +127,10 @@ func (s *Service) ProcessReferral(ctx context.Context, referredPhone, referralCo
return err
}
_, err = s.walletSvc.AddToWallet(ctx, wallets.StaticID, domain.ToCurrency(float32(referral.RewardAmount)), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
_, err = s.walletSvc.AddToWallet(ctx, wallets.StaticID,
domain.ToCurrency(float32(referral.RewardAmount)), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to static wallet because of referral ID %v", referral.RewardAmount, referrerId),
)
if err != nil {
s.logger.Error("Failed to add referral reward to static wallet", "walletID", wallets.StaticID, "referrer phone number", referredPhone, "error", err)
return err
@ -165,7 +168,9 @@ func (s *Service) ProcessDepositBonus(ctx context.Context, userPhone string, amo
walletID := wallets[0].ID
bonus := amount * (settings.CashbackPercentage / 100)
currentBonus := float64(wallets[0].Balance)
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.ToCurrency(float32(currentBonus+bonus)), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.ToCurrency(float32(currentBonus+bonus)), domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to static wallet because of Deposit Cashback Bonus %d", currentBonus+bonus, bonus))
if err != nil {
s.logger.Error("Failed to add deposit bonus to wallet", "walletID", walletID, "userID", userID, "bonus", bonus, "error", err)
return err
@ -219,7 +224,9 @@ func (s *Service) ProcessBetReferral(ctx context.Context, userPhone string, betA
walletID := wallets[0].ID
currentBalance := float64(wallets[0].Balance)
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.ToCurrency(float32(currentBalance+bonus)), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.ToCurrency(float32(currentBalance+bonus)), domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to static wallet because of bet referral", referral.RewardAmount))
if err != nil {
s.logger.Error("Failed to add bet referral bonus to wallet", "walletID", walletID, "referrerID", referrerID, "bonus", bonus, "error", err)
return err

View File

@ -58,8 +58,8 @@ func (s *Service) GetCashiersByBranch(ctx context.Context, branchID int64) ([]do
return s.userStore.GetCashiersByBranch(ctx, branchID)
}
func (s *Service) GetAllCashiers(ctx context.Context) ([]domain.GetCashier, int64, error){
return s.userStore.GetAllCashiers(ctx)
func (s *Service) GetAllCashiers(ctx context.Context, filter domain.UserFilter) ([]domain.GetCashier, int64, error){
return s.userStore.GetAllCashiers(ctx, filter)
}
func (s *Service) GetCashierByID(ctx context.Context, cashierID int64) (domain.GetCashier, error) {

View File

@ -10,8 +10,8 @@ type UserStore interface {
CreateUser(ctx context.Context, user domain.User, usedOtpId int64, is_company bool) (domain.User, error)
CreateUserWithoutOtp(ctx context.Context, user domain.User, is_company bool) (domain.User, error)
GetUserByID(ctx context.Context, id int64) (domain.User, error)
GetAllUsers(ctx context.Context, filter Filter) ([]domain.User, int64, error)
GetAllCashiers(ctx context.Context) ([]domain.GetCashier, int64, error)
GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error)
GetAllCashiers(ctx context.Context, filter domain.UserFilter) ([]domain.GetCashier, int64, error)
GetCashierByID(ctx context.Context, cashierID int64) (domain.GetCashier, error)
GetCashiersByBranch(ctx context.Context, branchID int64) ([]domain.User, error)
UpdateUser(ctx context.Context, user domain.UpdateUserReq) error

View File

@ -127,8 +127,9 @@ func (s *AleaPlayService) processTransaction(ctx context.Context, tx *domain.Vir
return errors.New("no wallet available for user")
}
tx.WalletID = wallets[0].ID
if _, err := s.walletSvc.AddToWallet(ctx, tx.WalletID, domain.Currency(tx.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil {
_, err = s.walletSvc.AddToWallet(ctx, tx.WalletID, domain.Currency(tx.Amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to wallet for winning AleaPlay Virtual Bet", tx.Amount))
if err != nil {
return fmt.Errorf("wallet update failed: %w", err)
}

View File

@ -138,7 +138,9 @@ func (s *service) HandleCallback(ctx context.Context, callback *domain.PopOKCall
return errors.New("unknown transaction type")
}
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.Currency(amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
_, err = s.walletSvc.AddToWallet(ctx, walletID, domain.Currency(amount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to wallet for winning PopOkBet", amount),
)
if err != nil {
s.logger.Error("Failed to update wallet", "walletID", walletID, "userID", session.UserID, "amount", amount, "error", err)
return err
@ -208,7 +210,7 @@ func (s *service) ProcessBet(ctx context.Context, req *domain.PopOKBetRequest) (
}
_, err = s.walletSvc.DeductFromWallet(ctx, claims.UserID, domain.Currency(amountCents),
domain.CustomerWalletType, domain.ValidInt64{}, domain.TRANSFER_DIRECT,
fmt.Sprintf("Deducted %d amount from wallet by system while placing virtual game bet", amountCents))
fmt.Sprintf("Deducted %v amount from wallet by system while placing virtual game bet", amountCents))
if err != nil {
return nil, fmt.Errorf("insufficient balance")
}
@ -274,8 +276,11 @@ func (s *service) ProcessWin(ctx context.Context, req *domain.PopOKWinRequest) (
amountCents := int64(req.Amount * 100)
// 4. Credit to wallet
if _, err := s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil {
_, err = s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to wallet for winning PopOkBet", req.Amount),
)
if err != nil {
s.logger.Error("Failed to credit wallet", "userID", claims.UserID, "error", err)
return nil, fmt.Errorf("wallet credit failed")
}
@ -342,7 +347,9 @@ func (s *service) ProcessTournamentWin(ctx context.Context, req *domain.PopOKWin
amountCents := int64(req.Amount * 100)
// 4. Credit user wallet
if _, err := s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil {
_, err = s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to wallet for winning Popok Tournament", req.Amount))
if err != nil {
s.logger.Error("Failed to credit wallet for tournament", "userID", claims.UserID, "error", err)
return nil, fmt.Errorf("wallet credit failed")
}
@ -403,8 +410,9 @@ func (s *service) ProcessPromoWin(ctx context.Context, req *domain.PopOKWinReque
}
amountCents := int64(req.Amount * 100)
if _, err := s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil {
_, err = s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(amountCents), domain.ValidInt64{},
domain.TRANSFER_DIRECT, domain.PaymentDetails{}, fmt.Sprintf("Added %v to wallet for winning PopOk Promo Win", req.Amount))
if err != nil {
s.logger.Error("Failed to credit wallet for promo", "userID", claims.UserID, "error", err)
return nil, fmt.Errorf("wallet credit failed")
}
@ -509,8 +517,10 @@ func (s *service) ProcessCancel(ctx context.Context, req *domain.PopOKCancelRequ
// 5. Refund the bet amount (absolute value since bet amount is negative)
refundAmount := -originalBet.Amount
if _, err := s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(refundAmount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}); err != nil {
_, err = s.walletSvc.AddToWallet(ctx, claims.UserID, domain.Currency(refundAmount), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to wallet as refund for cancelling PopOk bet", refundAmount),
)
if err != nil {
s.logger.Error("Failed to refund bet", "userID", claims.UserID, "error", err)
return nil, fmt.Errorf("refund failed")
}

View File

@ -26,10 +26,10 @@ type WalletStore interface {
type TransferStore interface {
CreateTransfer(ctx context.Context, transfer domain.CreateTransfer) (domain.Transfer, error)
GetAllTransfers(ctx context.Context) ([]domain.Transfer, error)
GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.Transfer, error)
GetTransferByReference(ctx context.Context, reference string) (domain.Transfer, error)
GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error)
GetAllTransfers(ctx context.Context) ([]domain.TransferDetail, error)
GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.TransferDetail, error)
GetTransferByReference(ctx context.Context, reference string) (domain.TransferDetail, error)
GetTransferByID(ctx context.Context, id int64) (domain.TransferDetail, error)
UpdateTransferVerification(ctx context.Context, id int64, verified bool) error
UpdateTransferStatus(ctx context.Context, id int64, status string) error
}

View File

@ -9,8 +9,9 @@ import (
)
var (
ErrWalletNotTransferable = errors.New("wallet is not transferable")
ErrInsufficientBalance = errors.New("wallet balance is insufficient")
ErrSenderWalletNotTransferable = errors.New("sender wallet is not transferable")
ErrReceiverWalletNotTransferable = errors.New("receiver wallet is not transferable")
ErrInsufficientBalance = errors.New("wallet balance is insufficient")
)
func (s *Service) CreateTransfer(ctx context.Context, transfer domain.CreateTransfer) (domain.Transfer, error) {
@ -18,19 +19,19 @@ func (s *Service) CreateTransfer(ctx context.Context, transfer domain.CreateTran
return s.transferStore.CreateTransfer(ctx, transfer)
}
func (s *Service) GetAllTransfers(ctx context.Context) ([]domain.Transfer, error) {
func (s *Service) GetAllTransfers(ctx context.Context) ([]domain.TransferDetail, error) {
return s.transferStore.GetAllTransfers(ctx)
}
func (s *Service) GetTransferByReference(ctx context.Context, reference string) (domain.Transfer, error) {
func (s *Service) GetTransferByReference(ctx context.Context, reference string) (domain.TransferDetail, error) {
return s.transferStore.GetTransferByReference(ctx, reference)
}
func (s *Service) GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error) {
func (s *Service) GetTransferByID(ctx context.Context, id int64) (domain.TransferDetail, error) {
return s.transferStore.GetTransferByID(ctx, id)
}
func (s *Service) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.Transfer, error) {
func (s *Service) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.TransferDetail, error) {
return s.transferStore.GetTransfersByWallet(ctx, walletID)
}
@ -44,15 +45,17 @@ func (s *Service) UpdateTransferStatus(ctx context.Context, id int64, status str
func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiverID int64,
amount domain.Currency, paymentMethod domain.PaymentMethod,
cashierID domain.ValidInt64) (domain.Transfer, error) {
cashierID domain.ValidInt64, message string) (domain.Transfer, error) {
senderWallet, err := s.GetWalletByID(ctx, senderID)
if err != nil {
return domain.Transfer{}, err
}
if senderWallet.IsTransferable {
return domain.Transfer{}, ErrWalletNotTransferable
if !senderWallet.IsTransferable {
fmt.Printf("Error: %d Sender Wallet is not transferable \n", senderWallet.ID)
return domain.Transfer{}, ErrSenderWalletNotTransferable
}
receiverWallet, err := s.GetWalletByID(ctx, receiverID)
@ -60,8 +63,9 @@ func (s *Service) TransferToWallet(ctx context.Context, senderID int64, receiver
return domain.Transfer{}, err
}
if receiverWallet.IsTransferable {
return domain.Transfer{}, ErrWalletNotTransferable
if !receiverWallet.IsTransferable {
fmt.Printf("Error: %d Receiver Wallet is not transferable \n", senderWallet.ID)
return domain.Transfer{}, ErrReceiverWalletNotTransferable
}
// Deduct from sender
@ -84,7 +88,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
transfer, err := s.CreateTransfer(ctx, domain.CreateTransfer{
Message: fmt.Sprintf("Transferring %d to another wallet", amount),
Message: message,
SenderWalletID: domain.ValidInt64{
Value: senderID,
Valid: true,

View File

@ -23,22 +23,22 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
spec string
task func()
}{
{
spec: "0 0 * * * *", // Every 1 hour
task: func() {
if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
log.Printf("FetchUpcomingEvents error: %v", err)
}
},
},
{
spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events)
task: func() {
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
log.Printf("FetchNonLiveOdds error: %v", err)
}
},
},
// {
// spec: "0 0 * * * *", // Every 1 hour
// task: func() {
// if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
// log.Printf("FetchUpcomingEvents error: %v", err)
// }
// },
// },
// {
// spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events)
// task: func() {
// if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
// log.Printf("FetchNonLiveOdds error: %v", err)
// }
// },
// },
{
spec: "0 */5 * * * *", // Every 5 Minutes
task: func() {
@ -66,7 +66,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
}
for _, job := range schedule {
job.task()
// job.task()
if _, err := c.AddFunc(job.spec, job.task); err != nil {
log.Fatalf("Failed to schedule cron job: %v", err)
}

View File

@ -7,7 +7,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"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/gofiber/fiber/v2"
)
@ -178,7 +177,11 @@ func (h *Handler) GetAllCashiers(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
cashiers, total, err := h.userSvc.GetAllCashiers(c.Context())
cashiers, total, err := h.userSvc.GetAllCashiers(c.Context(), domain.UserFilter{
Query: searchString,
CreatedBefore: createdBefore,
CreatedAfter: createdAfter,
})
if err != nil {
h.logger.Error("GetAllCashiers failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil)

View File

@ -66,7 +66,9 @@ func (h *Handler) InitiateDeposit(c *fiber.Ctx) error {
multiplier = bonusMultiplier[0].Multiplier
}
_, err = h.walletSvc.AddToWallet(c.Context(), wallet.StaticID, domain.ToCurrency(float32(amount)*multiplier), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{})
_, err = h.walletSvc.AddToWallet(c.Context(), wallet.StaticID, domain.ToCurrency(float32(amount)*multiplier), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
fmt.Sprintf("Added %v to static wallet because of deposit bonus using multiplier %v", float32(amount)*multiplier, multiplier),
)
if err != nil {
h.logger.Error("Failed to add bonus to static wallet", "walletID", wallet.StaticID, "user id", userID, "error", err)
return err

View File

@ -6,7 +6,6 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"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/gofiber/fiber/v2"
)
@ -173,7 +172,7 @@ func (h *Handler) GetAllManagers(c *fiber.Ctx) error {
managers, total, err := h.userSvc.GetAllUsers(c.Context(), filter)
if err != nil {
h.logger.Error("GetAllManagers failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", nil, nil)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", err, nil)
}
var result []ManagersRes = make([]ManagersRes, len(managers))

View File

@ -9,7 +9,6 @@ import (
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/adaptor"
@ -183,7 +182,7 @@ func (h *Handler) CreateAndSendNotification(c *fiber.Ctx) error {
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"message": "Single notification sent successfully", "notification_id": notification.ID})
case domain.NotificationDeliverySchemeBulk:
recipients, _, err := h.userSvc.GetAllUsers(context.Background(), user.Filter{
recipients, _, err := h.userSvc.GetAllUsers(context.Background(), domain.UserFilter{
Role: string(req.Reciever),
})
if err != nil {

View File

@ -8,20 +8,25 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
type TransferWalletRes struct {
ID int64 `json:"id"`
Amount float32 `json:"amount"`
Verified bool `json:"verified"`
Type string `json:"type"`
PaymentMethod string `json:"payment_method"`
ReceiverWalletID *int64 `json:"receiver_wallet_id,omitempty"`
SenderWalletID *int64 `json:"sender_wallet_id,omitempty"`
CashierID *int64 `json:"cashier_id,omitempty"`
ReferenceNumber string `json:"reference_number"` // ← Add this
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID int64 `json:"id"`
Amount float32 `json:"amount"`
Verified bool `json:"verified"`
Message string `json:"message"`
Type string `json:"type"`
PaymentMethod string `json:"payment_method"`
ReceiverWalletID *int64 `json:"receiver_wallet_id,omitempty"`
SenderWalletID *int64 `json:"sender_wallet_id,omitempty"`
DepositorID *int64 `json:"depositor_id,omitempty"`
DepositorFirstName string `json:"depositor_first_name"`
DepositorLastName string `json:"depositor_last_name"`
DepositorPhoneNumber string `json:"depositor_phone_number"`
ReferenceNumber string `json:"reference_number"` // ← Add this
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type RefillRes struct {
@ -48,25 +53,60 @@ func convertTransfer(t domain.Transfer) TransferWalletRes {
senderID = &t.SenderWalletID.Value
}
var cashierID *int64
if t.CashierID.Valid {
cashierID = &t.CashierID.Value
var depositorID *int64
if t.DepositorID.Valid {
depositorID = &t.DepositorID.Value
}
return TransferWalletRes{
ID: t.ID,
Amount: float32(t.Amount),
Amount: t.Amount.Float32(),
Verified: t.Verified,
Message: t.Message,
Type: string(t.Type),
PaymentMethod: string(t.PaymentMethod),
ReceiverWalletID: receiverID,
SenderWalletID: senderID,
CashierID: cashierID,
DepositorID: depositorID,
ReferenceNumber: t.ReferenceNumber,
CreatedAt: t.CreatedAt,
UpdatedAt: t.UpdatedAt,
}
}
func convertTransferDetail(t domain.TransferDetail) TransferWalletRes {
var receiverID *int64
if t.ReceiverWalletID.Valid {
receiverID = &t.ReceiverWalletID.Value
}
var senderID *int64
if t.SenderWalletID.Valid {
senderID = &t.SenderWalletID.Value
}
var depositorID *int64
if t.DepositorID.Valid {
depositorID = &t.DepositorID.Value
}
return TransferWalletRes{
ID: t.ID,
Amount: t.Amount.Float32(),
Verified: t.Verified,
Message: t.Message,
Type: string(t.Type),
PaymentMethod: string(t.PaymentMethod),
ReceiverWalletID: receiverID,
SenderWalletID: senderID,
DepositorID: depositorID,
DepositorFirstName: t.DepositorFirstName,
DepositorLastName: t.DepositorLastName,
DepositorPhoneNumber: t.DepositorPhoneNumber,
ReferenceNumber: t.ReferenceNumber,
CreatedAt: t.CreatedAt,
UpdatedAt: t.UpdatedAt,
}
}
type CreateTransferReq struct {
Amount float32 `json:"amount" example:"100.0"`
@ -107,7 +147,7 @@ func (h *Handler) GetTransfersByWallet(c *fiber.Ctx) error {
var transferResponses []TransferWalletRes
for _, transfer := range transfers {
transferResponses = append(transferResponses, convertTransfer(transfer))
transferResponses = append(transferResponses, convertTransferDetail(transfer))
}
return response.WriteJSON(c, fiber.StatusOK, "Transfers retrieved successfully", transferResponses, nil)
@ -140,16 +180,15 @@ func (h *Handler) TransferToWallet(c *fiber.Ctx) error {
role := c.Locals("role").(domain.Role)
companyID := c.Locals("company_id").(domain.ValidInt64)
fmt.Printf("\n\nCompant ID: %v\n\n", companyID.Value)
fmt.Printf("\n\nCompany ID: %v\n\n", companyID.Value)
var senderID int64
//TODO: check to make sure that the cashiers aren't transferring TO branch wallet
switch role {
case domain.RoleCustomer:
h.logger.Error("Unauthorized access", "userID", userID, "role", role)
return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
case domain.RoleBranchManager, domain.RoleAdmin, domain.RoleSuperAdmin:
case domain.RoleAdmin:
company, err := h.companySvc.GetCompanyByID(c.Context(), companyID.Value)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
@ -160,13 +199,20 @@ func (h *Handler) TransferToWallet(c *fiber.Ctx) error {
}
senderID = company.WalletID
h.logger.Error("Will", "userID", userID, "role", role)
default:
case domain.RoleSuperAdmin:
return response.WriteJSON(c, fiber.StatusBadRequest, "Super Admin does not have a wallet", err, nil)
case domain.RoleBranchManager:
return response.WriteJSON(c, fiber.StatusBadRequest, "Branch Manager does not have a wallet", err, nil)
case domain.RoleCashier:
cashierBranch, err := h.branchSvc.GetBranchByCashier(c.Context(), userID)
if err != nil {
h.logger.Error("Failed to get branch", "user ID", userID, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve cashier branch", err, nil)
}
senderID = cashierBranch.WalletID
default:
return response.WriteJSON(c, fiber.StatusInternalServerError, "Unknown Role", err, nil)
}
var req CreateTransferReq
@ -181,9 +227,14 @@ func (h *Handler) TransferToWallet(c *fiber.Ctx) error {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
transfer, err := h.walletSvc.TransferToWallet(c.Context(), senderID, receiverID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod), domain.ValidInt64{Value: userID, Valid: true})
transfer, err := h.walletSvc.TransferToWallet(c.Context(),
senderID, receiverID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod),
domain.ValidInt64{Value: userID, Valid: true},
fmt.Sprintf("Transferred %v from wallet to another", req.Amount),
)
if !ok {
if err != nil {
h.mongoLoggerSvc.Error("Failed to transfer money to wallet", zap.Error(err))
return response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
}
@ -233,7 +284,7 @@ func (h *Handler) RefillWallet(c *fiber.Ctx) error {
c.Context(), receiverID, domain.ToCurrency(req.Amount), domain.ValidInt64{
Value: userID,
Valid: true,
}, domain.TRANSFER_BANK, domain.PaymentDetails{}, fmt.Sprintf("Added %d to wallet directly by super-admin", req.Amount))
}, domain.TRANSFER_BANK, domain.PaymentDetails{}, fmt.Sprintf("Added %v to wallet directly by super-admin", req.Amount))
if !ok {
return response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)

View File

@ -50,7 +50,7 @@ swagger:
.PHONY: db-up
db-up:
@docker compose up -d postgres migrate mongo
@docker compose up -d postgres migrate mongo redis
.PHONY: db-down
db-down: