From a5f7e8785e676e69e5722331ab62de60595b7367 Mon Sep 17 00:00:00 2001 From: Martin Hansen Date: Mon, 16 Sep 2024 16:12:57 +0200 Subject: [PATCH] feat(ynab): delay setting Some banks change transaction IDs after some time, use this setting to trade real-time updates with reliability if needed. commit-id:a747bfc4 ghstack-source-id: ad19b761beb0dd5c0fef3d2bd9a07d58dfd187a4 Pull Request resolved: https://github.com/martinohansen/ynabber/pull/83 --- config.go | 5 ++++ writer/ynab/ynab.go | 13 +++++---- writer/ynab/ynab_test.go | 60 +++++++++++++++++++++++----------------- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/config.go b/config.go index 7814690..53c6a2d 100644 --- a/config.go +++ b/config.go @@ -137,6 +137,11 @@ type YNAB struct { // example: 2006-01-02 FromDate Date `envconfig:"YNAB_FROM_DATE"` + // Delay sending transaction to YNAB by this duration. This can be necessary + // if the bank changes transaction IDs after some time. Default is 0 (no + // delay). + Delay time.Duration `envconfig:"YNAB_DELAY" default:"0"` + // Set cleared status, possible values: cleared, uncleared, reconciled . // Default is uncleared for historical reasons but recommend setting this // to cleared because ynabber transactions are cleared by bank. diff --git a/writer/ynab/ynab.go b/writer/ynab/ynab.go index a471096..e1fb532 100644 --- a/writer/ynab/ynab.go +++ b/writer/ynab/ynab.go @@ -123,12 +123,15 @@ func (w Writer) toYNAB(t ynabber.Transaction) (Ytransaction, error) { }, nil } -// validTransaction checks if date is within the limits of YNAB and w.Config. +// validTransaction checks if date is within the limits of YNAB and +// ynabber.Config. func (w Writer) validTransaction(date time.Time) bool { - fiveYearsAgo := time.Now().AddDate(-5, 0, 0) - return !date.Before(fiveYearsAgo) && - !date.Before(time.Time(w.Config.YNAB.FromDate)) && - !date.After(time.Now()) + now := time.Now() + fiveYearsAgo := now.AddDate(-5, 0, 0) + fromDate := time.Time(w.Config.YNAB.FromDate) + delay := w.Config.YNAB.Delay + + return date.After(fiveYearsAgo) && date.After(fromDate) && date.Before(now.Add(-delay)) } func (w Writer) Bulk(t []ynabber.Transaction) error { diff --git a/writer/ynab/ynab_test.go b/writer/ynab/ynab_test.go index 24a5058..b99e283 100644 --- a/writer/ynab/ynab_test.go +++ b/writer/ynab/ynab_test.go @@ -162,46 +162,56 @@ func TestYnabberToYNAB(t *testing.T) { } func TestValidTransaction(t *testing.T) { - fromDate := time.Now().AddDate(-1, 0, 0) - mockFromDate := ynabber.Date(fromDate) - writer := Writer{ - Config: &ynabber.Config{ - YNAB: ynabber.YNAB{ - FromDate: mockFromDate, - }, - }, - } + yesterday := time.Now().AddDate(-1, 0, 0) + writer := Writer{Config: &ynabber.Config{}, logger: nil} tests := []struct { - name string - date time.Time - want bool + name string + date time.Time + fromDate time.Time + delay time.Duration + want bool }{ { - name: "Yesterday", - date: time.Now().AddDate(0, 0, -1), - want: true, + name: "Yesterday", + date: time.Now().AddDate(0, 0, -1), + fromDate: yesterday, + delay: 0, // Default value + want: true, }, { - name: "Tomorrow", - date: time.Now().AddDate(0, 0, 1), - want: false, + name: "Day before yesterday (25h delay)", + date: time.Now().AddDate(0, 0, -2), + fromDate: yesterday, + delay: 25 * time.Hour, + want: true, }, { - name: "5 years ago", - date: time.Now().AddDate(-5, 0, 0), - want: false, + name: "Tomorrow", + date: time.Now().AddDate(0, 0, 1), + fromDate: yesterday, + want: false, }, { - name: "Before FromDate", - date: fromDate.AddDate(0, 0, -1), - want: false, + name: "5 years ago", + date: time.Now().AddDate(-5, 0, 0), + fromDate: yesterday, + want: false, + }, + { + name: "Before FromDate", + date: yesterday.AddDate(0, 0, -1), + fromDate: yesterday, + want: false, }, } for _, tt := range tests { t.Run(tt.name, func(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 { - t.Errorf("validTransaction() = %v, want %v", got, tt.want) + t.Errorf("got = %v, want %v", got, tt.want) } }) }