From 9d65a782ca3e2084ef0f560500f6014d7bd09bc0 Mon Sep 17 00:00:00 2001 From: Biswa Kalyan Bhuyan Date: Sat, 26 Apr 2025 01:06:54 +0530 Subject: finance/backend: mvfeat: moved the backend api handlers to api/handlers and added couple of more api request handlers --- backend/handlers/goal_handler.go | 272 --------------------------------------- 1 file changed, 272 deletions(-) delete mode 100644 backend/handlers/goal_handler.go (limited to 'backend/handlers/goal_handler.go') diff --git a/backend/handlers/goal_handler.go b/backend/handlers/goal_handler.go deleted file mode 100644 index 09bea74..0000000 --- a/backend/handlers/goal_handler.go +++ /dev/null @@ -1,272 +0,0 @@ -package handlers - -import ( - "log" - "net/http" - "strconv" - "time" - - "finance/backend/internal/database" - "finance/backend/internal/models" - - "github.com/gin-gonic/gin" -) - -// CreateGoalInput defines the structure for creating a new financial goal -type CreateGoalInput struct { - Name string `json:"name" binding:"required"` - TargetAmount int64 `json:"targetAmount" binding:"required"` - CurrentAmount int64 `json:"currentAmount"` - TargetDate string `json:"targetDate"` // YYYY-MM-DD format - Status string `json:"status"` -} - -// UpdateGoalInput defines the structure for updating an existing financial goal -type UpdateGoalInput struct { - Name string `json:"name"` - TargetAmount int64 `json:"targetAmount"` - CurrentAmount int64 `json:"currentAmount"` - TargetDate string `json:"targetDate"` // YYYY-MM-DD format - Status string `json:"status"` -} - -// UpdateGoalProgressInput defines the structure for updating just the progress of a goal -type UpdateGoalProgressInput struct { - CurrentAmount int64 `json:"currentAmount" binding:"required"` -} - -// GoalHandler handles all goal-related operations in the API -type GoalHandler struct { -} - -// NewGoalHandler creates and returns a new GoalHandler instance -func NewGoalHandler() *GoalHandler { - return &GoalHandler{} -} - -// GetGoals retrieves all goals for the authenticated user -// Optionally filtered by status if provided as a query parameter -func (h *GoalHandler) GetGoals(c *gin.Context) { - userID := c.MustGet("userID").(uint) - var goals []models.Goal - - query := database.DB.Where("user_id = ?", userID) - - // Filter by status if provided - status := c.Query("status") - if status != "" { - query = query.Where("status = ?", status) - } - - if err := query.Find(&goals).Error; err != nil { - log.Printf("Error fetching goals for user %d: %v", userID, err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get goals"}) - return - } - - c.JSON(http.StatusOK, goals) -} - -// GetGoal retrieves a specific goal by ID for the authenticated user -func (h *GoalHandler) GetGoal(c *gin.Context) { - userID := c.MustGet("userID").(uint) - goalID, err := strconv.ParseUint(c.Param("id"), 10, 32) - if err != nil { - log.Printf("Error parsing goal ID: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid goal ID"}) - return - } - - var goal models.Goal - if err := database.DB.Where("id = ? AND user_id = ?", goalID, userID).First(&goal).Error; err != nil { - log.Printf("Error fetching goal ID %d for user %d: %v", goalID, userID, err) - c.JSON(http.StatusNotFound, gin.H{"error": "Goal not found"}) - return - } - - c.JSON(http.StatusOK, goal) -} - -// CreateGoal creates a new financial goal for the authenticated user -func (h *GoalHandler) CreateGoal(c *gin.Context) { - userID := c.MustGet("userID").(uint) - var input CreateGoalInput - - if err := c.ShouldBindJSON(&input); err != nil { - log.Printf("Error binding JSON for goal creation: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - // Set default status if not provided - status := "Active" - if input.Status != "" { - status = input.Status - } - - // Parse target date if provided - var targetDate time.Time - if input.TargetDate != "" { - parsedDate, err := time.Parse("2006-01-02", input.TargetDate) - if err != nil { - log.Printf("Error parsing target date for goal creation: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid date format for targetDate. Use YYYY-MM-DD"}) - return - } - targetDate = parsedDate - } - - goal := models.Goal{ - UserID: userID, - Name: input.Name, - TargetAmount: input.TargetAmount, - CurrentAmount: input.CurrentAmount, - Status: status, - } - - // Only set target date if it was provided - if !targetDate.IsZero() { - goal.TargetDate = targetDate - } - - if err := database.DB.Create(&goal).Error; err != nil { - log.Printf("Error creating goal for user %d: %v", userID, err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create goal"}) - return - } - - log.Printf("Goal created successfully for user %d: %s (ID: %d)", userID, goal.Name, goal.ID) - c.JSON(http.StatusCreated, goal) -} - -// UpdateGoal updates an existing goal for the authenticated user -func (h *GoalHandler) UpdateGoal(c *gin.Context) { - userID := c.MustGet("userID").(uint) - goalID, err := strconv.ParseUint(c.Param("id"), 10, 32) - if err != nil { - log.Printf("Error parsing goal ID for update: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid goal ID"}) - return - } - - var goal models.Goal - if err := database.DB.Where("id = ? AND user_id = ?", goalID, userID).First(&goal).Error; err != nil { - log.Printf("Error fetching goal ID %d for user %d in update: %v", goalID, userID, err) - c.JSON(http.StatusNotFound, gin.H{"error": "Goal not found"}) - return - } - - var input UpdateGoalInput - if err := c.ShouldBindJSON(&input); err != nil { - log.Printf("Error binding JSON for goal update: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - // Update fields that were provided - if input.Name != "" { - goal.Name = input.Name - } - if input.TargetAmount != 0 { - goal.TargetAmount = input.TargetAmount - } - if input.CurrentAmount != 0 { - goal.CurrentAmount = input.CurrentAmount - } - if input.TargetDate != "" { - parsedDate, err := time.Parse("2006-01-02", input.TargetDate) - if err != nil { - log.Printf("Error parsing target date for goal update: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid date format for targetDate. Use YYYY-MM-DD"}) - return - } - goal.TargetDate = parsedDate - } - if input.Status != "" { - goal.Status = input.Status - } - - // Check if goal has been achieved - if goal.CurrentAmount >= goal.TargetAmount { - goal.Status = "Achieved" - log.Printf("Goal ID %d for user %d automatically marked as Achieved", goalID, userID) - } - - if err := database.DB.Save(&goal).Error; err != nil { - log.Printf("Error saving updated goal ID %d for user %d: %v", goalID, userID, err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update goal"}) - return - } - - log.Printf("Goal ID %d updated successfully for user %d", goalID, userID) - c.JSON(http.StatusOK, goal) -} - -// UpdateGoalProgress updates just the progress (current amount) of a goal -func (h *GoalHandler) UpdateGoalProgress(c *gin.Context) { - userID := c.MustGet("userID").(uint) - goalID, err := strconv.ParseUint(c.Param("id"), 10, 32) - if err != nil { - log.Printf("Error parsing goal ID for progress update: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid goal ID"}) - return - } - - var goal models.Goal - if err := database.DB.Where("id = ? AND user_id = ?", goalID, userID).First(&goal).Error; err != nil { - log.Printf("Error fetching goal ID %d for user %d in progress update: %v", goalID, userID, err) - c.JSON(http.StatusNotFound, gin.H{"error": "Goal not found"}) - return - } - - var input UpdateGoalProgressInput - if err := c.ShouldBindJSON(&input); err != nil { - log.Printf("Error binding JSON for goal progress update: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - goal.CurrentAmount = input.CurrentAmount - - // Check if goal has been achieved - if goal.CurrentAmount >= goal.TargetAmount { - goal.Status = "Achieved" - log.Printf("Goal ID %d for user %d automatically marked as Achieved during progress update", goalID, userID) - } - - if err := database.DB.Save(&goal).Error; err != nil { - log.Printf("Error saving progress update for goal ID %d for user %d: %v", goalID, userID, err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update goal progress"}) - return - } - - log.Printf("Goal ID %d progress updated successfully for user %d: %d/%d", goalID, userID, goal.CurrentAmount, goal.TargetAmount) - c.JSON(http.StatusOK, goal) -} - -// DeleteGoal deletes a goal belonging to the authenticated user -func (h *GoalHandler) DeleteGoal(c *gin.Context) { - userID := c.MustGet("userID").(uint) - goalID, err := strconv.ParseUint(c.Param("id"), 10, 32) - if err != nil { - log.Printf("Error parsing goal ID for deletion: %v", err) - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid goal ID"}) - return - } - - var goal models.Goal - if err := database.DB.Where("id = ? AND user_id = ?", goalID, userID).First(&goal).Error; err != nil { - log.Printf("Error fetching goal ID %d for user %d for deletion: %v", goalID, userID, err) - c.JSON(http.StatusNotFound, gin.H{"error": "Goal not found"}) - return - } - - if err := database.DB.Delete(&goal).Error; err != nil { - log.Printf("Error deleting goal ID %d for user %d: %v", goalID, userID, err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete goal"}) - return - } - - log.Printf("Goal ID %d deleted successfully for user %d", goalID, userID) - c.JSON(http.StatusOK, gin.H{"message": "Goal deleted successfully"}) -} -- cgit v1.2.3-59-g8ed1b