2025-08-09 18:58:22 +07:00
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2025-08-15 21:17:19 +07:00
|
|
|
"eslogad-be/internal/appcontext"
|
2025-08-09 18:58:22 +07:00
|
|
|
"net/http"
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"eslogad-be/internal/contract"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type LetterService interface {
|
|
|
|
|
CreateIncomingLetter(ctx context.Context, req *contract.CreateIncomingLetterRequest) (*contract.IncomingLetterResponse, error)
|
|
|
|
|
GetIncomingLetterByID(ctx context.Context, id uuid.UUID) (*contract.IncomingLetterResponse, error)
|
|
|
|
|
ListIncomingLetters(ctx context.Context, req *contract.ListIncomingLettersRequest) (*contract.ListIncomingLettersResponse, error)
|
|
|
|
|
UpdateIncomingLetter(ctx context.Context, id uuid.UUID, req *contract.UpdateIncomingLetterRequest) (*contract.IncomingLetterResponse, error)
|
|
|
|
|
SoftDeleteIncomingLetter(ctx context.Context, id uuid.UUID) error
|
|
|
|
|
|
|
|
|
|
CreateDispositions(ctx context.Context, req *contract.CreateLetterDispositionRequest) (*contract.ListDispositionsResponse, error)
|
2025-08-15 21:17:19 +07:00
|
|
|
GetEnhancedDispositionsByLetter(ctx context.Context, letterID uuid.UUID) (*contract.ListEnhancedDispositionsResponse, error)
|
2025-08-09 18:58:22 +07:00
|
|
|
|
|
|
|
|
CreateDiscussion(ctx context.Context, letterID uuid.UUID, req *contract.CreateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error)
|
|
|
|
|
UpdateDiscussion(ctx context.Context, letterID uuid.UUID, discussionID uuid.UUID, req *contract.UpdateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type LetterHandler struct{ svc LetterService }
|
|
|
|
|
|
|
|
|
|
func NewLetterHandler(svc LetterService) *LetterHandler { return &LetterHandler{svc: svc} }
|
|
|
|
|
|
|
|
|
|
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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp, err := h.svc.CreateIncomingLetter(c.Request.Context(), &req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(http.StatusCreated, contract.BuildSuccessResponse(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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp, err := h.svc.GetIncomingLetterByID(c.Request.Context(), id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, contract.BuildSuccessResponse(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}
|
|
|
|
|
resp, err := h.svc.ListIncomingLetters(c.Request.Context(), req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, contract.BuildSuccessResponse(resp))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var req contract.UpdateIncomingLetterRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp, err := h.svc.UpdateIncomingLetter(c.Request.Context(), id, &req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, contract.BuildSuccessResponse(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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err := h.svc.SoftDeleteIncomingLetter(c.Request.Context(), id); err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, &contract.SuccessResponse{Message: "deleted"})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *LetterHandler) CreateDispositions(c *gin.Context) {
|
2025-08-15 21:17:19 +07:00
|
|
|
appCtx := appcontext.FromGinContext(c.Request.Context())
|
2025-08-09 18:58:22 +07:00
|
|
|
var req contract.CreateLetterDispositionRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-08-15 21:17:19 +07:00
|
|
|
req.FromDepartment = appCtx.DepartmentID
|
2025-08-09 18:58:22 +07:00
|
|
|
resp, err := h.svc.CreateDispositions(c.Request.Context(), &req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(201, contract.BuildSuccessResponse(resp))
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-15 21:17:19 +07:00
|
|
|
func (h *LetterHandler) GetEnhancedDispositionsByLetter(c *gin.Context) {
|
2025-08-09 18:58:22 +07:00
|
|
|
letterID, err := uuid.Parse(c.Param("letter_id"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid letter_id", Code: 400})
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-08-15 21:17:19 +07:00
|
|
|
resp, err := h.svc.GetEnhancedDispositionsByLetter(c.Request.Context(), letterID)
|
2025-08-09 18:58:22 +07:00
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, contract.BuildSuccessResponse(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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var req contract.CreateLetterDiscussionRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp, err := h.svc.CreateDiscussion(c.Request.Context(), letterID, &req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(201, contract.BuildSuccessResponse(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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
discussionID, err := uuid.Parse(c.Param("discussion_id"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid discussion_id", Code: 400})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var req contract.UpdateLetterDiscussionRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
|
|
|
|
|
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})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(200, contract.BuildSuccessResponse(resp))
|
|
|
|
|
}
|