models

package
v2.12.2 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2023 License: AGPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrAllocationZero = errors.New("allocation amounts must be non-zero. Instead of setting to zero, delete the Allocation")

Functions

func Migrate

func Migrate(db *gorm.DB) error

Migrate migrates all models to the schema defined in the code.

Types

type Account

type Account struct {
	DefaultModel
	AccountCreate
	Budget            Budget          `json:"-"`
	Balance           decimal.Decimal `json:"balance" gorm:"-" example:"2735.17"`
	ReconciledBalance decimal.Decimal `json:"reconciledBalance" gorm:"-" example:"2539.57"`
	Links             struct {
		Self         string `json:"self" example:"https://example.com/api/v1/accounts/af892e10-7e0a-4fb8-b1bc-4b6d88401ed2"`
		Transactions string `json:"transactions" example:"https://example.com/api/v1/transactions?account=af892e10-7e0a-4fb8-b1bc-4b6d88401ed2"`
	} `json:"links" gorm:"-"`
}

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

func (*Account) AfterFind added in v2.5.0

func (a *Account) AfterFind(tx *gorm.DB) (err error)

func (*Account) AfterSave added in v2.5.0

func (a *Account) AfterSave(tx *gorm.DB) (err error)

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

func (*Account) BeforeSave

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

BeforeSave sets OnBudget to false when External is true.

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.

func (Account) RecentEnvelopes

func (a Account) RecentEnvelopes(db *gorm.DB) (envelopes []Envelope, err error)

RecentEnvelopes returns the most common envelopes used in the last 10 transactions where the account is the destination account.

The list is sorted by decending frequency of the envelope being used.

func (Account) Self added in v2.6.4

func (a Account) Self() string

func (Account) SumReconciled

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

Transactions returns all transactions for this account.

func (Account) Transactions

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

Transactions returns all transactions for this account.

func (Account) WithCalculations

func (a Account) WithCalculations(db *gorm.DB) (Account, error)

type AccountCreate

type AccountCreate struct {
	Name               string          `json:"name" example:"Cash" default:""`
	Note               string          `json:"note" example:"Money in my wallet" default:""`
	BudgetID           uuid.UUID       `json:"budgetId" example:"550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
	OnBudget           bool            `json:"onBudget" example:"true" default:"false"` // Always false when external: true
	External           bool            `json:"external" example:"false" default:"false"`
	InitialBalance     decimal.Decimal `json:"initialBalance" example:"173.12" default:"0"`
	InitialBalanceDate *time.Time      `json:"initialBalanceDate" example:"2017-05-12T00:00:00Z"`
	Hidden             bool            `json:"hidden" example:"true" default:"false"`
	ImportHash         string          `json:"importHash" example:"867e3a26dc0baf73f4bff506f31a97f6c32088917e9e5cf1a5ed6f3f84a6fa70" default:""` // The SHA256 hash of a unique combination of values to use in duplicate detection
}

type AggregatedTransaction

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

type Allocation

type Allocation struct {
	DefaultModel
	AllocationCreate
	Envelope Envelope `json:"-"`
	Links    struct {
		Self string `json:"self" example:"https://example.com/api/v1/allocations/902cd93c-3724-4e46-8540-d014131282fc"`
	} `json:"links" gorm:"-"`
}

Allocation represents the allocation of money to an Envelope for a specific month.

func (*Allocation) AfterFind added in v2.5.0

func (a *Allocation) AfterFind(tx *gorm.DB) (err error)

func (*Allocation) AfterSave added in v2.5.0

func (a *Allocation) AfterSave(tx *gorm.DB) (err error)

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

func (*Allocation) BeforeSave added in v2.6.3

func (a *Allocation) BeforeSave(_ *gorm.DB) (err error)

BeforeSave verifies that the amount is non-zero. To remove an allocation, it has to be deleted instead of set to 0.

func (Allocation) Self added in v2.6.4

func (a Allocation) Self() string

type AllocationCreate

type AllocationCreate struct {
	Month  types.Month     `json:"month" gorm:"uniqueIndex:allocation_month_envelope" example:"2021-12-01T00:00:00.000000Z"` // Only year and month of this timestamp are used, everything else is ignored. This will always be set to 00:00 UTC on the first of the specified month
	Amount decimal.Decimal ``                                                                                                // The maximum value is "999999999999.99999999", swagger unfortunately rounds this.
	/* 132-byte string literal not displayed */
	EnvelopeID uuid.UUID `json:"envelopeId" gorm:"uniqueIndex:allocation_month_envelope" example:"a0909e84-e8f9-4cb6-82a5-025dff105ff2"`
}

type Budget

type Budget struct {
	DefaultModel
	BudgetCreate
	Balance decimal.Decimal `json:"balance" gorm:"-" example:"3423.42"` // DEPRECATED. Will be removed in API v2, see https://github.com/envelope-zero/backend/issues/526.
	Links   struct {
		Self             string `json:"self" example:"https://example.com/api/v1/budgets/550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
		Accounts         string `json:"accounts" example:"https://example.com/api/v1/accounts?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
		Categories       string `json:"categories" example:"https://example.com/api/v1/categories?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
		Envelopes        string `json:"envelopes" example:"https://example.com/api/v1/envelopes?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
		Transactions     string `json:"transactions" example:"https://example.com/api/v1/transactions?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf"`
		Month            string `json:"month" example:"https://example.com/api/v1/budgets/550dc009-cea6-4c12-b2a5-03446eb7b7cf/YYYY-MM"`                        // This uses 'YYYY-MM' for clients to replace with the actual year and month.
		GroupedMonth     string `json:"groupedMonth" example:"https://example.com/api/v1/months?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf&month=YYYY-MM"`     // This uses 'YYYY-MM' for clients to replace with the actual year and month.
		MonthAllocations string `json:"monthAllocations" example:"https://example.com/api/v1/months?budget=550dc009-cea6-4c12-b2a5-03446eb7b7cf&month=YYYY-MM"` // This uses 'YYYY-MM' for clients to replace with the actual year and month.
	} `json:"links" gorm:"-"`
}

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) AfterFind added in v2.5.0

func (b *Budget) AfterFind(tx *gorm.DB) (err error)

func (*Budget) AfterSave added in v2.5.0

func (b *Budget) AfterSave(tx *gorm.DB) (err error)

AfterSave does the same as AfterFind, so we just call it.

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) 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.

func (Budget) Month

func (b Budget) Month(db *gorm.DB, month types.Month) (Month, error)

Month calculates the month overview for this month.

func (Budget) Self added in v2.6.4

func (b Budget) Self() string

type BudgetCreate

type BudgetCreate struct {
	Name     string `json:"name" example:"Morre's Budget" default:""`
	Note     string `json:"note" example:"My personal expenses" default:""`
	Currency string `json:"currency" example:"€" default:""`
}

type BudgetMonth

type BudgetMonth struct {
	ID        uuid.UUID       `json:"id" example:"1e777d24-3f5b-4c43-8000-04f65f895578"` // The ID of the Budget
	Name      string          `json:"name" example:"Groceries"`                          // The name of the Budget
	Month     types.Month     `json:"month" example:"2006-05-01T00:00:00.000000Z"`
	Budgeted  decimal.Decimal `json:"budgeted" example:"2100"`
	Income    decimal.Decimal `json:"income" example:"2317.34"`
	Available decimal.Decimal `json:"available" example:"217.34"`
	Envelopes []EnvelopeMonth `json:"envelopes"`
}

func (BudgetMonth) Self added in v2.6.4

func (b BudgetMonth) Self() string

type Category

type Category struct {
	DefaultModel
	CategoryCreate
	Budget Budget `json:"-"` // The budget the category belongs to
	Links  struct {
		Self      string `json:"self" example:"https://example.com/api/v1/categories/3b1ea324-d438-4419-882a-2fc91d71772f"`
		Envelopes string `json:"envelopes" example:"https://example.com/api/v1/envelopes?category=3b1ea324-d438-4419-882a-2fc91d71772f"`
	} `json:"links" gorm:"-"`
}

Category represents a category of envelopes.

func (*Category) AfterFind added in v2.5.0

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

func (*Category) AfterSave added in v2.5.0

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

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

func (Category) Self added in v2.6.4

func (c Category) Self() string

type CategoryCreate

type CategoryCreate struct {
	Name     string    `json:"name" gorm:"uniqueIndex:category_budget_name" example:"Saving" default:""`                        // Name of the category
	BudgetID uuid.UUID `json:"budgetId" gorm:"uniqueIndex:category_budget_name" example:"52d967d3-33f4-4b04-9ba7-772e5ab9d0ce"` // ID of the budget the category belongs to
	Note     string    `json:"note" example:"All envelopes for long-term saving" default:""`                                    // Notes about the category
	Hidden   bool      `json:"hidden" example:"true" default:"false"`                                                           // Is the category hidden?
}

type CategoryEnvelopes

type CategoryEnvelopes struct {
	Category
	Envelopes  []EnvelopeMonth `json:"envelopes"`                // Slice of all envelopes
	Balance    decimal.Decimal `json:"balance" example:"-10.13"` // Sum of the balances of the envelopes
	Allocation decimal.Decimal `json:"allocation" example:"90"`  // Sum of allocations for the envelopes
	Spent      decimal.Decimal `json:"spent" example:"100.13"`   // Sum spent for all envelopes
}

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, we the timestamps are managed in the Timestamps struct.

func (*DefaultModel) AfterFind

func (m *DefaultModel) AfterFind(_ *gorm.DB) (err error)

AfterFind updates the timestamps to use UTC as timezone, not +0000. Yes, this is different.

We already store them in UTC, but somehow reading them from the database returns them as +0000.

func (*DefaultModel) BeforeCreate

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

BeforeCreate is set to generate a UUID for the resource.

type Envelope

type Envelope struct {
	DefaultModel
	EnvelopeCreate
	Category Category `json:"-"`
	Links    struct {
		Self         string `json:"self" example:"https://example.com/api/v1/envelopes/45b6b5b9-f746-4ae9-b77b-7688b91f8166"`                     // URL of the envelope
		Allocations  string `json:"allocations" example:"https://example.com/api/v1/allocations?envelope=45b6b5b9-f746-4ae9-b77b-7688b91f8166"`   // URL for the envelope's allocations
		Month        string `json:"month" example:"https://example.com/api/v1/envelopes/45b6b5b9-f746-4ae9-b77b-7688b91f8166/YYYY-MM"`            // URL to query for month information. This will always end in 'YYYY-MM' for clients to use replace with actual numbers.
		Transactions string `json:"transactions" example:"https://example.com/api/v1/transactions?envelope=45b6b5b9-f746-4ae9-b77b-7688b91f8166"` // URL for the envelope's transactions
	} `json:"links" gorm:"-"` // Links to related resources
}

Envelope represents an envelope in your budget.

func (*Envelope) AfterFind added in v2.5.0

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

func (*Envelope) AfterSave added in v2.5.0

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

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

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) BeforeUpdate added in v2.10.1

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) Month

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

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

func (Envelope) Self added in v2.6.4

func (e Envelope) Self() string

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 EnvelopeCreate

type EnvelopeCreate struct {
	Name       string    `json:"name" gorm:"uniqueIndex:envelope_category_name" example:"Groceries" default:""`                       // Name of the envelope
	CategoryID uuid.UUID `json:"categoryId" gorm:"uniqueIndex:envelope_category_name" example:"878c831f-af99-4a71-b3ca-80deb7d793c1"` // ID of the category the envelope belongs to
	Note       string    `json:"note" example:"For stuff bought at supermarkets and drugstores" default:""`                           // Notes about the envelope
	Hidden     bool      `json:"hidden" example:"true" default:"false"`                                                               // Is the envelope hidden?
}

type EnvelopeMonth

type EnvelopeMonth struct {
	Envelope
	Month      types.Month        `json:"month" example:"1969-06-01T00:00:00.000000Z" hidden:"deprecated"` // This is always set to 00:00 UTC on the first of the month. **This field is deprecated and will be removed in v2**
	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
	Links      EnvelopeMonthLinks `json:"links"`                                                           // Linked resources
}

EnvelopeMonth contains data about an Envelope for a specific month.

type EnvelopeMonthAllocation

type EnvelopeMonthAllocation struct {
	Month      time.Time
	Allocation decimal.Decimal
}

type EnvelopeMonthConfig

type EnvelopeMonthConfig struct {
	Month         time.Time
	OverspendMode OverspendMode
}
type EnvelopeMonthLinks struct {
	Allocation string `json:"allocation" example:"https://example.com/api/v1/allocations/772d6956-ecba-485b-8a27-46a506c5a2a3"` // This is an empty string when no allocation exists
}

type Model added in v2.6.4

type Model interface {
	Self() string
}

type Month

type Month struct {
	ID         uuid.UUID           `json:"id" example:"1e777d24-3f5b-4c43-8000-04f65f895578"` // The ID of the Budget
	Name       string              `json:"name" example:"Zero budget"`                        // The name of the Budget
	Month      types.Month         `json:"month" example:"2006-05-01T00:00:00.000000Z"`       // The month
	Budgeted   decimal.Decimal     `json:"budgeted" example:"2100"`                           // The sum of all allocations for the month. **Deprecated, please use the `allocation` field**
	Income     decimal.Decimal     `json:"income" example:"2317.34"`                          // The total income for the month (sum of all incoming transactions without an Envelope)
	Available  decimal.Decimal     `json:"available" example:"217.34"`                        // The amount available to budget
	Balance    decimal.Decimal     `json:"balance" example:"5231.37"`                         // The sum of all envelope balances
	Spent      decimal.Decimal     `json:"spent" example:"133.70"`                            // The amount of money spent in this month
	Allocation decimal.Decimal     `json:"allocation" example:"1200.50"`                      // The sum of all allocations for this month
	Categories []CategoryEnvelopes `json:"categories"`                                        // A list of envelope month calculations grouped by category
}

type MonthConfig

type MonthConfig struct {
	Timestamps
	MonthConfigCreate
	EnvelopeID uuid.UUID   `json:"envelopeId" gorm:"primaryKey" example:"10b9705d-3356-459e-9d5a-28d42a6c4547"`
	Month      types.Month `json:"month" gorm:"primaryKey" example:"1969-06-01T00:00:00.000000Z"` // This is always set to 00:00 UTC on the first of the month.
	Links      struct {
		Self     string `json:"self" example:"https://example.com/api/v1/month-configs/61027ebb-ab75-4a49-9e23-a104ddd9ba6b/2017-10"` // URL for the month config
		Envelope string `json:"envelope" example:"https://example.com/api/v1/envelopes/61027ebb-ab75-4a49-9e23-a104ddd9ba6b"`         // URL of the envelope this config belongs to
	} `json:"links" gorm:"-"`
}

func (*MonthConfig) AfterFind added in v2.5.0

func (m *MonthConfig) AfterFind(tx *gorm.DB) (err error)

func (*MonthConfig) AfterSave added in v2.5.0

func (m *MonthConfig) AfterSave(tx *gorm.DB) (err error)

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

type MonthConfigCreate

type MonthConfigCreate struct {
	OverspendMode OverspendMode `json:"overspendMode" example:"AFFECT_ENVELOPE" default:"AFFECT_AVAILABLE"`
	Note          string        `json:"note" example:"Added 200€ here because we replaced Tim's expensive vase" default:""` // A note for the month config
}

type OverspendMode

type OverspendMode string

swagger:enum OverspendMode

const (
	AffectAvailable OverspendMode = "AFFECT_AVAILABLE"
	AffectEnvelope  OverspendMode = "AFFECT_ENVELOPE"
)

type RenameRule added in v2.11.0

type RenameRule struct {
	DefaultModel
	RenameRuleCreate
	Links struct {
		Self string `json:"self" example:"https://example.com/api/v2/rename-rules/95685c82-53c6-455d-b235-f49960b73b21"`
	} `json:"links" gorm:"-"`
}

func (*RenameRule) AfterFind added in v2.11.0

func (r *RenameRule) AfterFind(tx *gorm.DB) (err error)

func (*RenameRule) AfterSave added in v2.11.0

func (r *RenameRule) AfterSave(tx *gorm.DB) (err error)

func (RenameRule) Self added in v2.11.0

func (r RenameRule) Self() string

type RenameRuleCreate added in v2.11.0

type RenameRuleCreate struct {
	Priority  uint      `json:"priority" example:"3"`                                     // The priority of the rename rule
	Match     string    `json:"match" example:"Bank*"`                                    // The matching applied to the opposite account. This is a glob pattern. Multiple globs are allowed. Globbing is case sensitive.
	AccountID uuid.UUID `json:"accountId" example:"f9e873c2-fb96-4367-bfb6-7ecd9bf4a6b5"` // The account to map matching transactions to
}

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
	TransactionCreate
	Budget             Budget   `json:"-"`
	SourceAccount      Account  `json:"-"`
	DestinationAccount Account  `json:"-"`
	Envelope           Envelope `json:"-"`

	Links struct {
		Self string `json:"self" example:"https://example.com/api/v1/transactions/d430d7c3-d14c-4712-9336-ee56965a6673"` // URL of the transaction resource
	} `json:"links" gorm:"-"` // Links for the transaction
}

Transaction represents a transaction between two accounts.

func (*Transaction) AfterFind

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

AfterFind updates the timestamps to use UTC as timezone, not +0000. Yes, this is different.

We already store them in UTC, but somehow reading them from the database returns them as +0000.

func (*Transaction) AfterSave added in v2.5.0

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

AfterSave also sets the links so that we do not need to query the resource directly after creating or updating it.

func (*Transaction) BeforeSave

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

BeforeSave

  • sets the timezone for the Date for UTC
  • ensures that ReconciledSource and ReconciledDestination are set to valid values

func (Transaction) Self added in v2.6.4

func (t Transaction) Self() string

type TransactionCreate

type TransactionCreate struct {
	Date   time.Time       `json:"date" example:"1815-12-10T18:43:00.271152Z"`
	Amount decimal.Decimal `` // The maximum value is "999999999999.99999999", swagger unfortunately rounds this.
	/* 132-byte string literal not displayed */
	Note                  string     `json:"note" example:"Lunch" default:""`
	BudgetID              uuid.UUID  `json:"budgetId" example:"55eecbd8-7c46-4b06-ada9-f287802fb05e"`
	SourceAccountID       uuid.UUID  `` /* 155-byte string literal not displayed */
	DestinationAccountID  uuid.UUID  `json:"destinationAccountId" example:"8e16b456-a719-48ce-9fec-e115cfa7cbcc"`
	EnvelopeID            *uuid.UUID `json:"envelopeId" example:"2649c965-7999-4873-ae16-89d5d5fa972e"`
	Reconciled            bool       `json:"reconciled" example:"true" default:"false"` // DEPRECATED. Do not use, this field does not work as intended. See https://github.com/envelope-zero/backend/issues/528. Use reconciledSource and reconciledDestination instead.
	ReconciledSource      bool       `json:"reconciledSource" example:"true" default:"false"`
	ReconciledDestination bool       `json:"reconciledDestination" example:"true" default:"false"`

	AvailableFrom types.Month `json:"availableFrom" example:"2021-11-17T00:00:00Z"` // The date from which on the transaction amount is available for budgeting. Only used for income transactions. Defaults to the transaction date.

	ImportHash string `json:"importHash" example:"867e3a26dc0baf73f4bff506f31a97f6c32088917e9e5cf1a5ed6f3f84a6fa70" default:""` // The SHA256 hash of a unique combination of values to use in duplicate detection
}

Jump to

Keyboard shortcuts

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