models

package
v5.5.1 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2024 License: AGPL-3.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAccountNameNotUnique    = errors.New("the account name must be unique for the budget")
	ErrAccountCannotBeOnBudget = errors.New("the account cannot be set to on budget")
)
View Source
var (
	ErrGeneral          = errors.New("an error occurred on the server during your request")
	ErrResourceNotFound = errors.New("there is no")
)
View Source
var (
	ErrAvailabilityMonthTooEarly                      = errors.New("availability month must not be earlier than the month of the transaction")
	ErrSourceDoesNotEqualDestination                  = errors.New("source and destination accounts for a transaction must be different")
	ErrTransactionAmountNotPositive                   = errors.New("the transaction amount must be positive")
	ErrTransactionNoInternalAccounts                  = errors.New("a transaction between two external accounts is not possible")
	ErrTransactionTransferBetweenOnBudgetWithEnvelope = errors.New("transfers between two on-budget accounts must not have an envelope set. Such a transaction would be incoming and outgoing for this envelope at the same time, which is not possible")
	ErrTransactionInvalidSourceAccount                = errors.New("invalid source account")
	ErrTransactionInvalidDestinationAccount           = errors.New("invalid destination account")
)
View Source
var DB *gorm.DB
View Source
var ErrCategoryNameNotUnique = errors.New("the category name must be unique for the budget")
View Source
var ErrEnvelopeNameNotUnique = errors.New("the envelope name must be unique for the category")
View Source
var ErrGoalAmountNotPositive = errors.New("goal amounts must be larger than zero")
View Source
var ErrMonthConfigMonthNotUnique = errors.New("you can not create multiple month configs for the same envelope and month")
View Source
var Registry = []Model{
	Account{},
	Budget{},
	Category{},
	Envelope{},
	Goal{},
	MatchRule{},
	MonthConfig{},
	Transaction{},
}

The "Registry" is a slice of all models available

It is maintained so that operations that affect all models do not need to explicitly iterate over every single model, increasing the risk of forgetting something when adding a new model

Functions

func Connect

func Connect(dsn string) error

Connect opens the SQLite database and configures the connection pool.

Types

type Account

type Account struct {
	DefaultModel
	Budget             Budget    `json:"-"`
	BudgetID           uuid.UUID `gorm:"uniqueIndex:account_name_budget_id"`
	Name               string    `gorm:"uniqueIndex:account_name_budget_id"`
	Note               string
	OnBudget           bool
	External           bool
	InitialBalance     decimal.Decimal `gorm:"type:DECIMAL(20,8)"`
	InitialBalanceDate *time.Time
	Archived           bool
	ImportHash         string // A SHA256 hash of a unique combination of values to use in duplicate detection for imports
}

Account represents an asset account, e.g. a bank account.

func (Account) Balance

func (a Account) Balance(db *gorm.DB, time time.Time) (balance decimal.Decimal, err error)

Balance calculates the balance of the account at a specific point in time, including all transactions

func (*Account) BeforeCreate

func (a *Account) BeforeCreate(tx *gorm.DB) error

func (*Account) BeforeSave

func (a *Account) BeforeSave(_ *gorm.DB) error

BeforeSave ensures consistency for the account

It enforces OnBudget to be false when the account is external.

It trims whitespace from all strings

func (*Account) BeforeUpdate

func (a *Account) BeforeUpdate(tx *gorm.DB) error

BeforeUpdate verifies the state of the account before committing an update to the database.

func (Account) Export added in v5.3.0

func (Account) Export() (json.RawMessage, error)

Returns all accounts on this instance for export

func (Account) GetBalanceMonth

func (a Account) GetBalanceMonth(db *gorm.DB, month types.Month) (balance, available decimal.Decimal, err error)

GetBalanceMonth calculates the balance and available sums for a specific month.

The balance Decimal is the actual account balance, factoring in all transactions before the end of the month. The available Decimal is the sum that is available for budgeting at the end of the specified month.

TODO: Get rid of this in favor of Balance()

func (Account) RecentEnvelopes

func (a Account) RecentEnvelopes(db *gorm.DB) ([]*uuid.UUID, error)

SetRecentEnvelopes returns the most common envelopes used in the last 50 transactions where the account is the destination account.

The list is sorted by decending frequency of the envelope being used. If two envelopes appear with the same frequency, the order is undefined since sqlite does not have ordering by datetime with more than second precision.

If creation times are more than a second apart, ordering is well defined.

func (Account) ReconciledBalance

func (a Account) ReconciledBalance(db *gorm.DB, time time.Time) (balance decimal.Decimal, err error)

ReconciledBalance calculates the reconciled balance at a specific point in time

func (Account) Transactions

func (a Account) Transactions(db *gorm.DB) []Transaction

Transactions returns all transactions for this account.

type AggregatedTransaction

type AggregatedTransaction struct {
	Amount                     decimal.Decimal
	Date                       time.Time
	SourceAccountOnBudget      bool
	DestinationAccountOnBudget bool
}

type Budget

type Budget struct {
	DefaultModel
	Name     string `json:"name"`
	Note     string `json:"note"`
	Currency string `json:"currency"`
}

Budget represents a budget

A budget is the highest level of organization in Envelope Zero, all other resources reference it directly or transitively.

func (Budget) Allocated

func (b Budget) Allocated(db *gorm.DB, month types.Month) (allocated decimal.Decimal, err error)

Allocated calculates the sum that has been budgeted for a specific month.

func (Budget) Balance

func (b Budget) Balance(tx *gorm.DB) (balance decimal.Decimal, err error)

Balance calculates the balance for a budget.

func (*Budget) BeforeSave

func (b *Budget) BeforeSave(_ *gorm.DB) error

func (Budget) Export added in v5.3.0

func (Budget) Export() (json.RawMessage, error)

Returns all budgets on this instance for export

func (Budget) Income

func (b Budget) Income(db *gorm.DB, month types.Month) (income decimal.Decimal, err error)

Income returns the income for a budget in a given month.

type Category

type Category struct {
	DefaultModel
	Budget   Budget    `json:"-"`
	BudgetID uuid.UUID `gorm:"uniqueIndex:category_budget_name"`
	Name     string    `gorm:"uniqueIndex:category_budget_name"`
	Note     string
	Archived bool
}

Category represents a category of envelopes.

func (*Category) BeforeCreate

func (c *Category) BeforeCreate(tx *gorm.DB) error

func (*Category) BeforeSave

func (c *Category) BeforeSave(_ *gorm.DB) error

func (*Category) BeforeUpdate

func (c *Category) BeforeUpdate(tx *gorm.DB) (err error)

BeforeUpdate archives all envelopes when the category is archived.

func (*Category) Envelopes

func (c *Category) Envelopes(tx *gorm.DB) ([]Envelope, error)

func (Category) Export added in v5.3.0

func (Category) Export() (json.RawMessage, error)

Returns all categories on this instance for export

type DefaultModel

type DefaultModel struct {
	ID uuid.UUID `json:"id" example:"65392deb-5e92-4268-b114-297faad6cdce"` // UUID for the resource
	Timestamps
}

DefaultModel is the base model for most models in Envelope Zero. As EnvelopeMonth uses the Envelope ID and the Month as primary key, the timestamps are managed in the Timestamps struct.

func (*DefaultModel) BeforeCreate

func (m *DefaultModel) BeforeCreate(_ *gorm.DB) error

BeforeCreate is set to generate a UUID for the resource.

type EZContext

type EZContext string
const (
	DBContextURL EZContext = "ez-backend-url"
)

type Envelope

type Envelope struct {
	DefaultModel
	Category   Category  `json:"-"`
	CategoryID uuid.UUID `gorm:"uniqueIndex:envelope_category_name"`
	Name       string    `gorm:"uniqueIndex:envelope_category_name"`
	Note       string
	Archived   bool
}

Envelope represents an envelope in your budget.

func (Envelope) Balance

func (e Envelope) Balance(db *gorm.DB, month types.Month) (decimal.Decimal, error)

Balance calculates the balance of an Envelope in a specific month.

func (*Envelope) BeforeCreate

func (e *Envelope) BeforeCreate(tx *gorm.DB) error

func (*Envelope) BeforeSave

func (e *Envelope) BeforeSave(_ *gorm.DB) error

func (*Envelope) BeforeUpdate

func (e *Envelope) BeforeUpdate(tx *gorm.DB) (err error)

BeforeUpdate verifies the state of the envelope before committing an update to the database.

func (Envelope) Export added in v5.3.0

func (Envelope) Export() (json.RawMessage, error)

Returns all envelopes on this instance for export

func (Envelope) Month

func (e Envelope) Month(db *gorm.DB, month types.Month) (EnvelopeMonth, error)

Month calculates the month specific values for an envelope and returns an EnvelopeMonth and allocation ID for them.

func (Envelope) Spent

func (e Envelope) Spent(db *gorm.DB, month types.Month) decimal.Decimal

Spent returns the amount spent for the month the time.Time instance is in.

type EnvelopeMonth

type EnvelopeMonth struct {
	Envelope
	Spent      decimal.Decimal `json:"spent" example:"73.12"`      // The amount spent over the whole month
	Balance    decimal.Decimal `json:"balance" example:"12.32"`    // The balance at the end of the monht
	Allocation decimal.Decimal `json:"allocation" example:"85.44"` // The amount of money allocated
}

EnvelopeMonth contains data about an Envelope for a specific month.

type Goal

type Goal struct {
	DefaultModel
	Name       string `gorm:"uniqueIndex:goal_name_envelope"`
	Note       string
	Envelope   Envelope        `json:"-"`
	EnvelopeID uuid.UUID       `gorm:"uniqueIndex:goal_name_envelope"`
	Amount     decimal.Decimal `gorm:"type:DECIMAL(20,8)"` // The target for the goal
	Month      types.Month
	Archived   bool
}

func (*Goal) AfterSave

func (g *Goal) AfterSave(_ *gorm.DB) error

func (*Goal) BeforeCreate

func (g *Goal) BeforeCreate(tx *gorm.DB) error

func (*Goal) BeforeSave

func (g *Goal) BeforeSave(_ *gorm.DB) error

func (*Goal) BeforeUpdate

func (g *Goal) BeforeUpdate(tx *gorm.DB) (err error)

func (Goal) Export added in v5.3.0

func (Goal) Export() (json.RawMessage, error)

Returns all goals on this instance for export

type MatchRule

type MatchRule struct {
	DefaultModel
	AccountID uuid.UUID
	Priority  uint
	Match     string
}

func (*MatchRule) BeforeCreate

func (m *MatchRule) BeforeCreate(tx *gorm.DB) error

func (*MatchRule) BeforeUpdate

func (m *MatchRule) BeforeUpdate(tx *gorm.DB) (err error)

func (MatchRule) Export added in v5.3.0

func (MatchRule) Export() (json.RawMessage, error)

Returns all match rules on this instance for export

type Model added in v5.3.0

type Model interface {
	Export() (json.RawMessage, error) // All instances of this model for export.
}

Model is an interface that

type MonthConfig

type MonthConfig struct {
	Timestamps
	EnvelopeID uuid.UUID       `gorm:"primaryKey"` // ID of the envelope
	Month      types.Month     `gorm:"primaryKey"`
	Allocation decimal.Decimal `gorm:"type:DECIMAL(20,8)"`
	Note       string
}

func (*MonthConfig) BeforeSave

func (m *MonthConfig) BeforeSave(_ *gorm.DB) error

func (MonthConfig) Export added in v5.3.0

func (MonthConfig) Export() (json.RawMessage, error)

Returns all match rules on this instance for export

type Timestamps

type Timestamps struct {
	CreatedAt time.Time       `json:"createdAt" example:"2022-04-02T19:28:44.491514Z"`                                             // Time the resource was created
	UpdatedAt time.Time       `json:"updatedAt" example:"2022-04-17T20:14:01.048145Z"`                                             // Last time the resource was updated
	DeletedAt *gorm.DeletedAt `json:"deletedAt" gorm:"index" example:"2022-04-22T21:01:05.058161Z" swaggertype:"primitive,string"` // Time the resource was marked as deleted
}

Timestamps only contains the timestamps that gorm sets automatically to enable other primary keys than ID.

type Transaction

type Transaction struct {
	DefaultModel
	SourceAccountID       uuid.UUID `gorm:"check:source_destination_different,source_account_id != destination_account_id"`
	SourceAccount         Account   `json:"-"`
	DestinationAccountID  uuid.UUID
	DestinationAccount    Account `json:"-"`
	EnvelopeID            *uuid.UUID
	Envelope              Envelope        `json:"-"`
	Date                  time.Time       // Time of day is currently only used for sorting
	Amount                decimal.Decimal `gorm:"type:DECIMAL(20,8)"`
	Note                  string
	ReconciledSource      bool        // Is the transaction reconciled in the source account?
	ReconciledDestination bool        // Is the transaction reconciled in the destination account?
	AvailableFrom         types.Month // Only used for income transactions. Defaults to the transaction date.
	ImportHash            string      // The SHA256 hash of a unique combination of values to use in duplicate detection when importing transactions
}

Transaction represents a transaction between two accounts.

func (*Transaction) BeforeCreate

func (t *Transaction) BeforeCreate(tx *gorm.DB) error

func (*Transaction) BeforeSave

func (t *Transaction) BeforeSave(tx *gorm.DB) (err error)

BeforeSave

  • ensures that ReconciledSource and ReconciledDestination are set to valid values
  • trims whitespace from string fields

func (*Transaction) BeforeUpdate

func (t *Transaction) BeforeUpdate(tx *gorm.DB) (err error)

func (Transaction) Export added in v5.3.0

func (Transaction) Export() (json.RawMessage, error)

Returns all transactions on this instance for export

Jump to

Keyboard shortcuts

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