fix: get bet by users for online betting

This commit is contained in:
Samuel Tariku 2025-05-27 14:57:35 +03:00
parent eafd68d3c2
commit 1b6fbebddf
13 changed files with 120 additions and 5 deletions

View File

@ -58,6 +58,10 @@ WHERE cashout_id = $1;
SELECT *
FROM bet_with_outcomes
WHERE branch_id = $1;
-- name: GetBetByUserID :many
SELECT *
FROM bet_with_outcomes
WHERE user_id = $1;
-- name: GetBetOutcomeByEventID :many
SELECT *
FROM bet_outcomes

View File

@ -243,6 +243,47 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
return i, err
}
const GetBetByUserID = `-- name: GetBetByUserID :many
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, cashout_id, created_at, updated_at, is_shop_bet, outcomes
FROM bet_with_outcomes
WHERE user_id = $1
`
func (q *Queries) GetBetByUserID(ctx context.Context, userID pgtype.Int8) ([]BetWithOutcome, error) {
rows, err := q.db.Query(ctx, GetBetByUserID, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []BetWithOutcome
for rows.Next() {
var i BetWithOutcome
if err := rows.Scan(
&i.ID,
&i.Amount,
&i.TotalOdds,
&i.Status,
&i.FullName,
&i.PhoneNumber,
&i.BranchID,
&i.UserID,
&i.CashedOut,
&i.CashoutID,
&i.CreatedAt,
&i.UpdatedAt,
&i.IsShopBet,
&i.Outcomes,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetBetOutcomeByBetID = `-- name: GetBetOutcomeByBetID :many
SELECT id, bet_id, sport_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, status, expires
FROM bet_outcomes

View File

@ -52,6 +52,7 @@ type Bet struct {
IsShopBet bool
CashedOut bool
CashoutID string
CreatedAt time.Time
}
type GetBet struct {
@ -67,6 +68,7 @@ type GetBet struct {
CashedOut bool
CashoutID string
Outcomes []BetOutcome
CreatedAt time.Time
}
type CreateBet struct {
@ -127,6 +129,7 @@ type BetRes struct {
IsShopBet bool `json:"is_shop_bet" example:"false"`
CashedOut bool `json:"cashed_out" example:"false"`
CashedID string `json:"cashed_id" example:"21234"`
CreatedAt time.Time `json:"created_at" example:"2025-04-08T12:00:00Z"`
}
func ConvertCreateBet(bet Bet, createdNumber int64) CreateBetRes {
@ -158,5 +161,6 @@ func ConvertBet(bet GetBet) BetRes {
IsShopBet: bet.IsShopBet,
CashedOut: bet.CashedOut,
CashedID: bet.CashoutID,
CreatedAt: bet.CreatedAt,
}
}

View File

@ -29,6 +29,7 @@ func convertDBBet(bet dbgen.Bet) domain.Bet {
IsShopBet: bet.IsShopBet,
CashedOut: bet.CashedOut,
CashoutID: bet.CashoutID,
CreatedAt: bet.CreatedAt.Time,
}
}
@ -78,6 +79,7 @@ func convertDBBetWithOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
CashedOut: bet.CashedOut,
CashoutID: bet.CashoutID,
Outcomes: outcomes,
CreatedAt: bet.CreatedAt.Time,
}
}
@ -198,6 +200,24 @@ func (s *Store) GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.
return result, nil
}
func (s *Store) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error) {
bets, err := s.queries.GetBetByUserID(ctx, pgtype.Int8{
Int64: UserID,
Valid: true,
})
if err != nil {
return nil, err
}
var result []domain.GetBet = make([]domain.GetBet, 0, len(bets))
for _, bet := range bets {
result = append(result, convertDBBetWithOutcomes(bet))
}
return result, nil
}
func (s *Store) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error {
err := s.queries.UpdateCashOut(ctx, dbgen.UpdateCashOutParams{
ID: id,

View File

@ -13,6 +13,7 @@ type BetStore interface {
GetBetByID(ctx context.Context, id int64) (domain.GetBet, error)
GetAllBets(ctx context.Context) ([]domain.GetBet, error)
GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error)
GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error)
GetBetOutcomeByEventID(ctx context.Context, eventID int64) ([]domain.BetOutcome, error)
GetBetOutcomeByBetID(ctx context.Context, betID int64) ([]domain.BetOutcome, error)
UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error

View File

@ -248,6 +248,12 @@ func (s *Service) PlaceBet(ctx context.Context, req domain.CreateBetReq, userID
return domain.CreateBetRes{}, err
}
newBet.UserID = domain.ValidInt64{
Value: userID,
Valid: true,
}
newBet.IsShopBet = false
default:
return domain.CreateBetRes{}, fmt.Errorf("Unknown Role Type")
}
@ -485,6 +491,10 @@ func (s *Service) GetBetByBranchID(ctx context.Context, branchID int64) ([]domai
return s.betStore.GetBetByBranchID(ctx, branchID)
}
func (s *Service) GetBetByUserID(ctx context.Context, UserID int64) ([]domain.GetBet, error) {
return s.betStore.GetBetByUserID(ctx, UserID)
}
func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error {
return s.betStore.UpdateCashOut(ctx, id, cashedOut)
}

View File

@ -104,7 +104,7 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
for _, sportID := range sportIDs {
var totalPages int = 1
var page int = 0
var limit int = 10
var limit int = 150
var count int = 0
for page <= totalPages {
page = page + 1

View File

@ -87,7 +87,7 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
return ErrBalanceInsufficient
}
return s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount)
return s.walletStore.UpdateBalance(ctx, id, wallet.Balance-amount)
}
func (s *Service) UpdateWalletActive(ctx context.Context, id int64, isActive bool) error {

View File

@ -52,7 +52,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

@ -45,7 +45,7 @@ func (h *Handler) CreateBet(c *fiber.Ctx) error {
h.logger.Error("PlaceBet failed", "error", err)
switch err {
case bet.ErrEventHasBeenRemoved, bet.ErrEventHasNotEnded, bet.ErrRawOddInvalid, wallet.ErrBalanceInsufficient:
return fiber.NewError(fiber.StatusBadGateway, err.Error())
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
return fiber.NewError(fiber.StatusInternalServerError, "Unable to create bet")
}

View File

@ -172,7 +172,10 @@ func (h *Handler) CreateTransaction(c *fiber.Ctx) error {
}
user, err := h.userSvc.GetUserByID(c.Context(), userID)
if err != nil {
h.logger.Error("CreateTransactionReq failed, user id invalid", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "User ID invalid", err, nil)
}
transaction, err := h.transactionSvc.CreateTransaction(c.Context(), domain.CreateTransaction{
BranchID: branchID,
CashierID: userID,

View File

@ -591,3 +591,34 @@ func (h *Handler) UpdateUserSuspend(c *fiber.Ctx) error {
}
return response.WriteJSON(c, fiber.StatusOK, "User suspend status updated successfully", res, nil)
}
// GetBetByUserID godoc
// @Summary Gets user bets
// @Description Gets user bets
// @Tags user
// @Accept json
// @Produce json
// @Success 200 {array} domain.BetRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /user/bets [get]
func (h *Handler) GetBetByUserID(c *fiber.Ctx) error {
userID, ok := c.Locals("user_id").(int64)
if !ok || userID == 0 {
h.logger.Error("Invalid user ID in context")
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user identification")
}
bets, err := h.betSvc.GetBetByUserID(c.Context(), userID)
if err != nil {
h.logger.Error("Failed to get bets", "error", err)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve bets")
}
res := make([]domain.BetRes, len(bets))
for i, bet := range bets {
res[i] = domain.ConvertBet(bet)
}
return response.WriteJSON(c, fiber.StatusOK, "User bets retrieved successfully", res, nil)
}

View File

@ -79,6 +79,7 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/user/single/:id", a.authMiddleware, h.GetUserByID)
a.fiber.Delete("/user/delete/:id", a.authMiddleware, h.DeleteUser)
a.fiber.Post("/user/suspend", a.authMiddleware, h.UpdateUserSuspend)
a.fiber.Get("/user/bets", a.authMiddleware, h.GetBetByUserID)
a.fiber.Get("/user/wallet", a.authMiddleware, h.GetCustomerWallet)
a.fiber.Post("/user/search", a.authMiddleware, h.SearchUserByNameOrPhone)