456 lines
16 KiB
Go
456 lines
16 KiB
Go
package handlers
|
|
|
|
import (
|
|
"Yimaru-Backend/internal/domain"
|
|
"Yimaru-Backend/internal/web_server/response"
|
|
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type CreateManagerReq struct {
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
Email string `json:"email" example:"john.doe@example.com"`
|
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
|
Password string `json:"password" example:"password123"`
|
|
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
|
|
}
|
|
|
|
// CreateManager godoc
|
|
// @Summary Create Manager
|
|
// @Description Create Manager
|
|
// @Tags manager
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param manger body CreateManagerReq true "Create manager"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/managers [post]
|
|
// func (h *Handler) CreateManager(c *fiber.Ctx) error {
|
|
|
|
// // Get user_id from middleware
|
|
|
|
// var req CreateManagerReq
|
|
// if err := c.BodyParser(&req); err != nil {
|
|
// h.logger.Error("RegisterUser failed", "error", err)
|
|
// h.mongoLoggerSvc.Info("CreateManager failed to create manager",
|
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusBadRequest, "Invalid request body:"+err.Error())
|
|
// }
|
|
// 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 CreateManager",
|
|
// zap.Any("request", req),
|
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
|
// zap.String("errMsg", errMsg),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
// }
|
|
|
|
// var companyID domain.ValidInt64
|
|
// role := c.Locals("role").(domain.Role)
|
|
// if role == domain.RoleSuperAdmin {
|
|
// if req.CompanyID == nil {
|
|
// h.logger.Error("RegisterUser failed error: company id is required")
|
|
// h.mongoLoggerSvc.Info("RegisterUser failed error: company id is required",
|
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusBadRequest, "Company ID is required for super-admin")
|
|
// }
|
|
// companyID = domain.ValidInt64{
|
|
// Value: *req.CompanyID,
|
|
// Valid: true,
|
|
// }
|
|
// } else {
|
|
// companyID = c.Locals("company_id").(domain.ValidInt64)
|
|
// }
|
|
|
|
// user := domain.CreateUserReq{
|
|
// FirstName: req.FirstName,
|
|
// LastName: req.LastName,
|
|
// Email: req.Email,
|
|
// PhoneNumber: req.PhoneNumber,
|
|
// Password: req.Password,
|
|
// Role: string(domain.RoleBranchManager),
|
|
// OrganizationID: companyID,
|
|
// }
|
|
// _, err := h.userSvc.CreateUser(c.Context(), user, true)
|
|
// if err != nil {
|
|
// h.mongoLoggerSvc.Error("CreateManager failed to create manager",
|
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusInternalServerError, "Failed to create manager:"+err.Error())
|
|
// }
|
|
// return response.WriteJSON(c, fiber.StatusOK, "Manager created successfully", nil, nil)
|
|
|
|
// }
|
|
|
|
type ManagersRes struct {
|
|
ID int64 `json:"id"`
|
|
FirstName string `json:"first_name"`
|
|
LastName string `json:"last_name"`
|
|
Email string `json:"email"`
|
|
PhoneNumber string `json:"phone_number"`
|
|
Role domain.Role `json:"role"`
|
|
EmailVerified bool `json:"email_verified"`
|
|
PhoneVerified bool `json:"phone_verified"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
LastLogin time.Time `json:"last_login"`
|
|
SuspendedAt time.Time `json:"suspended_at"`
|
|
Suspended bool `json:"suspended"`
|
|
}
|
|
|
|
// GetAllManagers godoc
|
|
// @Summary Get all Managers
|
|
// @Description Get all Managers
|
|
// @Tags manager
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param page query int false "Page number"
|
|
// @Param page_size query int false "Page size"
|
|
// @Success 200 {object} ManagersRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/managers [get]
|
|
// func (h *Handler) GetAllManagers(c *fiber.Ctx) error {
|
|
// role := c.Locals("role").(domain.Role)
|
|
// companyId := c.Locals("company_id").(domain.ValidInt64)
|
|
|
|
// // Checking to make sure that admin user has a company id in the token
|
|
// if role != domain.RoleSuperAdmin && !companyId.Valid {
|
|
// h.mongoLoggerSvc.Error("Cannot get company ID from context",
|
|
// zap.String("role", string(role)),
|
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID from context")
|
|
// }
|
|
|
|
// 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("created_before", 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("created_after", 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,
|
|
// }
|
|
// }
|
|
|
|
// filter := domain.UserFilter{
|
|
// Role: string(domain.RoleBranchManager),
|
|
// OrganizationID: companyId,
|
|
// Page: domain.ValidInt{
|
|
// Value: c.QueryInt("page", 1) - 1,
|
|
// Valid: true,
|
|
// },
|
|
// PageSize: domain.ValidInt{
|
|
// Value: c.QueryInt("page_size", 10),
|
|
// Valid: true,
|
|
// },
|
|
// Query: searchString,
|
|
// CreatedBefore: createdBefore,
|
|
// CreatedAfter: createdAfter,
|
|
// }
|
|
// valErrs, ok := h.validator.Validate(c, filter)
|
|
// if !ok {
|
|
// var errMsg string
|
|
// for field, msg := range valErrs {
|
|
// errMsg += fmt.Sprintf("%s: %s; ", field, msg)
|
|
// }
|
|
// h.mongoLoggerSvc.Info("Failed to validate get all filters",
|
|
// zap.Any("filter", filter),
|
|
// zap.Int("status_code", fiber.StatusBadRequest),
|
|
// zap.String("errMsg", errMsg),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusBadRequest, errMsg)
|
|
// }
|
|
// managers, total, err := h.userSvc.GetAllUsers(c.Context(), filter)
|
|
// if err != nil {
|
|
// h.logger.Error("GetAllManagers failed", "error", err)
|
|
// h.mongoLoggerSvc.Error("GetAllManagers failed to get all managers",
|
|
// zap.Any("filter", filter),
|
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusInternalServerError, "Failed to get Managers"+err.Error())
|
|
// }
|
|
|
|
// var result []ManagersRes = make([]ManagersRes, len(managers))
|
|
// for index, manager := range managers {
|
|
// lastLogin, err := h.authSvc.GetLastLogin(c.Context(), manager.ID)
|
|
// if err != nil {
|
|
// if err == authentication.ErrRefreshTokenNotFound {
|
|
// lastLogin = &manager.CreatedAt
|
|
// } else {
|
|
// h.mongoLoggerSvc.Error("Failed to get user last login",
|
|
// zap.Int64("userID", manager.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:"+err.Error())
|
|
// }
|
|
// }
|
|
// result[index] = ManagersRes{
|
|
// ID: manager.ID,
|
|
// FirstName: manager.FirstName,
|
|
// LastName: manager.LastName,
|
|
// Email: manager.Email,
|
|
// PhoneNumber: manager.PhoneNumber,
|
|
// Role: manager.Role,
|
|
// EmailVerified: manager.EmailVerified,
|
|
// PhoneVerified: manager.PhoneVerified,
|
|
// CreatedAt: manager.CreatedAt,
|
|
// UpdatedAt: manager.UpdatedAt,
|
|
// SuspendedAt: manager.SuspendedAt,
|
|
// Suspended: manager.Suspended,
|
|
// LastLogin: *lastLogin,
|
|
// }
|
|
// }
|
|
|
|
// return response.WritePaginatedJSON(c, fiber.StatusOK, "Managers retrieved successfully", result, nil, filter.Page.Value, int(total))
|
|
|
|
// }
|
|
|
|
// GetManagerByID godoc
|
|
// @Summary Get manager by id
|
|
// @Description Get a single manager by id
|
|
// @Tags manager
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "User ID"
|
|
// @Success 200 {object} ManagersRes
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/managers/{id} [get]
|
|
// func (h *Handler) GetManagerByID(c *fiber.Ctx) error {
|
|
// role := c.Locals("role").(domain.Role)
|
|
// companyId := c.Locals("company_id").(domain.ValidInt64)
|
|
// requestUserID := c.Locals("user_id").(int64)
|
|
|
|
// // Only Super Admin / Admin / Branch Manager can view this route
|
|
// if role != domain.RoleSuperAdmin && role != domain.RoleAdmin && role != domain.RoleBranchManager {
|
|
// h.mongoLoggerSvc.Warn("Attempt to access from unauthorized role",
|
|
// zap.Int64("userID", requestUserID),
|
|
// zap.String("role", string(role)),
|
|
// zap.Int("status_code", fiber.StatusForbidden),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusForbidden, "This role cannot view this route")
|
|
// }
|
|
|
|
// if role != domain.RoleSuperAdmin && !companyId.Valid {
|
|
// h.mongoLoggerSvc.Error("Cannot get company ID in context",
|
|
// zap.String("role", string(role)),
|
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusInternalServerError, "Cannot get company ID in context")
|
|
// }
|
|
|
|
// userIDstr := c.Params("id")
|
|
// userID, err := strconv.ParseInt(userIDstr, 10, 64)
|
|
// if err != nil {
|
|
// return fiber.NewError(fiber.StatusBadRequest, "Invalid managers ID")
|
|
// }
|
|
|
|
// user, err := h.userSvc.GetUserByID(c.Context(), userID)
|
|
// if err != nil {
|
|
// h.mongoLoggerSvc.Error("Failed to get manager by id",
|
|
// zap.Int64("userID", userID),
|
|
// zap.Int("status_code", fiber.StatusInternalServerError),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusInternalServerError, "Failed to get managers:"+err.Error())
|
|
// }
|
|
|
|
// // A Branch Manager can only fetch his own branch info
|
|
// if role == domain.RoleBranchManager && user.ID != requestUserID {
|
|
// h.mongoLoggerSvc.Warn("Attempt to access another branch manager info",
|
|
// zap.String("userID", userIDstr),
|
|
// zap.Int("status_code", fiber.StatusForbidden),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusForbidden, "User Access Not Allowed")
|
|
// }
|
|
|
|
// // Check that only admin from company can view this route
|
|
// if role != domain.RoleSuperAdmin && user.OrganizationID.Value != companyId.Value {
|
|
// h.mongoLoggerSvc.Warn("Attempt to access info from another company",
|
|
// zap.String("userID", userIDstr),
|
|
// zap.Int("status_code", fiber.StatusForbidden),
|
|
// zap.Error(err),
|
|
// zap.Time("timestamp", time.Now()),
|
|
// )
|
|
// return fiber.NewError(fiber.StatusForbidden, "Cannot access another company information")
|
|
// }
|
|
|
|
// lastLogin, err := h.authSvc.GetLastLogin(c.Context(), user.ID)
|
|
// if err != nil {
|
|
// if err != authentication.ErrRefreshTokenNotFound {
|
|
// h.mongoLoggerSvc.Error("Failed to get user last login",
|
|
// zap.Int64("userID", userID),
|
|
// 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"+err.Error())
|
|
// }
|
|
|
|
// lastLogin = &user.CreatedAt
|
|
// }
|
|
|
|
// res := ManagersRes{
|
|
// ID: user.ID,
|
|
// FirstName: user.FirstName,
|
|
// LastName: user.LastName,
|
|
// Email: user.Email,
|
|
// PhoneNumber: user.PhoneNumber,
|
|
// Role: user.Role,
|
|
// EmailVerified: user.EmailVerified,
|
|
// PhoneVerified: user.PhoneVerified,
|
|
// CreatedAt: user.CreatedAt,
|
|
// UpdatedAt: user.UpdatedAt,
|
|
// SuspendedAt: user.SuspendedAt,
|
|
// Suspended: user.Suspended,
|
|
// LastLogin: *lastLogin,
|
|
// }
|
|
|
|
// return response.WriteJSON(c, fiber.StatusOK, "User retrieved successfully", res, nil)
|
|
// }
|
|
|
|
type updateManagerReq struct {
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
Suspended bool `json:"suspended" example:"false"`
|
|
CompanyID *int64 `json:"company_id,omitempty" example:"1"`
|
|
}
|
|
|
|
// UpdateManagers godoc
|
|
// @Summary Update Managers
|
|
// @Description Update Managers
|
|
// @Tags manager
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param Managers body updateManagerReq true "Update Managers"
|
|
// @Success 200 {object} response.APIResponse
|
|
// @Failure 400 {object} response.APIResponse
|
|
// @Failure 401 {object} response.APIResponse
|
|
// @Failure 500 {object} response.APIResponse
|
|
// @Router /api/v1/managers/{id} [put]
|
|
func (h *Handler) UpdateManagers(c *fiber.Ctx) error {
|
|
|
|
var req updateManagerReq
|
|
|
|
if err := c.BodyParser(&req); err != nil {
|
|
h.logger.Error("UpdateManagers failed", "error", err)
|
|
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
|
|
}
|
|
|
|
valErrs, ok := h.validator.Validate(c, req)
|
|
|
|
if !ok {
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
|
}
|
|
ManagersIdStr := c.Params("id")
|
|
ManagersId, err := strconv.ParseInt(ManagersIdStr, 10, 64)
|
|
if err != nil {
|
|
h.logger.Error("UpdateManagers failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Managers ID", nil, nil)
|
|
}
|
|
var companyID domain.ValidInt64
|
|
role := c.Locals("role").(domain.Role)
|
|
if req.CompanyID != nil {
|
|
if role != domain.RoleSuperAdmin {
|
|
h.logger.Error("UpdateManagers failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusUnauthorized, "This user role cannot modify company ID", nil, nil)
|
|
}
|
|
companyID = domain.ValidInt64{
|
|
Value: *req.CompanyID,
|
|
Valid: true,
|
|
}
|
|
}
|
|
|
|
err = h.userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
|
|
UserID: ManagersId,
|
|
FirstName: domain.ValidString{
|
|
Value: req.FirstName,
|
|
Valid: req.FirstName != "",
|
|
},
|
|
LastName: domain.ValidString{
|
|
Value: req.LastName,
|
|
Valid: req.LastName != "",
|
|
},
|
|
Suspended: domain.ValidBool{
|
|
Value: req.Suspended,
|
|
Valid: true,
|
|
},
|
|
OrganizationID: companyID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
h.logger.Error("UpdateManagers failed", "error", err)
|
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Managers", nil, nil)
|
|
}
|
|
return response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil)
|
|
|
|
}
|