1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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"})
}
|