package handler import ( "strconv" "accounting-app/pkg/api" "accounting-app/internal/service" "github.com/gin-gonic/gin" ) // TemplateHandler handles HTTP requests for transaction templates type TemplateHandler struct { templateService *service.TemplateService } // NewTemplateHandler creates a new TemplateHandler instance func NewTemplateHandler(templateService *service.TemplateService) *TemplateHandler { return &TemplateHandler{ templateService: templateService, } } // RegisterRoutes registers template routes func (h *TemplateHandler) RegisterRoutes(router *gin.RouterGroup) { templates := router.Group("/templates") { templates.POST("", h.CreateTemplate) templates.GET("", h.GetAllTemplates) templates.GET("/:id", h.GetTemplate) templates.PUT("/:id", h.UpdateTemplate) templates.DELETE("/:id", h.DeleteTemplate) templates.PUT("/sort", h.UpdateSortOrder) } } // CreateTemplate creates a new transaction template // @Summary Create a new transaction template // @Tags templates // @Accept json // @Produce json // @Param template body service.TemplateInput true "Template data" // @Success 201 {object} api.Response{data=models.TransactionTemplate} // @Failure 400 {object} api.Response // @Router /templates [post] func (h *TemplateHandler) CreateTemplate(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } var input service.TemplateInput if err := c.ShouldBindJSON(&input); err != nil { api.BadRequest(c, "Invalid request body: "+err.Error()) return } template, err := h.templateService.CreateTemplate(userId.(uint), input) if err != nil { api.BadRequest(c, err.Error()) return } api.Created(c, template) } // GetAllTemplates retrieves all templates for the current user // @Summary Get all transaction templates // @Tags templates // @Produce json // @Success 200 {object} api.Response{data=[]models.TransactionTemplate} // @Router /templates [get] func (h *TemplateHandler) GetAllTemplates(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } templates, err := h.templateService.GetAllTemplates(userId.(uint)) if err != nil { api.InternalError(c, err.Error()) return } api.Success(c, templates) } // GetTemplate retrieves a template by ID // @Summary Get a transaction template by ID // @Tags templates // @Produce json // @Param id path int true "Template ID" // @Success 200 {object} api.Response{data=models.TransactionTemplate} // @Failure 404 {object} api.Response // @Router /templates/{id} [get] func (h *TemplateHandler) GetTemplate(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { api.BadRequest(c, "Invalid template ID") return } template, err := h.templateService.GetTemplate(userId.(uint), uint(id)) if err != nil { if err == service.ErrTemplateNotFound { api.NotFound(c, "Template not found") return } api.InternalError(c, err.Error()) return } api.Success(c, template) } // UpdateTemplate updates an existing template // @Summary Update a transaction template // @Tags templates // @Accept json // @Produce json // @Param id path int true "Template ID" // @Param template body service.TemplateInput true "Template data" // @Success 200 {object} api.Response{data=models.TransactionTemplate} // @Failure 400 {object} api.Response // @Failure 404 {object} api.Response // @Router /templates/{id} [put] func (h *TemplateHandler) UpdateTemplate(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { api.BadRequest(c, "Invalid template ID") return } var input service.TemplateInput if err := c.ShouldBindJSON(&input); err != nil { api.BadRequest(c, "Invalid request body: "+err.Error()) return } template, err := h.templateService.UpdateTemplate(userId.(uint), uint(id), input) if err != nil { if err == service.ErrTemplateNotFound { api.NotFound(c, "Template not found") return } api.BadRequest(c, err.Error()) return } api.Success(c, template) } // DeleteTemplate deletes a template // @Summary Delete a transaction template // @Tags templates // @Produce json // @Param id path int true "Template ID" // @Success 200 {object} api.Response // @Failure 404 {object} api.Response // @Router /templates/{id} [delete] func (h *TemplateHandler) DeleteTemplate(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { api.BadRequest(c, "Invalid template ID") return } err = h.templateService.DeleteTemplate(userId.(uint), uint(id)) if err != nil { if err == service.ErrTemplateNotFound { api.NotFound(c, "Template not found") return } api.InternalError(c, err.Error()) return } api.Success(c, gin.H{"message": "Template deleted successfully"}) } // UpdateSortOrderInput represents the input for updating sort order type UpdateSortOrderInput struct { IDs []uint `json:"ids" binding:"required"` } // UpdateSortOrder updates the sort order of templates // @Summary Update template sort order // @Tags templates // @Accept json // @Produce json // @Param input body UpdateSortOrderInput true "Template IDs in desired order" // @Success 200 {object} api.Response // @Failure 400 {object} api.Response // @Router /templates/sort [put] func (h *TemplateHandler) UpdateSortOrder(c *gin.Context) { userId, exists := c.Get("user_id") if !exists { api.Unauthorized(c, "User not authenticated") return } var input UpdateSortOrderInput if err := c.ShouldBindJSON(&input); err != nil { api.BadRequest(c, "Invalid request body: "+err.Error()) return } if len(input.IDs) == 0 { api.BadRequest(c, "IDs array cannot be empty") return } err := h.templateService.UpdateSortOrder(userId.(uint), input.IDs) if err != nil { api.InternalError(c, err.Error()) return } api.Success(c, gin.H{"message": "Sort order updated successfully"}) }