Yimaru-BackEnd/internal/web_server/handlers/direct_deposit.go

268 lines
9.1 KiB
Go

package handlers
import (
"fmt"
"math"
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/gofiber/fiber/v2"
)
// CreateDirectDeposit godoc
// @Summary Create a new direct deposit
// @Description Creates a direct deposit for a customer and notifies both the customer and admins
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param body body domain.CreateDirectDeposit true "Direct deposit details"
// @Success 200 {object} domain.Response{data=domain.DirectDeposit}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits [post]
func (h *Handler) CreateDirectDeposit(c *fiber.Ctx) error {
var req domain.CreateDirectDeposit
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid request payload",
Error: err.Error(),
})
}
// Call service
deposit, err := h.directDepositSvc.CreateDirectDeposit(c.Context(), req)
if err != nil {
// h.logger.Error("CreateDirectDeposit error", err.Error())
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to create direct deposit",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: "Direct deposit created successfully",
Data: deposit,
StatusCode: fiber.StatusOK,
Success: true,
})
}
// GetDirectDepositsByStatus godoc
// @Summary Get direct deposits by status
// @Description Fetches direct deposits filtered by status with pagination
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param status query string true "Deposit status (e.g., PENDING, APPROVED, REJECTED)"
// @Param page query int false "Page number"
// @Param pageSize query int false "Page size"
// @Success 200 {object} domain.Response{data=[]domain.DirectDeposit}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits [get]
func (h *Handler) GetDirectDepositsByStatus(c *fiber.Ctx) error {
status := c.Query("status")
if status == "" {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "status query parameter is required",
})
}
page, _ := strconv.Atoi(c.Query("page", "1"))
pageSize, _ := strconv.Atoi(c.Query("pageSize", "50"))
deposits, total, err := h.directDepositSvc.GetDirectDepositsByStatus(c.Context(), status, page, pageSize)
if err != nil {
// h.logger.Error("GetDirectDepositsByStatus error", err)
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to fetch direct deposits",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: fmt.Sprintf("Direct deposits with status '%s' fetched successfully", status),
Data: deposits,
StatusCode: fiber.StatusOK,
Success: true,
// Optional: include pagination info
MetaData: map[string]any{
"page": page,
"pageSize": pageSize,
"total": total,
"totalPage": int(math.Ceil(float64(total) / float64(pageSize))),
},
})
}
// ApproveDirectDeposit godoc
// @Summary Approve a direct deposit
// @Description Approves a direct deposit by admin and credits customer wallet
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param depositID path int true "Deposit ID"
// @Param adminID query int true "Admin ID performing the approval"
// @Success 200 {object} domain.Response{data=string}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits/{depositID}/approve [post]
func (h *Handler) ApproveDirectDeposit(c *fiber.Ctx) error {
depositID, err := strconv.Atoi(c.Params("depositID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid deposit ID",
Error: err.Error(),
})
}
adminID, err := strconv.Atoi(c.Query("adminID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid admin ID",
Error: err.Error(),
})
}
if err := h.directDepositSvc.ApproveDirectDeposit(c.Context(), depositID, adminID); err != nil {
// h.logger.Error("ApproveDirectDeposit error", err)
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to approve direct deposit",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: fmt.Sprintf("Direct deposit #%d approved successfully", depositID),
Data: fmt.Sprintf("Deposit #%d approved", depositID),
StatusCode: fiber.StatusOK,
Success: true,
})
}
// RejectDirectDeposit godoc
// @Summary Reject a direct deposit
// @Description Rejects a direct deposit by admin and notifies the customer
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param depositID path int true "Deposit ID"
// @Param adminID query int true "Admin ID performing the rejection"
// @Param reason query string true "Reason for rejection"
// @Success 200 {object} domain.Response{data=string}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits/{depositID}/reject [post]
func (h *Handler) RejectDirectDeposit(c *fiber.Ctx) error {
depositID, err := strconv.Atoi(c.Params("depositID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid deposit ID",
Error: err.Error(),
})
}
adminID, err := strconv.Atoi(c.Query("adminID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid admin ID",
Error: err.Error(),
})
}
reason := c.Query("reason")
if reason == "" {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Rejection reason is required",
})
}
if err := h.directDepositSvc.RejectDirectDeposit(c.Context(), depositID, adminID, reason); err != nil {
// h.logger.Error("RejectDirectDeposit error", err)
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to reject direct deposit",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: fmt.Sprintf("Direct deposit #%d rejected successfully", depositID),
Data: fmt.Sprintf("Deposit #%d rejected", depositID),
StatusCode: fiber.StatusOK,
Success: true,
})
}
// GetDirectDepositByID godoc
// @Summary Get a direct deposit by ID
// @Description Fetches a single direct deposit by its ID
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param depositID path int true "Deposit ID"
// @Success 200 {object} domain.Response{data=domain.DirectDeposit}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits/{depositID} [get]
func (h *Handler) GetDirectDepositByID(c *fiber.Ctx) error {
depositID, err := strconv.Atoi(c.Params("depositID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid deposit ID",
Error: err.Error(),
})
}
deposit, err := h.directDepositSvc.GetDirectDepositByID(c.Context(), depositID)
if err != nil {
// h.logger.Error("GetDirectDepositByID error", err)
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to fetch direct deposit",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: fmt.Sprintf("Direct deposit #%d fetched successfully", depositID),
Data: deposit,
StatusCode: fiber.StatusOK,
Success: true,
})
}
// DeleteDirectDeposit godoc
// @Summary Delete a direct deposit
// @Description Deletes a direct deposit by its ID
// @Tags DirectDeposit
// @Accept json
// @Produce json
// @Param depositID path int true "Deposit ID"
// @Success 200 {object} domain.Response{data=string}
// @Failure 400 {object} domain.ErrorResponse
// @Failure 502 {object} domain.ErrorResponse
// @Router /api/v1/direct-deposits/{depositID} [delete]
func (h *Handler) DeleteDirectDeposit(c *fiber.Ctx) error {
depositID, err := strconv.Atoi(c.Params("depositID"))
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Invalid deposit ID",
Error: err.Error(),
})
}
if err := h.directDepositSvc.DeleteDirectDeposit(c.Context(), depositID); err != nil {
// h.logger.Error("DeleteDirectDeposit error", err)
return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{
Message: "Failed to delete direct deposit",
Error: err.Error(),
})
}
return c.Status(fiber.StatusOK).JSON(domain.Response{
Message: fmt.Sprintf("Direct deposit #%d deleted successfully", depositID),
Data: fmt.Sprintf("Deposit #%d deleted", depositID),
StatusCode: fiber.StatusOK,
Success: true,
})
}