You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.0 KiB

package widgets
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"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"
)
type BudgetResponse struct {
Status int `json:"status"`
// total amount allowed to spend in a month
Budget money.Money `json:"budget"`
// total amount allowed to spend by category
BudgetCategories map[string]money.Money `json:"budget_categories"`
// categories in the budget
Categories []string `json:"categories"`
// transactions mapped to a category
Expenses map[string][]db.Transaction `json:"expenses"`
}
func GetBudget(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 response BudgetResponse
response.Budget = user.Budget
response.BudgetCategories = user.Categories
cats := make([]string, len(user.Categories))
i := 0
for k := range user.Categories {
cats[i] = k
i++
}
response.Categories = cats
response.Expenses = make(map[string][]db.Transaction)
for _, e := range user.Expenses {
if response.Expenses[e.Category] == nil {
response.Expenses[e.Category] = make([]db.Transaction, 0)
}
response.Expenses[e.Category] = append(response.Expenses[e.Category], e)
}
response.Status = 200
ret, err := json.Marshal(response)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "{\"error\":\"problem marshalling response\"}")
return
}
w.Write(ret)
}
func SetCategoryBudget(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
}
// get form values
r.ParseForm()
cat := r.FormValue("category")
if cat == "" {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"category must be specified\"}")
return
}
newWhole, err := strconv.Atoi(r.Form.Get("whole"))
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"incorrect whole value\"}")
return
}
newDecimal, err := strconv.Atoi(r.Form.Get("decimal"))
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"incorrect decimal value\"}")
return
}
// TODO: figure out how to efficiently determing currency
newBudget := money.Money{
Currency: money.Currency(r.FormValue("currency")),
Whole: newWhole,
Decimal: newDecimal,
}
if user.Categories == nil {
user.Categories = make(map[string]money.Money)
}
user.Categories[cat] = newBudget
filter := bson.D{primitive.E{Key: "session", Value: session}}
opts := options.Update().SetUpsert(true)
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: "categories", Value: user.Categories}}}}
_, err = userCollection.UpdateOne(context.TODO(), filter, update, opts)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
w.Write([]byte("{\"status\":200}"))
}
func SetBudget(w http.ResponseWriter, r *http.Request) {
// get session key from request
session := r.Header.Get("x-session-key")
// get form values
r.ParseForm()
newWhole, err := strconv.Atoi(r.Form.Get("whole"))
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"incorrect whole value\"}")
return
}
newDecimal, err := strconv.Atoi(r.Form.Get("decimal"))
if err != nil || newDecimal < 0 || newDecimal > 99 {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"incorrect decimal value\"}")
return
}
// TODO: figure out how to efficiently determing currency
newBudget := money.Money{
Currency: money.Currency(r.FormValue("currency")),
Whole: newWhole,
Decimal: newDecimal,
}
// get collection handle from db
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
filter := bson.D{primitive.E{Key: "session", Value: session}}
opts := options.Update().SetUpsert(true)
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: "budget", Value: newBudget}}}}
_, err = userCollection.UpdateOne(context.TODO(), filter, update, opts)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
w.Write([]byte("{\"status\":200}"))
}