aboutsummaryrefslogtreecommitdiffstats
path: root/backend/internal/api/handlers/account_handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/internal/api/handlers/account_handler.go')
-rw-r--r--backend/internal/api/handlers/account_handler.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/backend/internal/api/handlers/account_handler.go b/backend/internal/api/handlers/account_handler.go
new file mode 100644
index 0000000..5a92ef6
--- /dev/null
+++ b/backend/internal/api/handlers/account_handler.go
@@ -0,0 +1,162 @@
+package handlers
+
+import (
+ "log"
+ "net/http"
+ "strconv"
+
+ "finance/backend/internal/database"
+ "finance/backend/internal/models"
+
+ "github.com/gin-gonic/gin"
+)
+
+// AccountHandler handles account-related operations
+type AccountHandler struct {
+}
+
+// NewAccountHandler creates and returns a new AccountHandler instance
+func NewAccountHandler() *AccountHandler {
+ return &AccountHandler{}
+}
+
+// GetAccounts retrieves all accounts for the authenticated user
+func (h *AccountHandler) GetAccounts(c *gin.Context) {
+ userID := c.MustGet("userID").(uint)
+ var accounts []models.Account
+
+ // Fetch accounts for the current user
+ if err := database.DB.Where("user_id = ?", userID).Find(&accounts).Error; err != nil {
+ log.Printf("Error fetching accounts for user %d: %v", userID, err)
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get accounts"})
+ return
+ }
+
+ c.JSON(http.StatusOK, accounts)
+}
+
+// GetAccountByID retrieves a specific account by ID for the authenticated user
+func (h *AccountHandler) GetAccountByID(c *gin.Context) {
+ userID := c.MustGet("userID").(uint)
+ accountID, err := strconv.ParseUint(c.Param("id"), 10, 32)
+ if err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid account ID"})
+ return
+ }
+
+ var account models.Account
+ if err := database.DB.Where("id = ? AND user_id = ?", accountID, userID).First(&account).Error; err != nil {
+ c.JSON(http.StatusNotFound, gin.H{"error": "Account not found"})
+ return
+ }
+
+ c.JSON(http.StatusOK, account)
+}
+
+// CreateAccount creates a new financial account for the authenticated user
+func (h *AccountHandler) CreateAccount(c *gin.Context) {
+ userID := c.MustGet("userID").(uint)
+
+ // Define input structure
+ type CreateAccountInput struct {
+ Name string `json:"name" binding:"required"`
+ Type string `json:"type" binding:"required"`
+ Balance int64 `json:"balance"`
+ }
+
+ var input CreateAccountInput
+ if err := c.ShouldBindJSON(&input); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ // Create new account
+ account := models.Account{
+ UserID: userID,
+ Name: input.Name,
+ Type: input.Type,
+ Balance: input.Balance,
+ }
+
+ if err := database.DB.Create(&account).Error; err != nil {
+ log.Printf("Error creating account for user %d: %v", userID, err)
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create account"})
+ return
+ }
+
+ c.JSON(http.StatusCreated, account)
+}
+
+// UpdateAccount updates an existing account for the authenticated user
+func (h *AccountHandler) UpdateAccount(c *gin.Context) {
+ userID := c.MustGet("userID").(uint)
+ accountID, err := strconv.ParseUint(c.Param("id"), 10, 32)
+ if err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid account ID"})
+ return
+ }
+
+ // Find account
+ var account models.Account
+ if err := database.DB.Where("id = ? AND user_id = ?", accountID, userID).First(&account).Error; err != nil {
+ c.JSON(http.StatusNotFound, gin.H{"error": "Account not found"})
+ return
+ }
+
+ // Define update structure
+ type UpdateAccountInput struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+ Balance int64 `json:"balance"`
+ }
+
+ var input UpdateAccountInput
+ if err := c.ShouldBindJSON(&input); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ // Update fields if provided
+ if input.Name != "" {
+ account.Name = input.Name
+ }
+ if input.Type != "" {
+ account.Type = input.Type
+ }
+ // For balance updates, we'll accept zero values, so we update unconditionally
+ account.Balance = input.Balance
+
+ if err := database.DB.Save(&account).Error; err != nil {
+ log.Printf("Error updating account ID %d for user %d: %v", accountID, userID, err)
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update account"})
+ return
+ }
+
+ c.JSON(http.StatusOK, account)
+}
+
+// DeleteAccount deletes an account belonging to the authenticated user
+func (h *AccountHandler) DeleteAccount(c *gin.Context) {
+ userID := c.MustGet("userID").(uint)
+ accountID, err := strconv.ParseUint(c.Param("id"), 10, 32)
+ if err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid account ID"})
+ return
+ }
+
+ // Check if account exists and belongs to user
+ var account models.Account
+ if err := database.DB.Where("id = ? AND user_id = ?", accountID, userID).First(&account).Error; err != nil {
+ c.JSON(http.StatusNotFound, gin.H{"error": "Account not found"})
+ return
+ }
+
+ // Delete account
+ if err := database.DB.Delete(&account).Error; err != nil {
+ log.Printf("Error deleting account ID %d for user %d: %v", accountID, userID, err)
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete account"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"message": "Account deleted successfully"})
+}