diff --git a/http/ynab-import.go b/http/ynab-import.go index 39d0054..1b22bf2 100644 --- a/http/ynab-import.go +++ b/http/ynab-import.go @@ -5,7 +5,9 @@ import ( "encoding/csv" "fmt" "io" + "strings" "time" + "unicode/utf8" "git.javil.eu/jacob1123/budgeteer/postgres" "github.com/google/uuid" @@ -51,6 +53,7 @@ func (ynab *YNABImport) Import(r io.Reader) error { return fmt.Errorf("could not read from tsv: %w", err) } + count := 0 for _, record := range csvData[1:] { accountName := record[0] account, err := ynab.GetAccount(accountName) @@ -77,7 +80,10 @@ func (ynab *YNABImport) Import(r io.Reader) error { outflow := record[8] inflow := record[9] - amount := GetAmount(inflow, outflow) + amount, err := GetAmount(inflow, outflow) + if err != nil { + return fmt.Errorf("could not parse amount from (%s/%s): %w", inflow, outflow, err) + } //cleared := record[10] @@ -88,20 +94,38 @@ func (ynab *YNABImport) Import(r io.Reader) error { PayeeID: payeeID, Amount: amount, } - ynab.queries.CreateTransaction(ynab.Context, transaction) + _, err = ynab.queries.CreateTransaction(ynab.Context, transaction) + if err != nil { + return fmt.Errorf("could not save transaction %v: %w", transaction, err) + } + + count++ } + fmt.Printf("Imported %d transactions\n", count) + return nil } -func GetAmount(inflow string, outflow string) pgtype.Numeric { +func trimLastChar(s string) string { + r, size := utf8.DecodeLastRuneInString(s) + if r == utf8.RuneError && (size == 0 || size == 1) { + size = 0 + } + return s[:len(s)-size] +} + +func GetAmount(inflow string, outflow string) (pgtype.Numeric, error) { // Remove currency - inflow = inflow[:len(inflow)-1] - outflow = outflow[:len(outflow)-1] + inflow = strings.Replace(trimLastChar(inflow), ",", ".", 1) + outflow = strings.Replace(trimLastChar(outflow), ",", ".", 1) num := pgtype.Numeric{} - num.Set(inflow) - return num + err := num.Set(inflow) + if err != nil { + return num, fmt.Errorf("Could not inflow %s: %w", inflow, err) + } + return num, nil } func (ynab *YNABImport) GetAccount(name string) (*postgres.Account, error) { diff --git a/postgres/conn.go b/postgres/conn.go index 3020548..84de83b 100644 --- a/postgres/conn.go +++ b/postgres/conn.go @@ -39,3 +39,12 @@ func Connect(server string, user string, password string, database string) (*Que return New(connPG), nil } + +func (tx Transaction) GetAmount() float64 { + var amount float64 + err := tx.Amount.AssignTo(&amount) + if err != nil { + panic(err) + } + return amount +} diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index 6534cc1..966acaa 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -7,8 +7,10 @@ RETURNING *; -- name: GetTransactionsForBudget :many SELECT transactions.* FROM transactions LEFT JOIN accounts ON accounts.id = transactions.account_id -WHERE accounts.budget_id = $1; +WHERE accounts.budget_id = $1 +ORDER BY transactions.date DESC; -- name: GetTransactionsForAccount :many SELECT transactions.* FROM transactions -WHERE transactions.account_id = $1; \ No newline at end of file +WHERE transactions.account_id = $1 +ORDER BY transactions.date DESC; \ No newline at end of file diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index 18d39fa..3dba4de 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -49,6 +49,7 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa const getTransactionsForAccount = `-- name: GetTransactionsForAccount :many SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.account_id, transactions.payee_id FROM transactions WHERE transactions.account_id = $1 +ORDER BY transactions.date DESC ` func (q *Queries) GetTransactionsForAccount(ctx context.Context, accountID uuid.UUID) ([]Transaction, error) { @@ -82,6 +83,7 @@ const getTransactionsForBudget = `-- name: GetTransactionsForBudget :many SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.account_id, transactions.payee_id FROM transactions LEFT JOIN accounts ON accounts.id = transactions.account_id WHERE accounts.budget_id = $1 +ORDER BY transactions.date DESC ` func (q *Queries) GetTransactionsForBudget(ctx context.Context, budgetID uuid.UUID) ([]Transaction, error) { diff --git a/web/budget.html b/web/budget.html index 54b26b2..12ed47c 100644 --- a/web/budget.html +++ b/web/budget.html @@ -17,9 +17,9 @@