budget

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2024 License: MIT Imports: 12 Imported by: 0

README

Busy People Budget

The Busy People Budget is designed to provide personalized insights into financial health with only a few lines of code. The tool includes net worth calculation, built-in reports, and offers the flexibility to create a custom financial summary. The README contains example code and a tutorial; let me know your thoughts through GitHub Issues and Pull Requests!

Install

go get github.com/cassamajor/budget

Usage

Simple Summary: Income v Expenses
package main

import "github.com/cassamajor/budget"

func main() {
	budget.DefaultBudget()
}

Set your Personal Access Token as an environment variable, and execute the program:

export YNAB_PAT=personal-access-token
go run main.go

Output:

Ready to Assign: $529.15
Assigned: $3,703.49
Underfunded: $5,390.30
Income: $3,812.50
Expenses: $1,737.59
Advanced Summary: Detailed and Personalized Insights

The example can be found here: examples/advanced/main.go

Set your Personal Access Token as an environment variable, and execute the program:

export YNAB_PAT=personal-access-token
go run examples/advanced/main.go

Output:

Our Net Worth is $272,005.98.

We have $19,881.21 cash in our bank accounts.

We have $2,079.27 saved towards medical expenses.
We have $25,874.76 saved towards retirement.
We have $159,581.51 equity in our home.

We need an additional $5,390.30 to fund this month. At the end of the month, we will have roughly -$1,682.89 remaining. Unplanned purchases are not accounted for in this estimate.

We have $170,918.49 remaining on our mortgage.
We have $33,067.28 in student loans.
We have $18,315.82 in auto loans.
Tutorial: Brief Introduction to Features and Functionality

WithMonth and WithToken are functional options that can be passed into the NewBudget function.

If no options are passed, the current month is used, and the token is read from the environment variable YNAB_PAT.

month := budget.WithMonth("2024-07-01")
token := budget.WithToken("personal-access-token")

b, err := budget.NewBudget(month, token)

The Budget method returns a Summary. Included in the Summary are two structs: Month and Accounts.

Account balances are stored in the Accounts struct, and will always reflect current amounts; it is not affected by the WithMonth option.

Income and expense totals are stored in the Month struct. Both structs contain built-in reports that print to the console.

summary := b.Budget()

summary.Month.Report()
summary.Accounts.Report()

The NetWorth method is attached to the Accounts struct. It calculates the sum of all assets and liabilities and returns a NetWorth struct. The NetWorth struct has a Total method that returns the total net worth.

nw := summary.Accounts.NetWorth()
nw.Total()

AccountMap is a global variable that provides the ability to query accounts by their name.

c := budget.AccountMap["Checking"]

fmt.Println(c.Balance)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AccountMap = make(map[string]Account)

AccountMap allows an Account to be queried by name.

Functions

func AccessData

func AccessData[T Month | Accounts](jsonData []byte) *T

AccessData reads the JSON data and unmarshals it into the provided struct.

func AccessDataFiles

func AccessDataFiles[T Month | Accounts](fileLocation string) *T

AccessDataFiles reads the JSON data from the specified file and unmarshals it into the provided struct.

func DefaultBudget

func DefaultBudget() int

DefaultBudget creates a new Budget with the default options and prints a summary for the Month.

func FormatCurrency added in v0.2.0

func FormatCurrency(n float64) string

FormatCurrency adds a comma to a float64 value and prepends a dollar sign.

func GetURL

func GetURL(apiToken, url string) ([]byte, error)

GetURL builds and executes a request to the specified YNAB API endpoint.

func WithMonth

func WithMonth(t string) option

WithMonth sets the month for the Budget. Expects a string in the format `2024-12-01`, or `current`. If this is not set, NewBudget will use the current month.

func WithToken

func WithToken(t string) option

WithToken sets the API token for the Budget. If this is not set, NewBudget will attempt to use the `YNAB_PAT` environment variable.

Types

type Account

type Account struct {
	ID      string
	Name    string
	Type    string
	Balance Balance
}

Account contains the details of a specific account.

func (Account) String

func (a Account) String() string

String returns the Name, Balance, and Type as a string. The ID has been omitted.

type AccountData

type AccountData struct {
	Data struct {
		Accounts []struct {
			Id                  string     `json:"id"`
			Name                string     `json:"name"`
			Type                string     `json:"type"`
			OnBudget            bool       `json:"on_budget"`
			Closed              bool       `json:"closed"`
			Note                *string    `json:"note"`
			Balance             int        `json:"balance"`
			ClearedBalance      int        `json:"cleared_balance"`
			UnclearedBalance    int        `json:"uncleared_balance"`
			TransferPayeeId     string     `json:"transfer_payee_id"`
			DirectImportLinked  bool       `json:"direct_import_linked"`
			DirectImportInError bool       `json:"direct_import_in_error"`
			LastReconciledAt    *time.Time `json:"last_reconciled_at"`
			DebtOriginalBalance *int       `json:"debt_original_balance"`
			DebtInterestRates   struct {
				Field1 int `json:"2021-10-01,omitempty"`
				Field2 int `json:"2022-06-01,omitempty"`
				Field3 int `json:"2022-11-01,omitempty"`
				Field4 int `json:"2023-09-01,omitempty"`
			} `json:"debt_interest_rates"`
			DebtMinimumPayments struct {
				Field1 int `json:"2021-10-01,omitempty"`
				Field2 int `json:"2022-06-01,omitempty"`
				Field3 int `json:"2022-11-01,omitempty"`
				Field4 int `json:"2023-09-01,omitempty"`
			} `json:"debt_minimum_payments"`
			DebtEscrowAmounts struct {
				Field1 int `json:"2022-08-01,omitempty"`
				Field2 int `json:"2021-10-01,omitempty"`
				Field3 int `json:"2022-11-01,omitempty"`
				Field4 int `json:"2023-09-01,omitempty"`
			} `json:"debt_escrow_amounts"`
			Deleted bool `json:"deleted"`
		} `json:"accounts"`
		ServerKnowledge int `json:"server_knowledge"`
	} `json:"data"`
}

AccountData https://api.ynab.com/v1/#/Accounts/getAccounts

type Accounts

type Accounts []Account

Accounts is a collection of Account structs.

func (*Accounts) NetWorth added in v0.2.0

func (a *Accounts) NetWorth() NetWorth

NetWorth calculates the balance for all Account types.

func (*Accounts) Report

func (a *Accounts) Report()

Report prints the account balance for each account.

func (*Accounts) UnmarshalJSON

func (a *Accounts) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals the JSON data retrieved from YNAB's API into the Accounts struct.

type Assets added in v0.2.0

type Assets struct {
	Cash     Balance
	Checking Balance
	Savings  Balance
	Other    Balance
}

Assets contains the calculated balances for each Account type.

func (Assets) Total added in v0.2.0

func (a Assets) Total() Balance

Total calculates the balance across all Assets.

type Balance

type Balance float64

Balance represents the balance of an account. The String method formats the account balance with a dollar sign and comma(s).

func NewRat

func NewRat(a int) Balance

NewRat converts an `int` into an `int64` and is fed into `big.NewRat` to avoid floating point errors.

func (Balance) Float64

func (b Balance) Float64() float64

Float64 returns the Balance value as a float64.

func (Balance) String

func (b Balance) String() string

String returns the value of Balance with a dollar sign and comma(s).

type Budget

type Budget struct {
	APIToken string
	Month    string
}

Budget contains the API token and month for the budget.

func NewBudget

func NewBudget(opts ...option) (*Budget, error)

NewBudget creates a new Budget with the provided options.

func (*Budget) Budget

func (b *Budget) Budget() Summary

Budget retrieves the account and month data for the budget.

func (*Budget) GetAccounts

func (b *Budget) GetAccounts() ([]byte, error)

GetAccounts retrieves account data from the YNAB API.

func (*Budget) GetMonth

func (b *Budget) GetMonth() ([]byte, error)

GetMonth retrieves the month data from the YNAB API.

type Liabilities added in v0.2.0

type Liabilities struct {
	AutoLoans     Balance
	CreditCards   Balance
	StudentLoans  Balance
	Mortgages     Balance
	LinesOfCredit Balance
	PersonalLoans Balance
	MedicalDebt   Balance
	Other         Balance
}

Liabilities contains balances for Accounts that have an outstanding balance

func (Liabilities) Total added in v0.2.0

func (l Liabilities) Total() Balance

Total calculates the balance across all Liabilities.

type Month

type Month struct {
	Date          string
	ReadyToAssign Balance
	Assigned      Balance
	Underfunded   Balance
	Income        Balance
	Expenses      Balance
}

Month contains the overall financial picture for a specific month.

func (Month) Report

func (m Month) Report()

Report prints the current state of finances for a Month.

func (*Month) UnmarshalJSON

func (m *Month) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals the JSON data retrieved from YNAB's API into the Month struct.

type MonthData

type MonthData struct {
	Data struct {
		Month struct {
			Month        string `json:"month"`
			Note         string `json:"note"`
			Income       int    `json:"income"`
			Budgeted     int    `json:"budgeted"`
			Activity     int    `json:"activity"`
			ToBeBudgeted int    `json:"to_be_budgeted"`
			AgeOfMoney   int    `json:"age_of_money"`
			Deleted      bool   `json:"deleted"`
			Categories   []struct {
				Id                      string      `json:"id"`
				CategoryGroupId         string      `json:"category_group_id"`
				CategoryGroupName       string      `json:"category_group_name"`
				Name                    string      `json:"name"`
				Hidden                  bool        `json:"hidden"`
				OriginalCategoryGroupId interface{} `json:"original_category_group_id"`
				Note                    *string     `json:"note"`
				Budgeted                int         `json:"budgeted"`
				Activity                int         `json:"activity"`
				Balance                 int         `json:"balance"`
				GoalType                *string     `json:"goal_type"`
				GoalDay                 *int        `json:"goal_day"`
				GoalCadence             *int        `json:"goal_cadence"`
				GoalCadenceFrequency    *int        `json:"goal_cadence_frequency"`
				GoalCreationMonth       *string     `json:"goal_creation_month"`
				GoalTarget              int         `json:"goal_target"`
				GoalTargetMonth         *string     `json:"goal_target_month"`
				GoalPercentageComplete  *int        `json:"goal_percentage_complete"`
				GoalMonthsToBudget      *int        `json:"goal_months_to_budget"`
				GoalUnderFunded         *int        `json:"goal_under_funded"`
				GoalOverallFunded       *int        `json:"goal_overall_funded"`
				GoalOverallLeft         *int        `json:"goal_overall_left"`
				Deleted                 bool        `json:"deleted"`
			} `json:"categories"`
		} `json:"month"`
	} `json:"data"`
}

MonthData https://api.ynab.com/v1/#/Months/getBudgetMonth

type NetWorth

type NetWorth struct {
	Assets      Assets
	Liabilities Liabilities
}

NetWorth contains the combined balances Assets and Liabilities.

func (NetWorth) Total

func (n NetWorth) Total() Balance

Total calculates the total Net Worth.

type Summary

type Summary struct {
	Accounts *Accounts
	Month    *Month
}

Summary contains financial data for each account and the specified month.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL