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

@ -25,11 +25,11 @@ 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)
UpdateTransferVerification(ctx context.Context, id int64, verified bool) error
UpdateTransferStatus(ctx context.Context, id int64, status string) error
CreateTransfer(ctx context.Context, transfer domain.CreateTransfer) (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: