267 lines
8.1 KiB
Go
267 lines
8.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"log/slog"
|
|
"strconv"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
|
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type CreateBetReq struct {
|
|
Outcomes []int64 `json:"outcomes"`
|
|
Amount float32 `json:"amount" example:"100.0"`
|
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
|
Status domain.BetStatus `json:"status" example:"1"`
|
|
FullName string `json:"full_name" example:"John"`
|
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
|
}
|
|
|
|
type BetRes struct {
|
|
ID int64 `json:"id" example:"1"`
|
|
Outcomes []domain.Outcome `json:"outcomes"`
|
|
Amount float32 `json:"amount" example:"100.0"`
|
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
|
Status domain.BetStatus `json:"status" example:"1"`
|
|
FullName string `json:"full_name" example:"John"`
|
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
|
BranchID int64 `json:"branch_id" example:"2"`
|
|
UserID int64 `json:"user_id" example:"2"`
|
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
|
}
|
|
|
|
func convertBet(bet domain.Bet) BetRes {
|
|
return BetRes{
|
|
ID: bet.ID,
|
|
Outcomes: bet.Outcomes,
|
|
Amount: bet.Amount.Float64(),
|
|
TotalOdds: bet.TotalOdds,
|
|
Status: bet.Status,
|
|
FullName: bet.FullName,
|
|
PhoneNumber: bet.PhoneNumber,
|
|
BranchID: bet.BranchID.Value,
|
|
UserID: bet.UserID.Value,
|
|
}
|
|
}
|
|
|
|
// CreateBet godoc
|
|
// @Summary Create a bet
|
|
// @Description Creates a bet
|
|
// @Tags bet
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createBet body CreateBetReq true "Creates bet"
|
|
// @Success 200 {object} BetRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /bet [post]
|
|
func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
|
|
// TODO: Check the token, and find the role and get the branch id from there
|
|
|
|
// TODO Reduce amount from the branch wallet
|
|
|
|
var isShopBet bool = true
|
|
var branchID int64 = 1
|
|
var userID int64
|
|
|
|
var req CreateBetReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
logger.Error("CreateBetReq failed", "error", err)
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
|
"error": "Invalid request",
|
|
})
|
|
}
|
|
|
|
valErrs, ok := validator.Validate(c, req)
|
|
if !ok {
|
|
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
return nil
|
|
}
|
|
|
|
// TODO Validate Outcomes Here and make sure they didn't expire
|
|
|
|
bet, err := betSvc.CreateBet(c.Context(), domain.CreateBet{
|
|
Outcomes: req.Outcomes,
|
|
Amount: domain.Currency(req.Amount),
|
|
TotalOdds: req.TotalOdds,
|
|
Status: req.Status,
|
|
FullName: req.FullName,
|
|
PhoneNumber: req.PhoneNumber,
|
|
|
|
BranchID: domain.ValidInt64{
|
|
Value: branchID,
|
|
Valid: isShopBet,
|
|
},
|
|
UserID: domain.ValidInt64{
|
|
Value: userID,
|
|
Valid: !isShopBet,
|
|
},
|
|
IsShopBet: req.IsShopBet,
|
|
})
|
|
|
|
if err != nil {
|
|
logger.Error("CreateBetReq failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil)
|
|
}
|
|
|
|
res := convertBet(bet)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Bet Created", res, nil)
|
|
}
|
|
}
|
|
|
|
// GetAllBet godoc
|
|
// @Summary Gets all bets
|
|
// @Description Gets all the bets
|
|
// @Tags bet
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} BetRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /bet [get]
|
|
func GetAllBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
bets, err := betSvc.GetAllBets(c.Context())
|
|
|
|
if err != nil {
|
|
logger.Error("Failed to get bets", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve bets", err, nil)
|
|
}
|
|
|
|
var res []BetRes
|
|
for _, bet := range bets {
|
|
res = append(res, convertBet(bet))
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "All Bets Retrieved", res, nil)
|
|
}
|
|
}
|
|
|
|
// GetBetByID godoc
|
|
// @Summary Gets bet by id
|
|
// @Description Gets a single bet by id
|
|
// @Tags bet
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Bet ID"
|
|
// @Success 200 {object} BetRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /bet/{id} [get]
|
|
func GetBetByID(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
betID := c.Params("id")
|
|
id, err := strconv.ParseInt(betID, 10, 64)
|
|
|
|
if err != nil {
|
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
|
}
|
|
|
|
bet, err := betSvc.GetBetByID(c.Context(), id)
|
|
|
|
if err != nil {
|
|
logger.Error("Failed to get bet by ID", "betID", id, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve bet", err, nil)
|
|
}
|
|
|
|
res := convertBet(bet)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Bet retrieved successfully", res, nil)
|
|
|
|
}
|
|
}
|
|
|
|
type UpdateCashOutReq struct {
|
|
CashedOut bool
|
|
}
|
|
|
|
// UpdateCashOut godoc
|
|
// @Summary Updates the cashed out field
|
|
// @Description Updates the cashed out field
|
|
// @Tags bet
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Bet ID"
|
|
// @Param updateCashOut body UpdateCashOutReq true "Updates Cashed Out"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /bet/{id} [patch]
|
|
func UpdateCashOut(logger *slog.Logger, betSvc *bet.Service,
|
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
betID := c.Params("id")
|
|
id, err := strconv.ParseInt(betID, 10, 64)
|
|
|
|
if err != nil {
|
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
|
}
|
|
|
|
var req UpdateCashOutReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
logger.Error("UpdateCashOutReq failed", "error", err)
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
|
"error": "Invalid request",
|
|
})
|
|
}
|
|
|
|
valErrs, ok := validator.Validate(c, req)
|
|
if !ok {
|
|
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
return nil
|
|
}
|
|
|
|
err = betSvc.UpdateCashOut(c.Context(), id, req.CashedOut)
|
|
|
|
if err != nil {
|
|
logger.Error("Failed to update cash out bet", "betID", id, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cash out bet", err, nil)
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Bet updated successfully", nil, nil)
|
|
}
|
|
}
|
|
|
|
// DeleteBet godoc
|
|
// @Summary Deletes bet by id
|
|
// @Description Deletes bet by id
|
|
// @Tags bet
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Bet ID"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /bet/{id} [delete]
|
|
func DeleteBet(logger *slog.Logger, betSvc *bet.Service,
|
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
betID := c.Params("id")
|
|
id, err := strconv.ParseInt(betID, 10, 64)
|
|
|
|
if err != nil {
|
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
|
}
|
|
|
|
err = betSvc.DeleteBet(c.Context(), id)
|
|
|
|
if err != nil {
|
|
logger.Error("Failed to delete by ID", "betID", id, "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to delete bet", err, nil)
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Bet removed successfully", nil, nil)
|
|
}
|
|
}
|