Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: validate delay config #86

Merged
merged 2 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/ynabber/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ func main() {

setupLogging(cfg.Debug)
slog.Info("starting...", "version", versioninfo.Short())
slog.Debug("", "config", cfg)

ynabber := ynabber.Ynabber{}
for _, reader := range cfg.Readers {
Expand Down
2 changes: 1 addition & 1 deletion reader/nordigen/nordigen.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ func (r Reader) toYnabbers(a ynabber.Account, t nordigen.AccountTransactions) ([
y := []ynabber.Transaction{}
for _, v := range t.Transactions.Booked {
transaction, err := r.toYnabber(a, v)
r.logger.Debug("mapping transaction", "from", v, "to", transaction)
if err != nil {
return nil, err
}

// Append transaction
r.logger.Debug("mapped transaction", "from", v, "to", transaction)
y = append(y, transaction)
}
return y, nil
Expand Down
55 changes: 28 additions & 27 deletions writer/ynab/ynab.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const maxPayeeSize int = 100 // Max size of payee field in YNAB API

var space = regexp.MustCompile(`\s+`) // Matches all whitespace characters

// Ytransaction is a single YNAB transaction
type Ytransaction struct {
// Transaction is a single YNAB transaction
type Transaction struct {
AccountID string `json:"account_id"`
Date string `json:"date"`
Amount string `json:"amount"`
Expand All @@ -31,9 +31,9 @@ type Ytransaction struct {
Approved bool `json:"approved"`
}

// Ytransactions is multiple YNAB transactions
type Ytransactions struct {
Transactions []Ytransaction `json:"transactions"`
// Transactions is multiple YNAB transactions
type Transactions struct {
Transactions []Transaction `json:"transactions"`
}

type Writer struct {
Expand Down Expand Up @@ -78,54 +78,55 @@ func makeID(t ynabber.Transaction) string {
return fmt.Sprintf("YBBR:%x", hash)[:32]
}

func (w Writer) toYNAB(t ynabber.Transaction) (Ytransaction, error) {
accountID, err := accountParser(t.Account.IBAN, w.Config.YNAB.AccountMap)
func (w Writer) toYNAB(source ynabber.Transaction) (Transaction, error) {
accountID, err := accountParser(source.Account.IBAN, w.Config.YNAB.AccountMap)
if err != nil {
return Ytransaction{}, err
return Transaction{}, err
}
logger := w.logger.With("account", accountID)

date := t.Date.Format("2006-01-02")
date := source.Date.Format("2006-01-02")

// Trim consecutive spaces from memo and truncate if too long
memo := strings.TrimSpace(space.ReplaceAllString(t.Memo, " "))
memo := strings.TrimSpace(space.ReplaceAllString(source.Memo, " "))
if len(memo) > maxMemoSize {
logger.Warn("memo too long", "transaction", t, "max_size", maxMemoSize)
w.logger.Warn("memo too long", "transaction", source, "max_size", maxMemoSize)
memo = memo[0:(maxMemoSize - 1)]
}

// Trim consecutive spaces from payee and truncate if too long
payee := strings.TrimSpace(space.ReplaceAllString(string(t.Payee), " "))
payee := strings.TrimSpace(space.ReplaceAllString(string(source.Payee), " "))
if len(payee) > maxPayeeSize {
logger.Warn("payee too long", "transaction", t, "max_size", maxPayeeSize)
w.logger.Warn("payee too long", "transaction", source, "max_size", maxPayeeSize)
payee = payee[0:(maxPayeeSize - 1)]
}

// If SwapFlow is defined check if the account is configured to swap inflow
// to outflow. If so swap it by using the Negate method.
if w.Config.YNAB.SwapFlow != nil {
for _, account := range w.Config.YNAB.SwapFlow {
if account == t.Account.IBAN {
t.Amount = t.Amount.Negate()
if account == source.Account.IBAN {
source.Amount = source.Amount.Negate()
}
}
}

return Ytransaction{
ImportID: makeID(t),
transaction := Transaction{
ImportID: makeID(source),
AccountID: accountID,
Date: date,
Amount: t.Amount.String(),
Amount: source.Amount.String(),
PayeeName: payee,
Memo: memo,
Cleared: string(w.Config.YNAB.Cleared),
Approved: false,
}, nil
}
w.logger.Debug("mapped transaction", "from", source, "to", transaction)
return transaction, nil
}

// validTransaction checks if date is within the limits of YNAB and
// checkTransactionDateValidity checks if date is within the limits of YNAB and
// ynabber.Config.
func (w Writer) validTransaction(date time.Time) bool {
func (w Writer) checkTransactionDateValidity(date time.Time) bool {
now := time.Now()
fiveYearsAgo := now.AddDate(-5, 0, 0)
fromDate := time.Time(w.Config.YNAB.FromDate)
Expand All @@ -140,11 +141,11 @@ func (w Writer) Bulk(t []ynabber.Transaction) error {
failed := 0

// Build array of transactions to send to YNAB
y := new(Ytransactions)
y := new(Transactions)
for _, v := range t {

// Skip transactions that are not within the valid date range.
if !w.validTransaction(v.Date) {
if !w.checkTransactionDateValidity(v.Date) {
w.logger.Debug("date out of range", "transaction", v)
skipped += 1
continue
}
Expand All @@ -153,15 +154,15 @@ func (w Writer) Bulk(t []ynabber.Transaction) error {
if err != nil {
// If we fail to parse a single transaction we log it but move on so
// we don't halt the entire program.
w.logger.Error("parsing", "transaction", v, "err", err)
w.logger.Error("mapping to YNAB", "transaction", transaction, "err", err)
failed += 1
continue
}
y.Transactions = append(y.Transactions, transaction)
}

if len(t) == 0 || len(y.Transactions) == 0 {
w.logger.Info("No transactions to write")
w.logger.Info("no transactions to write")
return nil
}

Expand Down
8 changes: 4 additions & 4 deletions writer/ynab/ynab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func TestYnabberToYNAB(t *testing.T) {
tests := []struct {
name string
args args
want Ytransaction
want Transaction
wantErr bool
}{
{
Expand All @@ -113,7 +113,7 @@ func TestYnabberToYNAB(t *testing.T) {
Amount: 10000,
},
},
want: Ytransaction{
want: Transaction{
AccountID: "abc",
Date: "0001-01-01",
Amount: "10000",
Expand All @@ -136,7 +136,7 @@ func TestYnabberToYNAB(t *testing.T) {
Amount: 10000,
},
},
want: Ytransaction{
want: Transaction{
AccountID: "abc",
Date: "0001-01-01",
Amount: "-10000",
Expand Down Expand Up @@ -210,7 +210,7 @@ func TestValidTransaction(t *testing.T) {
writer.Config.YNAB.FromDate = ynabber.Date(tt.fromDate)
writer.Config.YNAB.Delay = tt.delay

if got := writer.validTransaction(tt.date); got != tt.want {
if got := writer.checkTransactionDateValidity(tt.date); got != tt.want {
t.Errorf("got = %v, want %v", got, tt.want)
}
})
Expand Down
Loading