Implement assignment import and clear of budget
This commit is contained in:
@@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -75,3 +76,28 @@ func (h *Handler) budgeting(c *gin.Context) {
|
||||
|
||||
c.HTML(http.StatusOK, "budgeting.html", d)
|
||||
}
|
||||
|
||||
func (h *Handler) clearBudget(c *gin.Context) {
|
||||
budgetID := c.Param("budgetid")
|
||||
budgetUUID, err := uuid.Parse(budgetID)
|
||||
if err != nil {
|
||||
c.Redirect(http.StatusTemporaryRedirect, "/login")
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := h.Service.DB.DeleteAllAssignments(c.Request.Context(), budgetUUID)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Deleted %d assignments\n", rows)
|
||||
|
||||
rows, err = h.Service.DB.DeleteAllTransactions(c.Request.Context(), budgetUUID)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Deleted %d transactions\n", rows)
|
||||
}
|
||||
|
48
http/http.go
48
http/http.go
@@ -1,6 +1,7 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -57,6 +58,7 @@ func (h *Handler) Serve() {
|
||||
withBudget.Use(h.verifyLoginWithRedirect)
|
||||
withBudget.Use(h.getImportantData)
|
||||
withBudget.GET("/budget/:budgetid", h.budgeting)
|
||||
withBudget.GET("/budget/:budgetid/clear", h.clearBudget)
|
||||
withBudget.GET("/budget/:budgetid/:year/:month", h.budgeting)
|
||||
withBudget.GET("/budget/:budgetid/all-accounts", h.budget)
|
||||
withBudget.GET("/budget/:budgetid/accounts", h.accounts)
|
||||
@@ -86,21 +88,9 @@ func (h *Handler) Serve() {
|
||||
}
|
||||
|
||||
func (h *Handler) importYNAB(c *gin.Context) {
|
||||
transactionsFile, err := c.FormFile("transactions")
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
transactions, err := transactionsFile.Open()
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
budgetID, succ := c.GetPostForm("budget_id")
|
||||
if !succ {
|
||||
c.AbortWithError(http.StatusBadRequest, err)
|
||||
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("no budget_id specified"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -116,7 +106,37 @@ func (h *Handler) importYNAB(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err = ynab.Import(transactions)
|
||||
transactionsFile, err := c.FormFile("transactions")
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
transactions, err := transactionsFile.Open()
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = ynab.ImportTransactions(transactions)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
assignmentsFile, err := c.FormFile("assignments")
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
assignments, err := assignmentsFile.Open()
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = ynab.ImportAssignments(assignments)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
|
@@ -56,7 +56,61 @@ func NewYNABImport(q *postgres.Queries, budgetID uuid.UUID) (*YNABImport, error)
|
||||
|
||||
}
|
||||
|
||||
func (ynab *YNABImport) Import(r io.Reader) error {
|
||||
func (ynab *YNABImport) ImportAssignments(r io.Reader) error {
|
||||
csv := csv.NewReader(r)
|
||||
csv.Comma = '\t'
|
||||
csv.LazyQuotes = true
|
||||
|
||||
csvData, err := csv.ReadAll()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read from tsv: %w", err)
|
||||
}
|
||||
|
||||
count := 0
|
||||
for _, record := range csvData[1:] {
|
||||
//"Month" "Category Group/Category" "Category Group" "Category" "Budgeted" "Activity" "Available"
|
||||
//"Apr 2019" "Income: Next Month" "Income" "Next Month" 0,00€ 0,00€ 0,00€
|
||||
dateString := record[0]
|
||||
date, err := time.Parse("Jan 2006", dateString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse date %s: %w", dateString, err)
|
||||
}
|
||||
|
||||
categoryGroup, categoryName := record[2], record[3] //also in 1 joined by :
|
||||
category, err := ynab.GetCategory(categoryGroup, categoryName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get category %s/%s: %w", categoryGroup, categoryName, err)
|
||||
}
|
||||
|
||||
amountString := record[4]
|
||||
amount, err := GetAmount(amountString, "0,00€")
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse amount %s: %w", amountString, err)
|
||||
}
|
||||
|
||||
if amount.Int.Int64() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
assignment := postgres.CreateAssignmentParams{
|
||||
Date: date,
|
||||
CategoryID: category.UUID,
|
||||
Amount: amount,
|
||||
}
|
||||
_, err = ynab.queries.CreateAssignment(ynab.Context, assignment)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not save assignment %v: %w", assignment, err)
|
||||
}
|
||||
|
||||
count++
|
||||
}
|
||||
|
||||
fmt.Printf("Imported %d assignments\n", count)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ynab *YNABImport) ImportTransactions(r io.Reader) error {
|
||||
csv := csv.NewReader(r)
|
||||
csv.Comma = '\t'
|
||||
csv.LazyQuotes = true
|
||||
@@ -88,10 +142,10 @@ func (ynab *YNABImport) Import(r io.Reader) error {
|
||||
return fmt.Errorf("could not get payee %s: %w", payeeName, err)
|
||||
}
|
||||
|
||||
categoryGroup, categoryName := record[5], record[6] //also in 5 + 6 split by group/category
|
||||
categoryGroup, categoryName := record[5], record[6] //also in 4 joined by :
|
||||
category, err := ynab.GetCategory(categoryGroup, categoryName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get category %s: %w", payeeName, err)
|
||||
return fmt.Errorf("could not get category %s/%s: %w", categoryGroup, categoryName, err)
|
||||
}
|
||||
|
||||
memo := record[7]
|
||||
|
Reference in New Issue
Block a user