digits-2023-10-15/digits-work-sample-go.d/transaction.go

95 lines
2.2 KiB
Go

package analyzer
import (
"encoding/json"
"errors"
"fmt"
"os"
)
// Transaction represents a transaction from our upstream source.
// URL: https://catalog.data.gov/dataset/purchase-card-pcard-fiscal-year-2014
type Transaction struct {
Category string `json:"MerchantCategory"`
Vendor string
Description string
AgencyName string
CardholderLastName string
TransactionDate string
Amount Amount `json:",string"`
YearMonth string
CardholderFirstInitial string
AgencyNumber string
PostedDate string
}
func (trn Transaction) String() string {
if trn.isRefund() {
return trn.stringifyRefund()
}
return trn.stringifyExpense()
}
func (trn Transaction) stringifyRefund() string {
amount := trn.Amount * -1.0
return fmt.Sprintf("%s refunded %s %s", trn.Vendor, trn.stringifyCardholder(), amount.FormatUSD())
}
func (trn Transaction) stringifyExpense() string {
return fmt.Sprintf("%s spent %s at %s", trn.stringifyCardholder(), trn.Amount.FormatUSD(), trn.Vendor)
}
func (trn Transaction) stringifyCardholder() string {
return fmt.Sprintf("%s. %s", trn.CardholderFirstInitial, trn.CardholderLastName)
}
func (trn Transaction) isRefund() bool {
return trn.Amount < 0
}
// Transactions represents a list of Transaction
type Transactions []Transaction
func (trns Transactions) expenses() Transactions {
result := make(Transactions, 0, len(trns))
for i := range trns {
if !trns[i].isRefund() {
result = append(result, trns[i])
}
}
return result
}
// Sum adds all transactions together.
func (trns Transactions) Sum() Amount {
result := Amount(0.0)
for i := range trns {
result += trns[i].Amount
}
return result
}
// Count is the number of unique Transactions.
func (trns Transactions) Count() int {
return len(trns)
}
func TransactionsFromFile(path string) (Transactions, error) {
jsonFile, err := os.Open(path)
if err != nil {
return nil, err
}
defer jsonFile.Close()
var transactions Transactions
if err := json.NewDecoder(jsonFile).Decode(&transactions); err != nil {
return nil, err
}
return transactions, nil
}
func TransactionsFromURLs(url ...string) (Transactions, error) {
return nil, errors.New("not implemented")
}