From 74211a3c029a157dbd9499b3fe1d29333a8a3a1d Mon Sep 17 00:00:00 2001 From: William Carroll Date: Fri, 7 Feb 2020 21:33:08 +0000 Subject: [PATCH] Support serde for Monzo and YNAB transaction structs Define transaction structs for both Monzo and YNAB. Each package has a `main` function that runs some shallow but preliminary round-trip tests for the serializers and decoders. The fixtures.json file that each of them is referencing has been ignored in case either contains confidential data of which I'm unaware. --- .gitignore | 4 +- monzo_ynab/monzo/serde.go | 82 +++++++++++++++++++++++++++++++++++++++ monzo_ynab/ynab/serde.go | 52 +++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 monzo_ynab/monzo/serde.go create mode 100644 monzo_ynab/ynab/serde.go diff --git a/.gitignore b/.gitignore index 83bf215fa..b13385077 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,6 @@ Vundle.vim # Python __pycache__ -*.class \ No newline at end of file +*.class +/monzo_ynab/ynab/fixture.json +/monzo_ynab/monzo/fixture.json diff --git a/monzo_ynab/monzo/serde.go b/monzo_ynab/monzo/serde.go new file mode 100644 index 000000000..a38585eca --- /dev/null +++ b/monzo_ynab/monzo/serde.go @@ -0,0 +1,82 @@ +// This package hosts the serialization and deserialization logic for all of the +// data types with which our application interacts from the Monzo API. +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "time" +) + +type TxMetadata struct { + FasterPayment string `json:"faster_payment"` + FpsPaymentId string `json:"fps_payment_id"` + Insertion string `json:"insertion"` + Notes string `json:"notes"` + Trn string `json:"trn"` +} + +type TxCounterparty struct { + AccountNumber string `json:"account_number"` + Name string `json:"name"` + SortCode string `json:"sort_code"` + UserId string `json:"user_id"` +} + +type Transaction struct { + Id string `json:"id"` + Created time.Time `json:"created"` + Description string `json:"description"` + Amount int `json:"amount"` + Currency string `json:"currency"` + Notes string `json:"notes"` + Metadata TxMetadata + AccountBalance int `json:"account_balance"` + International interface{} `json:"international"` + Category string `json:"category"` + IsLoad bool `json:"is_load"` + Settled time.Time `json:"settled"` + LocalAmount int `json:"local_amount"` + LocalCurrency string `json:"local_currency"` + Updated time.Time `json:"updated"` + AccountId string `json:"account_id"` + UserId string `json:"user_id"` + Counterparty TxCounterparty `json:"counterparty"` + Scheme string `json:"scheme"` + DedupeId string `json:"dedupe_id"` + Originator bool `json:"originator"` + IncludeInSpending bool `json:"include_in_spending"` + CanBeExcludedFromBreakdown bool `json:"can_be_excluded_from_breakdown"` + CanBeMadeSubscription bool `json:"can_be_made_subscription"` + CanSplitTheBill bool `json:"can_split_the_bill"` + CanAddToTab bool `json:"can_add_to_tab"` + AmountIsPending bool `json:"amount_is_pending"` + // Fees interface{} `json:"fees"` + // Merchant interface `json:"merchant"` + // Labels interface{} `json:"labels"` + // Attachments interface{} `json:"attachments"` + // Categories interface{} `json:"categories"` +} + +// Attempts to encode a Monzo transaction struct into a string. +func serializeTx(tx *Transaction) (string, error) { + x, err := json.Marshal(tx) + return string(x), err +} + +// Attempts to parse a string encoding a transaction presumably sent from a +// Monzo server. +func deserializeTx(x string) (*Transaction, error) { + target := &Transaction{} + err := json.Unmarshal([]byte(x), target) + return target, err +} + +func main() { + b, _ := ioutil.ReadFile("./fixture.json") + tx := string(b) + target, _ := deserializeTx(tx) + out, _ := serializeTx(target) + fmt.Println(out) +} diff --git a/monzo_ynab/ynab/serde.go b/monzo_ynab/ynab/serde.go new file mode 100644 index 000000000..53dd33e83 --- /dev/null +++ b/monzo_ynab/ynab/serde.go @@ -0,0 +1,52 @@ +// This package hosts the serialization and deserialization logic for all of the +// data types with which our application interacts from the YNAB API. +package main + +import ( + "encoding/json" + "fmt" + "time" +) + +type Transaction struct { + Id string `json:"id"` + Date time.Time `json:"date"` + Amount int `json:"amount"` + Memo string `json:"memo"` + Cleared string `json:"cleared"` + Approved bool `json:"approved"` + FlagColor string `json:"flag_color"` + AccountId string `json:"account_id"` + AccountName string `json:"account_name"` + PayeeId string `json:"payeed_id"` + PayeeName string `json:"payee_name"` + CategoryId string `json:"category_id"` + CategoryName string `json:"category_name"` + Deleted bool `json:"deleted"` + // TransferAccountId interface{} `json:"transfer_account_id"` + // TransferTransactionId interface{} `json:"transfer_transaction_id"` + // MatchedTransactionId interface{} `json:"matched_transaction_id"` + // ImportId interface{} `json:"import_id"` + // Subtransactions interface{} `json:"subtransactions"` +} + +// Attempts to encode a YNAB transaction into a string. +func serializeTx(tx *Transaction) (string, error) { + x, err := json.Marshal(tx) + return string(x), err +} + +// Attempts to parse a string encoding a transaction presumably sent from a +// YNAB server. +func deserializeTx(x string) (*Transaction, error) { + target := &Transaction{} + err := json.Unmarshal([]byte(x), target) + return target, err +} + +func main() { + target, _ := deserializeTx(tx) + out, _ := serializeTx(target) + fmt.Println(out) + fmt.Println(ynabOut) +}