aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2022-02-01 21:42:09 +0100
committerMartin Polden <mpolden@mpolden.no>2022-02-01 21:42:09 +0100
commit6579727041faacd0d69a7f71bb551315561a1117 (patch)
tree5d5086a67baacf97f82f9fd9307608167001d905
parent8fa1cf07a8523747665052eef450d487a023b80e (diff)
komplett: Handle new format
-rw-r--r--record/komplett/komplett.go76
-rw-r--r--record/komplett/komplett_test.go1
-rw-r--r--record/komplett/testdata/test.json22
3 files changed, 58 insertions, 41 deletions
diff --git a/record/komplett/komplett.go b/record/komplett/komplett.go
index e68560d..a95363c 100644
--- a/record/komplett/komplett.go
+++ b/record/komplett/komplett.go
@@ -3,35 +3,35 @@ package komplett
import (
"encoding/json"
"io"
+ "regexp"
"strconv"
- "strings"
"time"
"github.com/mpolden/journal/record"
)
-const (
- decimalSeparator = "."
- thousandSeparator = " "
- timeLayout = "02.01.2006"
+const timeLayout = "02.01.2006"
+
+var (
+ separatorPattern = regexp.MustCompile("[.,]")
+ cleanPattern = regexp.MustCompile(`kr|NOK|"|\s+|\p{Z}+`)
)
// Reader implements a reader for Komplett-encoded (JSON) records.
-type Reader struct {
- rd io.Reader
- replacer *strings.Replacer
-}
+type Reader struct{ rd io.Reader }
type jsonTime time.Time
type jsonAmount int64
type jsonRecord struct {
- Time jsonTime `json:"FormattedPostingDate"`
- BillingAmount jsonAmount `json:"BillingAmount"`
- Amount jsonAmount `json:"Amount"`
- FormattedAmount string `json:"FormattedAmount"`
- Text string `json:"DisplayDescription"`
+ // The JSON from their API keeps shuffling field names. Each number corresponds to a version of the format
+ Time1 jsonTime `json:"FormattedPostingDate"`
+ Time2 jsonTime `json:"TransactionDate"`
+ Amount1 jsonAmount `json:"BillingAmount"`
+ Amount2 jsonAmount `json:"FormattedAmount"`
+ Text1 string `json:"DisplayDescription"`
+ Text2 string `json:"MerchantName"`
}
func (t *jsonTime) UnmarshalJSON(data []byte) error {
@@ -48,17 +48,18 @@ func (t *jsonTime) UnmarshalJSON(data []byte) error {
}
func (a *jsonAmount) UnmarshalJSON(data []byte) error {
- parts := strings.Split(string(data), decimalSeparator)
- s := parts[0]
+ text := cleanPattern.ReplaceAllString(string(data), "")
+ parts := separatorPattern.Split(text, -1)
+ firstPart := parts[0]
if len(parts) == 2 {
- s += parts[1]
+ firstPart += parts[1]
if len(parts[1]) == 1 {
- s += "0"
+ firstPart += "0"
}
} else {
- s += "00"
+ firstPart += "00"
}
- n, err := strconv.ParseInt(s, 10, 64)
+ n, err := strconv.ParseInt(firstPart, 10, 64)
if err != nil {
return err
}
@@ -68,10 +69,7 @@ func (a *jsonAmount) UnmarshalJSON(data []byte) error {
// NewReader returns a new reader for Komplett-encoded records.
func NewReader(rd io.Reader) *Reader {
- return &Reader{
- rd: rd,
- replacer: strings.NewReplacer(decimalSeparator, "", thousandSeparator, ""),
- }
+ return &Reader{rd: rd}
}
func (r *Reader) Read() ([]record.Record, error) {
@@ -81,25 +79,21 @@ func (r *Reader) Read() ([]record.Record, error) {
}
var rs []record.Record
for _, jr := range jrs {
- amount := jr.BillingAmount
- if amount == 0 { // New format
- var b strings.Builder
- for _, r := range jr.FormattedAmount {
- if r == '-' {
- b.WriteRune(r)
- } else if r >= '0' && r <= '9' {
- b.WriteRune(r)
- }
- }
- if n, err := strconv.ParseInt(b.String(), 10, 64); err == nil {
- amount = jsonAmount(n)
- } else {
- return nil, err
- }
+ amount := jr.Amount1
+ if amount == 0 {
+ amount = jr.Amount2
+ }
+ txTime := time.Time(jr.Time1)
+ if txTime.IsZero() {
+ txTime = time.Time(jr.Time2)
+ }
+ text := jr.Text1
+ if text == "" {
+ text = jr.Text2
}
rs = append(rs, record.Record{
- Time: time.Time(jr.Time),
- Text: jr.Text,
+ Time: txTime,
+ Text: text,
Amount: int64(amount),
})
}
diff --git a/record/komplett/komplett_test.go b/record/komplett/komplett_test.go
index d2ffb59..5193e60 100644
--- a/record/komplett/komplett_test.go
+++ b/record/komplett/komplett_test.go
@@ -80,6 +80,7 @@ func TestRead(t *testing.T) {
{date(2019, 10, 30), "Uttak av bonus", 6000},
{date(2020, 12, 14), "Varekjøp", -9900},
{date(2020, 12, 28), "Varekjøp (5,00 EUR / Kurs 10,74000)", -5370},
+ {date(2022, 2, 1), "Varekjøp 2", -29601},
}
if len(rs) != len(tests) {
t.Fatalf("want %d records, got %d", len(tests), len(rs))
diff --git a/record/komplett/testdata/test.json b/record/komplett/testdata/test.json
index bce8a9e..0350e64 100644
--- a/record/komplett/testdata/test.json
+++ b/record/komplett/testdata/test.json
@@ -58,5 +58,27 @@
"FormattedAmount": "kr -53,70",
"FormattedPostingDate": "28.12.2020",
"FormattedDefermentExpiryDate": null
+ },
+ {
+ "TransactionId": "42",
+ "TransactionType": 79,
+ "IsReserved": true,
+ "DeferPaymentUrl": null,
+ "IsDeferred": false,
+ "CanDefer": false,
+ "BookingDate": null,
+ "RecipientAccountNr": null,
+ "ExchangeRate": null,
+ "DeferTransactionInfo": null,
+ "OriginalTransactionInfo": null,
+ "Amount": "296,01 NOK",
+ "AmountCurrency": "NOK",
+ "BillingAmount": "-kr 296,01",
+ "BillingAmountCurrency": "NOK",
+ "MerchantName": "Varekjøp 2",
+ "Description": null,
+ "TransactionRef": "ref",
+ "TransactionDate": "01.02.2022",
+ "TransactionDateRaw": "2/1/2022"
}
]