mirror of
https://github.com/gabehf/BudgetBuddy.git
synced 2026-03-14 17:56:01 -07:00
api for initial widgets
This commit is contained in:
parent
36f751a69f
commit
4aa8a2f822
14 changed files with 864 additions and 11 deletions
248
widgets/transactions.go
Normal file
248
widgets/transactions.go
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/jacobmveber-01839764/BudgetBuddy/db"
|
||||
"github.com/jacobmveber-01839764/BudgetBuddy/money"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
const (
|
||||
RecentTransactionAmount = 10
|
||||
)
|
||||
|
||||
type RecentTransactionsResponse struct {
|
||||
Status int `json:"status"`
|
||||
Transactions []db.Transaction `json:"transactions"`
|
||||
}
|
||||
|
||||
func GetRecentTransactions(w http.ResponseWriter, r *http.Request) {
|
||||
// get session key from request
|
||||
session := r.Header.Get("x-session-key")
|
||||
|
||||
// get collection handle from db
|
||||
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
|
||||
|
||||
var user = db.UserSchema{}
|
||||
|
||||
err := userCollection.FindOne(context.Background(), bson.D{primitive.E{Key: "session", Value: session}}).Decode(&user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
|
||||
return
|
||||
}
|
||||
|
||||
var transactionA []db.Transaction
|
||||
|
||||
i := 0
|
||||
j := 0
|
||||
for i+j < RecentTransactionAmount {
|
||||
// if we are out of transactions, return
|
||||
if i >= len(user.Expenses) && j >= len(user.Income) {
|
||||
break
|
||||
} else if i > len(user.Expenses)-1 { // if we are out of expenses, just use income
|
||||
transactionA = append(transactionA, user.Income[j])
|
||||
j++
|
||||
} else if j > len(user.Income)-1 { // if we are out of income, just use expenses
|
||||
transactionA = append(transactionA, user.Expenses[i])
|
||||
i++
|
||||
} else if user.Expenses[i].Timestamp > user.Income[j].Timestamp {
|
||||
transactionA = append(transactionA, user.Expenses[i])
|
||||
i++
|
||||
} else {
|
||||
transactionA = append(transactionA, user.Income[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
response := RecentTransactionsResponse{
|
||||
Status: 200,
|
||||
Transactions: transactionA,
|
||||
}
|
||||
|
||||
ret, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintf(w, "{\"error\":\"problem marshalling response\"}")
|
||||
}
|
||||
|
||||
w.Write(ret)
|
||||
}
|
||||
|
||||
func NewTransaction(w http.ResponseWriter, r *http.Request) {
|
||||
// get session key from request
|
||||
session := r.Header.Get("x-session-key")
|
||||
|
||||
// get collection handle from db
|
||||
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
|
||||
|
||||
var user = db.UserSchema{}
|
||||
|
||||
err := userCollection.FindOne(context.Background(), bson.D{primitive.E{Key: "session", Value: session}}).Decode(&user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
whole, err := strconv.Atoi(r.Form.Get("whole"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"incorrect whole value\"}")
|
||||
return
|
||||
}
|
||||
decimal, err := strconv.Atoi(r.Form.Get("decimal"))
|
||||
if err != nil || decimal < 0 || decimal > 99 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"incorrect decimal value\"}")
|
||||
return
|
||||
}
|
||||
|
||||
var cat string
|
||||
|
||||
if r.FormValue("category") == "" {
|
||||
cat = "uncategorized"
|
||||
} else {
|
||||
cat = r.FormValue("category")
|
||||
}
|
||||
|
||||
newT := db.Transaction{
|
||||
Timestamp: time.Now().Unix(),
|
||||
Category: cat,
|
||||
Amount: money.Money{
|
||||
Currency: money.Currency(r.FormValue("currency")),
|
||||
Whole: whole,
|
||||
Decimal: decimal,
|
||||
},
|
||||
Type: r.FormValue("type"),
|
||||
}
|
||||
|
||||
var newArr []db.Transaction
|
||||
var success bool
|
||||
if r.FormValue("type") == "income" {
|
||||
newArr = append(user.Income, newT)
|
||||
success = addToBalance(user, newT.Amount)
|
||||
} else if r.FormValue("type") == "expenses" {
|
||||
newArr = append(user.Expenses, newT)
|
||||
success = subtractFromBalance(user, newT.Amount)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"invalid transaction type - only income or expenses are allowed\"}")
|
||||
return
|
||||
}
|
||||
|
||||
if !success {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintf(w, "{\"error\":\"unable to update balance\"}")
|
||||
return
|
||||
}
|
||||
|
||||
// push the new transaction to db
|
||||
filter := bson.D{primitive.E{Key: "session", Value: user.Session}}
|
||||
opts := options.Update().SetUpsert(true)
|
||||
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: r.FormValue("type"), Value: newArr}}}}
|
||||
userCollection.UpdateOne(context.TODO(), filter, update, opts)
|
||||
|
||||
w.Write([]byte("{\"status\": 200}"))
|
||||
}
|
||||
|
||||
func NewRecurring(w http.ResponseWriter, r *http.Request) {
|
||||
// get session key from request
|
||||
session := r.Header.Get("x-session-key")
|
||||
|
||||
// get collection handle from db
|
||||
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
|
||||
|
||||
var user = db.UserSchema{}
|
||||
|
||||
err := userCollection.FindOne(context.Background(), bson.D{primitive.E{Key: "session", Value: session}}).Decode(&user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
whole, err := strconv.Atoi(r.Form.Get("whole"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"incorrect whole value\"}")
|
||||
return
|
||||
}
|
||||
decimal, err := strconv.Atoi(r.Form.Get("decimal"))
|
||||
if err != nil || decimal < 0 || decimal > 99 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"incorrect decimal value\"}")
|
||||
return
|
||||
}
|
||||
period, err := strconv.Atoi(r.Form.Get("period"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"period must be specified\"}")
|
||||
return
|
||||
}
|
||||
|
||||
var cat string
|
||||
|
||||
if r.FormValue("category") == "" {
|
||||
cat = "uncategorized"
|
||||
}
|
||||
|
||||
newT := db.Transaction{
|
||||
Timestamp: time.Now().Unix(),
|
||||
Category: cat,
|
||||
Amount: money.Money{
|
||||
Currency: money.Currency(r.FormValue("currency")),
|
||||
Whole: whole,
|
||||
Decimal: decimal,
|
||||
},
|
||||
Type: r.FormValue("type"),
|
||||
}
|
||||
|
||||
newR := db.RecurringTransaction{
|
||||
Transaction: newT,
|
||||
Period: period,
|
||||
Since: time.Now().Unix(),
|
||||
Until: int64(0),
|
||||
}
|
||||
|
||||
var newArr []db.RecurringTransaction
|
||||
var success bool
|
||||
if r.FormValue("type") == "income" {
|
||||
newArr = append(user.RecurringIncome, newR)
|
||||
success = addToBalance(user, newT.Amount)
|
||||
} else if r.FormValue("type") == "expenses" {
|
||||
newArr = append(user.RecurringExpenses, newR)
|
||||
success = subtractFromBalance(user, newT.Amount)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintf(w, "{\"error\":\"invalid transaction type - only income or expenses are allowed\"}")
|
||||
return
|
||||
}
|
||||
|
||||
if !success {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintf(w, "{\"error\":\"unable to update balance\"}")
|
||||
return
|
||||
}
|
||||
|
||||
// push the new transaction to db
|
||||
filter := bson.D{primitive.E{Key: "session", Value: user.Session}}
|
||||
opts := options.Update().SetUpsert(true)
|
||||
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: r.FormValue("type"), Value: newArr}}}}
|
||||
userCollection.UpdateOne(context.TODO(), filter, update, opts)
|
||||
|
||||
w.Write([]byte("{\"status\": 200}"))
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue