1064 lines
33 KiB
Go
1064 lines
33 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
|
"github.com/gofiber/fiber/v2"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// CreateBranch godoc
|
|
// @Summary Create a branch
|
|
// @Description Creates a branch
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createBranch body domain.CreateBranchReq true "Creates branch"
|
|
// @Success 200 {object} domain.BranchRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch [post]
|
|
func (h *Handler) CreateBranch(c *fiber.Ctx) error {
|
|
// Check if user is either branch manager / super main
|
|
// role := string(c.Locals("role").(domain.Role))
|
|
|
|
// if role != string(domain.RoleAdmin) && role != string(domain.RoleSuperAdmin) && role != string(domain.RoleBranchManager) {
|
|
// logger.Error("Unauthorized access", "role", role)
|
|
// return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil)
|
|
// }
|
|
|
|
role := c.Locals("role").(domain.Role)
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
|
|
var req domain.CreateBranchReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
// h.logger.Error("CreateBranchReq failed", "error", err)
|
|
h.mongoLoggerSvc.Info("CreateBranchReq failed",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
var errMsg string
|
|
for field, msg := range valErrs {
|
|
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
|
}
|
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
}
|
|
var IsSelfOwned bool
|
|
var checkedCompanyID int64
|
|
if role == domain.RoleSuperAdmin {
|
|
if req.IsSelfOwned == nil {
|
|
h.mongoLoggerSvc.Info("is_self_owned is required for super admin",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "is_self_owned is required for super admin")
|
|
}
|
|
if req.CompanyID == nil {
|
|
h.mongoLoggerSvc.Info("company_id is required for super admin",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "company_id is required for super admin")
|
|
}
|
|
IsSelfOwned = *req.IsSelfOwned
|
|
checkedCompanyID = *req.CompanyID
|
|
} else {
|
|
IsSelfOwned = false
|
|
checkedCompanyID = companyID.Value
|
|
}
|
|
|
|
// Create Branch Wallet
|
|
newWallet, err := h.walletSvc.CreateWallet(c.Context(), domain.CreateWallet{
|
|
IsWithdraw: false,
|
|
IsBettable: true,
|
|
IsTransferable: true,
|
|
UserID: req.BranchManagerID,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Create Branch Wallet failed",
|
|
zap.Int64("branch_manager_id", req.BranchManagerID),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
branch, err := h.branchSvc.CreateBranch(c.Context(), domain.CreateBranch{
|
|
Name: req.Name,
|
|
Location: req.Location,
|
|
WalletID: newWallet.ID,
|
|
BranchManagerID: req.BranchManagerID,
|
|
CompanyID: checkedCompanyID,
|
|
IsSelfOwned: IsSelfOwned,
|
|
ProfitPercentage: req.ProfitPercentage,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to create branch",
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
for _, operation := range req.Operations {
|
|
err := h.branchSvc.CreateBranchOperation(c.Context(), domain.CreateBranchOperation{
|
|
BranchID: branch.ID,
|
|
OperationID: operation,
|
|
})
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to create branch operations",
|
|
zap.Int64("branchID", branch.ID),
|
|
zap.Int64("operation", operation),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
}
|
|
|
|
res := domain.ConvertBranch(branch)
|
|
|
|
return response.WriteJSON(c, fiber.StatusCreated, "Branch Created", res, nil)
|
|
}
|
|
|
|
// CreateSupportedOperation godoc
|
|
// @Summary Create a supported operation
|
|
// @Description Creates a supported operation
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createSupportedOperation body domain.CreateSupportedOperationReq true "Creates supported operation"
|
|
// @Success 200 {object} domain.SupportedOperationRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/supportedOperation [post]
|
|
func (h *Handler) CreateSupportedOperation(c *fiber.Ctx) error {
|
|
var req domain.CreateSupportedOperationReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to parse CreateSupportedOperationReq",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
|
|
}
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
var errMsg string
|
|
for field, msg := range valErrs {
|
|
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
|
}
|
|
|
|
h.mongoLoggerSvc.Error("Failed to validate CreateSupportedOperationReq",
|
|
zap.Any("request", req),
|
|
zap.String("error", errMsg),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
}
|
|
operation, err := h.branchSvc.CreateSupportedOperation(c.Context(), domain.CreateSupportedOperation{
|
|
Name: req.Name,
|
|
Description: req.Description,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to create supported operation",
|
|
zap.String("name", req.Name),
|
|
zap.String("description", req.Description),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create supported operation")
|
|
}
|
|
|
|
res := domain.SupportedOperationRes{
|
|
Name: operation.Name,
|
|
Description: operation.Description,
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Operation Created", res, nil)
|
|
}
|
|
|
|
// CreateBranchOperation godoc
|
|
// @Summary Create a operation
|
|
// @Description Creates a operation
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param createBranchOperation body domain.CreateBranchOperationReq true "Creates operation"
|
|
// @Success 200 {object} domain.BranchOperationRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/operation [post]
|
|
func (h *Handler) CreateBranchOperation(c *fiber.Ctx) error {
|
|
var req domain.CreateBranchOperationReq
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("CreateBranchOperationReq failed", "error", err)
|
|
h.mongoLoggerSvc.Info("Failed to parse CreateBranchOperationReq",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
var errMsg string
|
|
for field, msg := range valErrs {
|
|
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
|
}
|
|
h.mongoLoggerSvc.Info("Failed to validated CreateBranchOperationReq",
|
|
zap.String("errMsg", errMsg),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
}
|
|
|
|
err := h.branchSvc.CreateBranchOperation(c.Context(), domain.CreateBranchOperation{
|
|
BranchID: req.BranchID,
|
|
OperationID: req.OperationID,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to create branch operation",
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Operation Created", nil, nil)
|
|
}
|
|
|
|
// GetBranchByID godoc
|
|
// @Summary Gets branch by id
|
|
// @Description Gets a single branch by id
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Success 200 {object} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id} [get]
|
|
func (h *Handler) GetBranchByID(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID",
|
|
zap.String("branch", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
branch, err := h.branchSvc.GetBranchByID(c.Context(), id)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to get branch by ID",
|
|
zap.Int64("branchID", id),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
res := domain.ConvertBranchDetail(branch)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch retrieved successfully", res, nil)
|
|
}
|
|
|
|
// GetBranchByManagerID godoc
|
|
// @Summary Gets branches by manager id
|
|
// @Description Gets a branches by manager id
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "User ID"
|
|
// @Success 200 {array} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/manager/{id}/branch [get]
|
|
func (h *Handler) GetBranchByManagerID(c *fiber.Ctx) error {
|
|
// TODO: Restrict any who isn't branch manager or higher
|
|
userID := c.Params("id")
|
|
id, err := strconv.ParseInt(userID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid user ID",
|
|
zap.String("userID", userID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID")
|
|
}
|
|
|
|
branches, err := h.branchSvc.GetBranchByManagerID(c.Context(), id)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to get branches",
|
|
zap.String("userID", userID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
|
}
|
|
var result []domain.BranchDetailRes = make([]domain.BranchDetailRes, 0, len(branches))
|
|
for _, branch := range branches {
|
|
result = append(result, domain.ConvertBranchDetail(branch))
|
|
}
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branches for Branch Manager retrieved", result, nil)
|
|
}
|
|
|
|
// GetBranchByCompanyID godoc
|
|
// @Summary Gets branches by company id
|
|
// @Description Gets branches by company id
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Company ID"
|
|
// @Success 200 {array} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/company/{id}/branch [get]
|
|
func (h *Handler) GetBranchByCompanyID(c *fiber.Ctx) error {
|
|
companyID := c.Params("id")
|
|
id, err := strconv.ParseInt(companyID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid company ID",
|
|
zap.String("companyID", companyID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid company ID")
|
|
}
|
|
|
|
branches, err := h.branchSvc.GetBranchByCompanyID(c.Context(), id)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to get branches",
|
|
zap.String("companyID", companyID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var result []domain.BranchDetailRes = make([]domain.BranchDetailRes, 0, len(branches))
|
|
for _, branch := range branches {
|
|
result = append(result, domain.ConvertBranchDetail(branch))
|
|
}
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branches for Company retrieved", result, nil)
|
|
}
|
|
|
|
// GetAllBranches godoc
|
|
// @Summary Gets all branches
|
|
// @Description Gets all branches
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch [get]
|
|
func (h *Handler) GetAllBranches(c *fiber.Ctx) error {
|
|
companyID := c.Locals("company_id").(domain.ValidInt64)
|
|
isActiveParam := c.Params("is_active")
|
|
isActiveValid := isActiveParam != ""
|
|
isActive, err := strconv.ParseBool(isActiveParam)
|
|
|
|
if isActiveValid && err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid is_active param",
|
|
zap.String("isActive", isActiveParam),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid is_active param")
|
|
}
|
|
|
|
branchManagerQuery := c.Query("branch_manager_id")
|
|
var branchManagerID domain.ValidInt64
|
|
if branchManagerQuery != "" {
|
|
parseManagerID, err := strconv.ParseInt(branchManagerQuery, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to parse branch_manager_id",
|
|
zap.String("userID", branchManagerQuery),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Failed to parse branch_manager_id")
|
|
}
|
|
branchManagerID = domain.ValidInt64{
|
|
Value: parseManagerID,
|
|
Valid: true,
|
|
}
|
|
}
|
|
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.mongoLoggerSvc.Info("invalid created_before format",
|
|
zap.String("createdBeforeQuery", createdBeforeQuery),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid created_before format")
|
|
}
|
|
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.mongoLoggerSvc.Info("invalid created_after format",
|
|
zap.String("createdAfterQuery", createdAfterQuery),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid created_after format")
|
|
}
|
|
createdAfter = domain.ValidTime{
|
|
Value: createdAfterParsed,
|
|
Valid: true,
|
|
}
|
|
}
|
|
|
|
branches, err := h.branchSvc.GetAllBranches(c.Context(),
|
|
domain.BranchFilter{
|
|
CompanyID: companyID,
|
|
IsActive: domain.ValidBool{
|
|
Value: isActive,
|
|
Valid: isActiveValid,
|
|
},
|
|
BranchManagerID: branchManagerID,
|
|
Query: searchString,
|
|
CreatedBefore: createdBefore,
|
|
CreatedAfter: createdAfter,
|
|
})
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to get branches",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var result []domain.BranchDetailRes = make([]domain.BranchDetailRes, 0, len(branches))
|
|
for _, branch := range branches {
|
|
result = append(result, domain.ConvertBranchDetail(branch))
|
|
}
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branches for Company retrieved", result, nil)
|
|
}
|
|
|
|
// SearchBranch godoc
|
|
// @Summary Search branches
|
|
// @Description Search branches by name or location
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param q query string true "Search query"
|
|
// @Success 200 {array} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/search/branch [get]
|
|
func (h *Handler) SearchBranch(c *fiber.Ctx) error {
|
|
// Get search query from request
|
|
searchQuery := c.Query("q")
|
|
if searchQuery == "" {
|
|
h.mongoLoggerSvc.Info("Search query is required",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Search query is required")
|
|
}
|
|
|
|
// Call the service to search for branches
|
|
branches, err := h.branchSvc.SearchBranchByName(c.Context(), searchQuery)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to search branches",
|
|
zap.String("query", searchQuery),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
// Convert branches to response format
|
|
var result []domain.BranchDetailRes
|
|
for _, branch := range branches {
|
|
result = append(result, domain.ConvertBranchDetail(branch))
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branches retrieved successfully", result, nil)
|
|
}
|
|
|
|
// GetAllSupportedOperations godoc
|
|
// @Summary Gets all supported operations
|
|
// @Description Gets all supported operations
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/supportedOperation [get]
|
|
func (h *Handler) GetAllSupportedOperations(c *fiber.Ctx) error {
|
|
operations, err := h.branchSvc.GetAllSupportedOperations(c.Context())
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get operations",
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var result []domain.SupportedOperationRes = make([]domain.SupportedOperationRes, 0, len(operations))
|
|
for _, operation := range operations {
|
|
result = append(result, domain.SupportedOperationRes{
|
|
ID: operation.ID,
|
|
Name: operation.Name,
|
|
Description: operation.Description,
|
|
})
|
|
}
|
|
return response.WriteJSON(c, fiber.StatusOK, "SupportedOperations for Company retrieved", result, nil)
|
|
|
|
}
|
|
|
|
// GetBranchOperations godoc
|
|
// @Summary Gets branch operations
|
|
// @Description Gets branch operations
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Success 200 {array} domain.BranchOperationRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id}/operation [get]
|
|
func (h *Handler) GetBranchOperations(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Invalid branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
operations, err := h.branchSvc.GetBranchOperations(c.Context(), id)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get operation by ID",
|
|
zap.Int64("branchID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var result []domain.BranchOperationRes = make([]domain.BranchOperationRes, 0, len(operations))
|
|
|
|
for _, branch := range operations {
|
|
result = append(result, domain.BranchOperationRes{
|
|
Name: branch.OperationName,
|
|
Description: branch.OperationDescription,
|
|
})
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Operations retrieved successfully", result, nil)
|
|
}
|
|
|
|
// GetAllBranchLocations godoc
|
|
// @Summary Gets all branch locations
|
|
// @Description Gets all branch locations
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} domain.BranchLocation
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branchLocation [get]
|
|
func (h *Handler) GetAllBranchLocations(c *fiber.Ctx) error {
|
|
|
|
searchQuery := c.Query("query")
|
|
searchString := domain.ValidString{
|
|
Value: searchQuery,
|
|
Valid: searchQuery != "",
|
|
}
|
|
|
|
locations, err := h.branchSvc.GetAllBranchLocations(c.Context(), searchString)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get branch locations",
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Location successfully fetched", locations, nil)
|
|
}
|
|
|
|
// GetBranchCashiers godoc
|
|
// @Summary Gets branch cashiers
|
|
// @Description Gets branch cashiers
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Success 200 {array} GetCashierRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id}/cashier [get]
|
|
func (h *Handler) GetBranchCashiers(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
cashiers, err := h.userSvc.GetCashiersByBranch(c.Context(), id)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get cashier by branch ID",
|
|
zap.Int64("branchID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var result []GetCashierRes = make([]GetCashierRes, 0, len(cashiers))
|
|
|
|
for _, cashier := range cashiers {
|
|
lastLogin, err := h.authSvc.GetLastLogin(c.Context(), cashier.ID)
|
|
if err != nil {
|
|
if err == authentication.ErrRefreshTokenNotFound {
|
|
lastLogin = &cashier.CreatedAt
|
|
} else {
|
|
h.mongoLoggerSvc.Error("Failed to get user last login",
|
|
zap.Int64("cashier ID", cashier.ID),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user last login")
|
|
}
|
|
}
|
|
result = append(result, GetCashierRes{
|
|
ID: cashier.ID,
|
|
FirstName: cashier.FirstName,
|
|
LastName: cashier.LastName,
|
|
Email: cashier.Email,
|
|
PhoneNumber: cashier.PhoneNumber,
|
|
Role: cashier.Role,
|
|
EmailVerified: cashier.EmailVerified,
|
|
PhoneVerified: cashier.PhoneVerified,
|
|
CreatedAt: cashier.CreatedAt,
|
|
UpdatedAt: cashier.UpdatedAt,
|
|
SuspendedAt: cashier.SuspendedAt,
|
|
Suspended: cashier.Suspended,
|
|
LastLogin: *lastLogin,
|
|
})
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Cashiers retrieved successfully", result, nil)
|
|
}
|
|
|
|
// GetBranchForCashier godoc
|
|
// @Summary Gets branch for cahier
|
|
// @Description Gets branch for cahier
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Success 200 {object} domain.BranchDetailRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branchCashier [get]
|
|
func (h *Handler) GetBranchForCashier(c *fiber.Ctx) error {
|
|
cashierID, ok := c.Locals("user_id").(int64)
|
|
|
|
if !ok {
|
|
h.mongoLoggerSvc.Error("Invalid cashier ID in context",
|
|
zap.Int64("cashierID", cashierID),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user_id")
|
|
}
|
|
|
|
role, ok := c.Locals("role").(domain.Role)
|
|
|
|
if !ok || role != domain.RoleCashier {
|
|
|
|
h.mongoLoggerSvc.Error("Unauthorized access",
|
|
zap.Int64("cashierID", cashierID),
|
|
zap.String("role", string(role)),
|
|
zap.Int("status_code", fiber.StatusForbidden),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusForbidden, "Unauthorized access")
|
|
}
|
|
|
|
branchID, ok := c.Locals("branch_id").(domain.ValidInt64)
|
|
if !ok || !branchID.Valid {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID in context",
|
|
zap.Int64("cashierID", cashierID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
branch, err := h.branchSvc.GetBranchByID(c.Context(), branchID.Value)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get branch by ID",
|
|
zap.Int64("branchID", branchID.Value),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
res := domain.ConvertBranchDetail(branch)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch retrieved successfully", res, nil)
|
|
}
|
|
|
|
// GetBetByBranchID godoc
|
|
// @Summary Gets bets by its branch id
|
|
// @Description Gets bets by its branch id
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {array} domain.BetRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id}/bets [get]
|
|
func (h *Handler) GetBetByBranchID(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
bets, err := h.transactionSvc.GetAllShopBet(c.Context(), domain.ShopBetFilter{
|
|
BranchID: domain.ValidInt64{
|
|
Value: id,
|
|
Valid: true,
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to get bets",
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
var res []domain.ShopBetRes = make([]domain.ShopBetRes, 0, len(bets))
|
|
for _, bet := range bets {
|
|
res = append(res, domain.ConvertShopBetDetail(bet))
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Bets Retrieved", res, nil)
|
|
}
|
|
|
|
// UpdateBranch godoc
|
|
// @Summary Updates a branch
|
|
// @Description Updates a branch
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Param updateBranch body domain.CreateBranchReq true "Update Branch"
|
|
// @Success 200 {object} domain.BranchRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id} [put]
|
|
func (h *Handler) UpdateBranch(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch ID")
|
|
}
|
|
|
|
var req domain.UpdateBranchReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.mongoLoggerSvc.Info("Failed to parse CreateBranchReq",
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
|
|
}
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
if !ok {
|
|
var errMsg string
|
|
for field, msg := range valErrs {
|
|
errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
|
}
|
|
h.mongoLoggerSvc.Info("Failed to validate UpdateBranchReq",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.String("errMsg", errMsg),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
}
|
|
|
|
branch, err := h.branchSvc.UpdateBranch(c.Context(), domain.UpdateBranch{
|
|
ID: id,
|
|
Name: req.Name,
|
|
Location: req.Location,
|
|
BranchManagerID: req.BranchManagerID,
|
|
CompanyID: req.CompanyID,
|
|
IsSelfOwned: req.IsSelfOwned,
|
|
IsActive: req.IsActive,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to update branch",
|
|
zap.Int64("branchID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
res := domain.ConvertBranch(branch)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Updated", res, nil)
|
|
|
|
}
|
|
|
|
func (h *Handler) UpdateBranchStatus(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
|
}
|
|
|
|
var isActive bool
|
|
path := strings.Split(strings.Trim(c.Path(), "/"), "/")
|
|
|
|
if path[len(path)-1] == "set-active" {
|
|
isActive = true
|
|
} else if path[len(path)-1] == "set-inactive" {
|
|
isActive = false
|
|
} else {
|
|
h.mongoLoggerSvc.Info("Invalid branch status",
|
|
zap.Bool("status", isActive),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid branch status")
|
|
}
|
|
|
|
branch, err := h.branchSvc.UpdateBranch(c.Context(), domain.UpdateBranch{
|
|
ID: id,
|
|
IsActive: &isActive,
|
|
})
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to update branch",
|
|
zap.Int64("branchID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
res := domain.ConvertBranch(branch)
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Updated", res, nil)
|
|
|
|
}
|
|
|
|
// DeleteBranch godoc
|
|
// @Summary Delete the branch
|
|
// @Description Delete the branch
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID""
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id} [delete]
|
|
func (h *Handler) DeleteBranch(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Info("Invalid Branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Branch ID")
|
|
}
|
|
|
|
err = h.branchSvc.DeleteBranch(c.Context(), id)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to delete by ID",
|
|
zap.Int64("Branch ID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch removed successfully", nil, nil)
|
|
}
|
|
|
|
// DeleteBranchOperation godoc
|
|
// @Summary Delete the branch operation
|
|
// @Description Delete the branch operation
|
|
// @Tags branch
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "Branch ID"
|
|
// @Param opID path int true "Branch Operation ID"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/branch/{id}/operation/{opID} [delete]
|
|
func (h *Handler) DeleteBranchOperation(c *fiber.Ctx) error {
|
|
branchID := c.Params("id")
|
|
opID := c.Params("opID")
|
|
|
|
id, err := strconv.ParseInt(branchID, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
h.mongoLoggerSvc.Error("Invalid Branch ID",
|
|
zap.String("branchID", branchID),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Branch ID")
|
|
}
|
|
|
|
operationID, err := strconv.ParseInt(opID, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
h.mongoLoggerSvc.Info("Invalid Operation ID",
|
|
zap.String("operationID", opID),
|
|
zap.Int("status_code", fiber.StatusBadRequest),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid Operation ID")
|
|
}
|
|
|
|
err = h.branchSvc.DeleteBranchOperation(c.Context(), id, operationID)
|
|
|
|
if err != nil {
|
|
h.mongoLoggerSvc.Error("Failed to delete operation",
|
|
zap.Int64("Branch ID", id),
|
|
zap.Int("status_code", fiber.StatusInternalServerError),
|
|
zap.Error(err),
|
|
zap.Time("timestamp", time.Now()),
|
|
)
|
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
}
|
|
|
|
return response.WriteJSON(c, fiber.StatusOK, "Branch Operation removed successfully", nil, nil)
|
|
|
|
}
|