Added expenses to plan

This commit is contained in:
Manuel Forcén Muñoz 2025-04-09 18:37:02 +02:00
parent 8ea8574f3f
commit 54d7d14ef9
9 changed files with 401 additions and 13 deletions

231
apis/expenses.go Normal file
View file

@ -0,0 +1,231 @@
package apis
import (
"net/http"
"planner/core"
"slices"
"strconv"
"github.com/gin-gonic/gin"
"github.com/shopspring/decimal"
)
type ExpenseDef struct {
Payer string `json:"payer"`
Type string `json:"type"`
Amount decimal.Decimal `json:"amount"`
}
func createExpense(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
plan_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || plan_id < 0 {
c.Status(http.StatusBadRequest)
return
}
plan, err := u.GetPlan(db, uint(plan_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
members, err := plan.GetAllUsers(db)
if err != nil {
c.Status(http.StatusInternalServerError)
return
}
var exp ExpenseDef
if err := c.ShouldBind(&exp); err != nil {
c.Status(http.StatusBadRequest)
return
}
var compare func(m core.Member) bool
if exp.Type == "user" {
compare = func(m core.Member) bool {
return m.UserID == exp.Payer
}
} else if exp.Type == "non-user" {
compare = func(m core.Member) bool {
return m.Name == exp.Payer
}
} else {
c.String(http.StatusBadRequest, "Invalid member type")
return
}
idx := slices.IndexFunc(members, compare)
if idx != -1 {
expense, err := core.CreateExpense(db, plan, members[idx], exp.Amount)
if err != nil {
c.Status(http.StatusInternalServerError)
return
}
c.JSON(http.StatusOK, expense)
return
}
c.String(http.StatusBadRequest, "Unable to found member")
}
func listExpenses(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
plan_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || plan_id < 0 {
c.Status(http.StatusBadRequest)
return
}
plan, err := u.GetPlan(db, uint(plan_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
expenses, err := core.ListExpenses(db, plan)
if err != nil {
c.Status(http.StatusInternalServerError)
return
}
c.JSON(http.StatusOK, expenses)
}
func getExpense(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
expense_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || expense_id < 0 {
c.Status(http.StatusBadRequest)
return
}
expense, err := core.GetExpense(db, uint(expense_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
_, err = u.GetPlan(db, expense.PlanID)
if err != nil {
c.Status(http.StatusBadRequest)
return
}
c.JSON(http.StatusOK, expense)
}
func deleteExpense(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
expense_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || expense_id < 0 {
c.Status(http.StatusBadRequest)
return
}
expense, err := core.GetExpense(db, uint(expense_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
_, err = u.GetPlan(db, expense.PlanID)
if err != nil {
c.Status(http.StatusBadRequest)
return
}
if err = expense.Delete(db); err != nil {
c.Status(http.StatusInternalServerError)
return
}
c.Status(http.StatusOK)
}
func getExpenseDebts(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
expense_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || expense_id < 0 {
c.Status(http.StatusBadRequest)
return
}
expense, err := core.GetExpense(db, uint(expense_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
_, err = u.GetPlan(db, expense.PlanID)
if err != nil {
c.Status(http.StatusBadRequest)
return
}
debts, err := expense.GetDebt(db)
if err != nil {
c.Status(http.StatusInternalServerError)
return
}
c.JSON(http.StatusOK, debts)
}
func setExpenseDebts(c *gin.Context) {
u := extractUser(db, c)
if u == nil {
c.Status(http.StatusUnauthorized)
return
}
expense_id, err := strconv.ParseInt(c.Param("id"), 10, 32)
if err != nil || expense_id < 0 {
c.Status(http.StatusBadRequest)
return
}
expense, err := core.GetExpense(db, uint(expense_id))
if err != nil {
c.Status(http.StatusBadRequest)
return
}
plan, err := u.GetPlan(db, expense.PlanID)
if err != nil {
c.Status(http.StatusBadRequest)
return
}
expense.Plan = plan
var debtSpec []core.DebtSpec
if err := c.ShouldBind(&debtSpec); err != nil {
c.Status(http.StatusBadRequest)
return
}
//expense.SetDebt(db, debtSpec)
c.JSON(http.StatusOK, debtSpec)
}
func bindExpensesAPIs(r *gin.Engine) {
r.POST("/plans/:id/expenses", createExpense)
r.GET("/plans/:id/expenses", listExpenses)
r.GET("/expenses/:id", getExpense)
r.DELETE("/expenses/:id", deleteExpense)
r.GET("/expenses/:id/debts", getExpenseDebts)
r.POST("/expenses/:id/debts", setExpenseDebts)
}