package http import ( "context" "encoding/csv" "fmt" "io" "time" "git.javil.eu/jacob1123/budgeteer/postgres" "github.com/google/uuid" "github.com/jackc/pgtype" ) type YNABImport struct { Context context.Context accounts []postgres.Account payees []postgres.Payee queries *postgres.Queries budgetID uuid.UUID } func NewYNABImport(q *postgres.Queries, budgetID uuid.UUID) (*YNABImport, error) { accounts, err := q.GetAccounts(context.Background(), uuid.UUID{}) if err != nil { return nil, err } payees, err := q.GetPayees(context.Background(), uuid.UUID{}) if err != nil { return nil, err } return &YNABImport{ Context: context.Background(), accounts: accounts, payees: payees, queries: q, budgetID: budgetID, }, nil } func (ynab *YNABImport) Import(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) } for _, record := range csvData { accountName := record[0] account, err := ynab.GetAccount(accountName) if err != nil { return fmt.Errorf("could not get account %s: %w", accountName, err) } //flag := record[1] dateString := record[2] date, err := time.Parse("02.01.2006", dateString) if err != nil { return fmt.Errorf("could not parse date %s: %w", dateString, err) } payeeName := record[3] payeeID, err := ynab.GetPayee(payeeName) if err != nil { return fmt.Errorf("could not get payee %s: %w", payeeName, err) } //category := record[4] //also in 5 + 6 split by group/category memo := record[7] outflow := record[8] inflow := record[9] amount := GetAmount(inflow, outflow) //cleared := record[10] transaction := postgres.CreateTransactionParams{ Date: date, Memo: memo, AccountID: account.ID, PayeeID: payeeID, Amount: amount, } ynab.queries.CreateTransaction(ynab.Context, transaction) } return nil } func GetAmount(inflow string, outflow string) pgtype.Numeric { // Remove currency inflow = inflow[:len(inflow)-1] outflow = outflow[:len(outflow)-1] num := pgtype.Numeric{} num.Set(inflow) return num } func (ynab *YNABImport) GetAccount(name string) (*postgres.Account, error) { for _, acc := range ynab.accounts { if acc.Name == name { return &acc, nil } } account, err := ynab.queries.CreateAccount(ynab.Context, name) if err != nil { return nil, err } ynab.accounts = append(ynab.accounts, account) return &account, nil } func (ynab *YNABImport) GetPayee(name string) (uuid.NullUUID, error) { if name == "" { return uuid.NullUUID{}, nil } for _, pay := range ynab.payees { if pay.Name == name { return uuid.NullUUID{UUID: pay.ID, Valid: true}, nil } } payee, err := ynab.queries.CreatePayee(ynab.Context, name) if err != nil { return uuid.NullUUID{}, err } ynab.payees = append(ynab.payees, payee) return uuid.NullUUID{UUID: payee.ID, Valid: true}, nil }