383 lines
13 KiB
Go
383 lines
13 KiB
Go
package handlers
|
|
|
|
import (
|
|
"log/slog"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
// CreateShopBet godoc
|
|
// @Summary Create bet at branch
|
|
// @Description Create bet at branch
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createBet body domain.ShopBetReq true "create bet"
|
|
// @Success 200 {object} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/bet [post]
|
|
func (h *Handler) CreateShopBet(c *fiber.Ctx) error {
|
|
|
|
userID := c.Locals("user_id").(int64)
|
|
role := c.Locals("role").(domain.Role)
|
|
company_id := c.Locals("company_id").(domain.ValidInt64)
|
|
|
|
var req domain.ShopBetReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("CreateBetReq failed to parse request", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
h.logger.Error("CreateBetReq failed v", "error", valErrs)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
shopBet, err := h.transactionSvc.CreateShopBet(c.Context(), userID, role, company_id, req)
|
|
|
|
if err != nil {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to cashout bet", err, nil)
|
|
}
|
|
res := domain.ConvertShopBet(shopBet)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
|
}
|
|
|
|
// CashoutBet godoc
|
|
// @Summary Cashout bet at branch
|
|
// @Description Cashout bet at branch
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param cashoutBet body domain.CashoutReq true "cashout bet"
|
|
// @Success 200 {object} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/bet/{id}/cashout [post]
|
|
func (h *Handler) CashoutBet(c *fiber.Ctx) error {
|
|
|
|
betIDStr := c.Params("id")
|
|
|
|
betID, err := strconv.ParseInt(betIDStr, 10, 64)
|
|
|
|
if err != nil {
|
|
h.logger.Error("CashoutReq invalid bet id", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet id", err, nil)
|
|
}
|
|
|
|
userID := c.Locals("user_id").(int64)
|
|
role := c.Locals("role").(domain.Role)
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
|
|
var req domain.CashoutReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("CashoutReq failed to parse request", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
h.logger.Error("CashoutReq failed v", "error", valErrs)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
transaction, err := h.transactionSvc.CashoutBet(c.Context(), betID, userID, role, req, companyID)
|
|
|
|
if err != nil {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to cashout bet", err, nil)
|
|
}
|
|
res := domain.ConvertShopTransaction(transaction)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
|
}
|
|
|
|
// CashoutByCashoutID godoc
|
|
// @Summary Cashout bet by cashoutID
|
|
// @Description Cashout bet by cashoutID
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param cashoutBet body domain.CashoutReq true "cashout bet"
|
|
// @Success 200 {object} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/cashout [post]
|
|
func (h *Handler) CashoutByCashoutID(c *fiber.Ctx) error {
|
|
|
|
userID := c.Locals("user_id").(int64)
|
|
role := c.Locals("role").(domain.Role)
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
|
|
var req domain.CashoutReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("CashoutReq failed to parse request", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
h.logger.Error("CashoutReq failed v", "error", valErrs)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
bet, err := h.transactionSvc.GetShopBetByCashoutID(c.Context(), req.CashoutID)
|
|
|
|
if err != nil {
|
|
h.logger.Error("CashoutReq failed invalid cashout id", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashout ID", err, nil)
|
|
}
|
|
|
|
transaction, err := h.transactionSvc.CashoutBet(c.Context(), bet.BetID, userID, role, req, companyID)
|
|
|
|
if err != nil {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to cashout bet", err, nil)
|
|
}
|
|
res := domain.ConvertShopTransaction(transaction)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
|
}
|
|
|
|
// CashoutBet godoc
|
|
// @Summary Cashout bet at branch
|
|
// @Description Cashout bet at branch
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createBet body domain.CashoutReq true "cashout bet"
|
|
// @Success 200 {object} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/cashout/{id} [get]
|
|
func (h *Handler) GetShopBetByCashoutID(c *fiber.Ctx) error {
|
|
|
|
cashoutID := c.Params("id")
|
|
|
|
if cashoutID == "" {
|
|
h.logger.Error("CashoutReq failed cashout id is required", "error", nil)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "cashout ID is required", nil, nil)
|
|
}
|
|
|
|
bet, err := h.transactionSvc.GetShopBetByCashoutID(c.Context(), cashoutID)
|
|
|
|
if err != nil {
|
|
h.logger.Error("CashoutReq failed invalid cashout id", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashout ID", err, nil)
|
|
}
|
|
|
|
res := domain.ConvertShopBetDetail(bet)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction created successfully", res, nil)
|
|
}
|
|
|
|
// DepositForCustomer godoc
|
|
// @Summary Shop deposit into customer wallet
|
|
// @Description Transfers money from branch wallet to customer wallet
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param transferToWallet body domain.ShopDepositReq true "ShopDepositReq"
|
|
// @Success 200 {object} TransferWalletRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/deposit [post]
|
|
func (h *Handler) DepositForCustomer(c *fiber.Ctx) error {
|
|
|
|
// Get sender ID from the cashier
|
|
userID := c.Locals("user_id").(int64)
|
|
role := c.Locals("role").(domain.Role)
|
|
|
|
var req domain.ShopDepositReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("CreateTransferReq failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
deposit, err := h.transactionSvc.CreateShopDeposit(c.Context(), userID, role, req)
|
|
|
|
if err != nil {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Failed to create shop deposit", err, nil)
|
|
}
|
|
|
|
res := domain.ConvertShopDeposit(deposit)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transfer Successful", res, nil)
|
|
|
|
}
|
|
|
|
// GetAllTransactions godoc
|
|
// @Summary Gets all transactions
|
|
// @Description Gets all the transactions
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/transaction [get]
|
|
func (h *Handler) GetAllTransactions(c *fiber.Ctx) error {
|
|
// Get user_id from middleware
|
|
// userID := c.Locals("user_id").(int64)
|
|
// role := c.Locals("role").(domain.Role)
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
branchID := c.Locals("branch_id").(domain.ValidInt64)
|
|
|
|
searchQuery := c.Query("query")
|
|
searchString := domain.ValidString{
|
|
Value: searchQuery,
|
|
Valid: searchQuery != "",
|
|
}
|
|
|
|
createdBeforeQuery := c.Query("created_before")
|
|
var createdBefore domain.ValidTime
|
|
if createdBeforeQuery != "" {
|
|
createdBeforeParsed, err := time.Parse(time.RFC3339, createdBeforeQuery)
|
|
if err != nil {
|
|
h.logger.Error("invalid start_time format", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
|
}
|
|
createdBefore = domain.ValidTime{
|
|
Value: createdBeforeParsed,
|
|
Valid: true,
|
|
}
|
|
}
|
|
|
|
createdAfterQuery := c.Query("created_after")
|
|
var createdAfter domain.ValidTime
|
|
if createdAfterQuery != "" {
|
|
createdAfterParsed, err := time.Parse(time.RFC3339, createdAfterQuery)
|
|
if err != nil {
|
|
h.logger.Error("invalid start_time format", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil)
|
|
}
|
|
createdAfter = domain.ValidTime{
|
|
Value: createdAfterParsed,
|
|
Valid: true,
|
|
}
|
|
}
|
|
|
|
// Check user role and fetch transactions accordingly
|
|
transactions, err := h.transactionSvc.GetAllShopTransactions(c.Context(), domain.ShopTransactionFilter{
|
|
CompanyID: companyID,
|
|
BranchID: branchID,
|
|
Query: searchString,
|
|
CreatedBefore: createdBefore,
|
|
CreatedAfter: createdAfter,
|
|
})
|
|
|
|
if err != nil {
|
|
h.logger.Error("Failed to get transactions", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve transactions", err, nil)
|
|
}
|
|
|
|
res := make([]domain.ShopTransactionRes, len(transactions))
|
|
for i, transaction := range transactions {
|
|
res[i] = domain.ConvertShopTransactionDetail(transaction)
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transactions retrieved successfully", res, nil)
|
|
|
|
}
|
|
|
|
// GetTransactionByID godoc
|
|
// @Summary Gets transaction by id
|
|
// @Description Gets a single transaction by id
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Transaction ID"
|
|
// @Success 200 {object} TransactionRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/transaction/{id} [get]
|
|
func (h *Handler) GetTransactionByID(c *fiber.Ctx) error {
|
|
transactionID := c.Params("id")
|
|
id, err := strconv.ParseInt(transactionID, 10, 64)
|
|
if err != nil {
|
|
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
|
}
|
|
|
|
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
|
if err != nil {
|
|
h.logger.Error("Failed to get transaction by ID", "transactionID", id, "error", err)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve transaction")
|
|
}
|
|
|
|
res := domain.ConvertShopTransactionDetail(transaction)
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction retrieved successfully", res, nil)
|
|
}
|
|
|
|
type UpdateTransactionVerifiedReq struct {
|
|
Verified bool `json:"verified" example:"true"`
|
|
}
|
|
|
|
// UpdateTransactionVerified godoc
|
|
// @Summary Updates the verified field of a transaction
|
|
// @Description Updates the verified status of a transaction
|
|
// @Tags transaction
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Transaction ID"
|
|
// @Param updateVerified body UpdateTransactionVerifiedReq true "Updates Transaction Verification"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /shop/transaction/{id} [put]
|
|
func (h *Handler) UpdateTransactionVerified(c *fiber.Ctx) error {
|
|
transactionID := c.Params("id")
|
|
userID := c.Locals("user_id").(int64)
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
role := c.Locals("role").(domain.Role)
|
|
|
|
id, err := strconv.ParseInt(transactionID, 10, 64)
|
|
if err != nil {
|
|
h.logger.Error("Invalid transaction ID", "transactionID", transactionID, "error", err)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid transaction ID")
|
|
}
|
|
|
|
var req UpdateTransactionVerifiedReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
|
|
h.logger.Info("Update Transaction Verified", slog.Bool("verified", req.Verified))
|
|
|
|
if valErrs, ok := h.validator.Validate(c, req); !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
|
|
transaction, err := h.transactionSvc.GetShopTransactionByID(c.Context(), id)
|
|
if role != domain.RoleSuperAdmin {
|
|
if !companyID.Valid || companyID.Value != transaction.CompanyID {
|
|
h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
|
|
}
|
|
}
|
|
|
|
user, err := h.userSvc.GetUserById(c.Context(), userID)
|
|
if err != nil {
|
|
h.logger.Error("Invalid user ID", "userID", userID, "error", err)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID")
|
|
}
|
|
err = h.transactionSvc.UpdateShopTransactionVerified(c.Context(), id, req.Verified, userID, user.FirstName+" "+user.LastName)
|
|
if err != nil {
|
|
h.logger.Error("Failed to update transaction verification", "transactionID", id, "error", err)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update transaction verification")
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Transaction updated successfully", nil, nil)
|
|
}
|