add app setting letter out
This commit is contained in:
@@ -26,161 +26,241 @@ type LetterService interface {
|
||||
UpdateDiscussion(ctx context.Context, letterID uuid.UUID, discussionID uuid.UUID, req *contract.UpdateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error)
|
||||
}
|
||||
|
||||
type LetterHandler struct{ svc LetterService }
|
||||
type LetterHandler struct {
|
||||
svc LetterService
|
||||
}
|
||||
|
||||
func NewLetterHandler(svc LetterService) *LetterHandler { return &LetterHandler{svc: svc} }
|
||||
func NewLetterHandler(svc LetterService) *LetterHandler {
|
||||
return &LetterHandler{svc: svc}
|
||||
}
|
||||
|
||||
// Helper functions for common patterns
|
||||
func (h *LetterHandler) parseUUID(c *gin.Context, param string) (uuid.UUID, bool) {
|
||||
id, err := uuid.Parse(c.Param(param))
|
||||
if err != nil {
|
||||
h.respondError(c, http.StatusBadRequest, "invalid "+param)
|
||||
return uuid.Nil, false
|
||||
}
|
||||
return id, true
|
||||
}
|
||||
|
||||
func (h *LetterHandler) bindJSON(c *gin.Context, req interface{}) bool {
|
||||
if err := c.ShouldBindJSON(req); err != nil {
|
||||
h.respondError(c, http.StatusBadRequest, "invalid request body")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *LetterHandler) bindQuery(c *gin.Context, req interface{}) bool {
|
||||
if err := c.ShouldBindQuery(req); err != nil {
|
||||
h.respondError(c, http.StatusBadRequest, "invalid query parameters")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *LetterHandler) respondError(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, &contract.ErrorResponse{
|
||||
Error: message,
|
||||
Code: code,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *LetterHandler) respondSuccess(c *gin.Context, code int, data interface{}) {
|
||||
c.JSON(code, contract.BuildSuccessResponse(data))
|
||||
}
|
||||
|
||||
func (h *LetterHandler) handleServiceError(c *gin.Context, err error) {
|
||||
if err != nil {
|
||||
h.respondError(c, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (h *LetterHandler) CreateIncomingLetter(c *gin.Context) {
|
||||
var req contract.CreateIncomingLetterRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "invalid body", Code: http.StatusBadRequest})
|
||||
if !h.bindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.CreateIncomingLetter(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusCreated, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) GetIncomingLetter(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
|
||||
id, ok := h.parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.GetIncomingLetterByID(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) ListIncomingLetters(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
status := c.Query("status")
|
||||
query := c.Query("q")
|
||||
var statusPtr *string
|
||||
var queryPtr *string
|
||||
if status != "" {
|
||||
statusPtr = &status
|
||||
}
|
||||
if query != "" {
|
||||
queryPtr = &query
|
||||
}
|
||||
req := &contract.ListIncomingLettersRequest{Page: page, Limit: limit, Status: statusPtr, Query: queryPtr}
|
||||
req := h.parseListRequest(c)
|
||||
|
||||
resp, err := h.svc.ListIncomingLetters(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) parseListRequest(c *gin.Context) *contract.ListIncomingLettersRequest {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
|
||||
// Ensure valid pagination values
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if limit < 1 {
|
||||
limit = 10
|
||||
}
|
||||
if limit > 100 {
|
||||
limit = 100
|
||||
}
|
||||
|
||||
req := &contract.ListIncomingLettersRequest{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
// Handle optional query parameters
|
||||
if status := c.Query("status"); status != "" {
|
||||
req.Status = &status
|
||||
}
|
||||
if query := c.Query("q"); query != "" {
|
||||
req.Query = &query
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
func (h *LetterHandler) UpdateIncomingLetter(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
|
||||
id, ok := h.parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req contract.UpdateIncomingLetterRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
||||
if !h.bindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.UpdateIncomingLetter(c.Request.Context(), id, &req)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) DeleteIncomingLetter(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
|
||||
id, ok := h.parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.SoftDeleteIncomingLetter(c.Request.Context(), id); err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, &contract.SuccessResponse{Message: "deleted"})
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, &contract.SuccessResponse{
|
||||
Message: "Letter deleted successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func (h *LetterHandler) CreateDispositions(c *gin.Context) {
|
||||
appCtx := appcontext.FromGinContext(c.Request.Context())
|
||||
var req contract.CreateLetterDispositionRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
||||
if !h.bindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract department ID from context
|
||||
appCtx := appcontext.FromGinContext(c.Request.Context())
|
||||
req.FromDepartment = appCtx.DepartmentID
|
||||
|
||||
resp, err := h.svc.CreateDispositions(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusCreated, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) GetEnhancedDispositionsByLetter(c *gin.Context) {
|
||||
letterID, err := uuid.Parse(c.Param("letter_id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid letter_id", Code: 400})
|
||||
letterID, ok := h.parseUUID(c, "letter_id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.GetEnhancedDispositionsByLetter(c.Request.Context(), letterID)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) CreateDiscussion(c *gin.Context) {
|
||||
letterID, err := uuid.Parse(c.Param("letter_id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid letter_id", Code: 400})
|
||||
letterID, ok := h.parseUUID(c, "letter_id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req contract.CreateLetterDiscussionRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
||||
if !h.bindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.CreateDiscussion(c.Request.Context(), letterID, &req)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusCreated, resp)
|
||||
}
|
||||
|
||||
func (h *LetterHandler) UpdateDiscussion(c *gin.Context) {
|
||||
letterID, err := uuid.Parse(c.Param("letter_id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid letter_id", Code: 400})
|
||||
letterID, ok := h.parseUUID(c, "letter_id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
discussionID, err := uuid.Parse(c.Param("discussion_id"))
|
||||
if err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid discussion_id", Code: 400})
|
||||
|
||||
discussionID, ok := h.parseUUID(c, "discussion_id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req contract.UpdateLetterDiscussionRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
||||
if !h.bindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.UpdateDiscussion(c.Request.Context(), letterID, discussionID, &req)
|
||||
if err != nil {
|
||||
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
h.handleServiceError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
|
||||
h.respondSuccess(c, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ type MasterService interface {
|
||||
UpdateDispositionAction(ctx context.Context, id uuid.UUID, req *contract.UpdateDispositionActionRequest) (*contract.DispositionActionResponse, error)
|
||||
DeleteDispositionAction(ctx context.Context, id uuid.UUID) error
|
||||
ListDispositionActions(ctx context.Context) (*contract.ListDispositionActionsResponse, error)
|
||||
|
||||
ListDepartments(ctx context.Context, req *contract.ListDepartmentsRequest) (*contract.ListDepartmentsResponse, error)
|
||||
}
|
||||
|
||||
type MasterHandler struct{ svc MasterService }
|
||||
@@ -256,3 +258,21 @@ func (h *MasterHandler) ListDispositionActions(c *gin.Context) {
|
||||
}
|
||||
c.JSON(200, contract.BuildSuccessResponse(resp))
|
||||
}
|
||||
|
||||
// Departments
|
||||
func (h *MasterHandler) ListDepartments(c *gin.Context) {
|
||||
var req contract.ListDepartmentsRequest
|
||||
|
||||
// Parse query parameters
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "invalid query parameters", Code: 400})
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.svc.ListDepartments(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, contract.BuildSuccessResponse(resp))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user