ledger

package module
v0.0.0-...-8da493b Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2022 License: MIT Imports: 13 Imported by: 0

README

Ledger

Package Ledger contains a parser for Ledger CLI transactions.

This should support the spec more-or-less fully for simple transactions, but I did not add support for automated transactions or budgeting.

Additionally, I properly implemented String on everything so you can dump Transactions to a file and read it with Ledger again.

Finally, there are a bunch of functions and methods for dealing with transactions that should be helpful to anyone trying to use this for real work.

Documentation

Overview

Package Ledger contains a parser for Ledger CLI transactions.

This should support the spec more-or-less fully for simple transactions, but I did not add support for automated transactions or budgeting.

Additionally, I properly implemented String on everything so you can dump Transactions to a file and read it with Ledger again.

Finally, there are a bunch of functions and methods for dealing with transactions that should be helpful to anyone trying to use this for real work.

Index

Constants

View Source
const (
	StatusUndefined = status(iota)
	StatusPending
	StatusClear
)

Status constants for Transaction.Status

Variables

View Source
var ErrImproperInterleave = errors.New("Ledger file transaction and directive lists do not interleave properly.")

ErrImproperInterleave is returned by File.Format if the lists do not interleave properly. Caused by bad FoundBefore values in the directives.

View Source
var IDService <-chan string

IDService is a read only channel that will return a short ID string every time you read it.

Functions

func FormatSums

func FormatSums(accounts map[string]int64, pad string) [][]string

FormatSums takes a map of accounts to sums and turns it into a list of name/value pairs with indentation applied to the names.

func FormatValue

func FormatValue(v int64) string

FormatValue takes a amount of money in thousandths of a cent and formats it for display. Rounding is done via the round to even method.

func FormatValueNumber

func FormatValueNumber(v int64) string

FormatValueNumber is exactly the same as FormatValue, but it does not add any currency indicators.

func ParseValueNumber

func ParseValueNumber(v string) (int64, error)

ParseValueNumber takes a decimal number and converts it to a integer with a precision of . Rounding is done via the round to even method.

func SumTransactions

func SumTransactions(ts []Transaction) (map[string]int64, error)

SumTransactions balances a list of transactions, and returns a map of accounts to their ending values.

Types

type Account

type Account struct {
	Name    string   // The name of this account.
	Note    string   // The contents of the note subdirective.
	Aliases []string // One string for each alias subdirective.
	Payees  []string // One string for each payee subdirective.
	Default bool     // True if the default subdirective is present.

	FoundBefore    int          // The transaction index this account precedes.
	DirectiveIndex int          // The index of this account in the list of all directives. Calling File.Format may ruin this relationship.
	Location       lex.Location // Line number where this account starts.
}

Account is a simple type representing an account directive. Subdirectives containing value expressions are not included.

type BalanceError

type BalanceError struct {
	T int
	L lex.Location
}

BalanceError is returned by functions that validate transactions in some way when the transaction isn't balanced.

func (BalanceError) Error

func (err BalanceError) Error() string

type Directive

type Directive struct {
	Type        string       // The keyword that starts the directive.
	Argument    string       // Any remaining content that was on the first line of the directive.
	Lines       []string     // Subsequent indented lines. Stored here unparsed.
	FoundBefore int          // The transaction index this directive precedes.
	Location    lex.Location // Line number this directive begins at.
}

Directive is a simple type to represent a partially parsed, but not validated, command directive.

func (*Directive) Compare

func (d *Directive) Compare(d2 Directive) bool

Compare two directives to see if they are identical.

func (*Directive) String

func (d *Directive) String() string

type ErrMalformedAccountName

type ErrMalformedAccountName struct {
	Name     string
	Location lex.Location
}

ErrMalformedAccountName is returned by File.Accounts if an account name is malformed.

func (ErrMalformedAccountName) Error

func (err ErrMalformedAccountName) Error() string

type File

type File struct {
	T []Transaction
	D []Directive
}

File hold a parsed ledger file stored as lists of Directives and Transactions.

func (*File) Accounts

func (f *File) Accounts() ([]Account, error)

Accounts returns a slice of all account directives, in the order they are found in D. If any account directives fail to parse, Accounts returns an error.

func (*File) Format

func (f *File) Format(w io.Writer) error

Format writes out a ledger file, interleaving the transactions and directives according to the "FoundBefore" values in the directives. The directive list is sorted on the FoundBefore values as part of this operation.

func (*File) Matched

func (f *File) Matched(account string, matchers []Matcher) []Transaction

Matched finds transactions by regexp on the description, and returns a slice of found transactions with postings and description modified by the first successful match from matchers. Only transactions with a posting containing the given account will be modified.

func (*File) ParseMatchers

func (f *File) ParseMatchers() ([]Matcher, error)

ParseMatchers parses matchers from the directives of this ledger file.

func (*File) Payees

func (f *File) Payees() ([]Payee, error)

Payees returns a slice of all payee directives, in the order they are found in D. if any payee directives fail to parse, Payees returns an error.

type Matcher

type Matcher struct {
	R       *regexp.Regexp
	Account string
	Payee   string
}

Matcher associates an account or a payee with a regexp to match against a transaction description.

type MultipleNullError

type MultipleNullError struct {
	T int
	L lex.Location
}

MultipleNullError is returned by functions that validate transactions in some way when the transaction has more than one null posting.

func (MultipleNullError) Error

func (err MultipleNullError) Error() string

type Payee

type Payee struct {
	Name    string   // The payee name to substitute if matched
	Aliases []string // One string for each regexp to match with.
	Uuids   []string // One string for each uuid to check.

	FoundBefore    int          // The transaction index this directive precedes.
	DirectiveIndex int          // The index of this directive in the list of all directives. Calling File.Format may ruin this relationship.
	Location       lex.Location // Line number where this directive starts.
}

Payee is a simple type representing a payee directive.

type Posting

type Posting struct {
	Status    status //   | ! | *  (optional)
	Account   string // Account:Name
	Value     int64  // $20.00 (currently only supporting USD, in thousandths of a cent)
	Null      bool   // True if the Value is implied. Value may or may not contain a valid amount.
	Assert    int64  // = $20.00
	HasAssert bool
	Note      string // ; Stuff
}

Posting is a single line item in a Transaction.

func (*Posting) String

func (p *Posting) String() string

type Transaction

type Transaction struct {
	Date        time.Time // 2020/10/10
	ClearDate   time.Time // =2020/10/10 (optional)
	Status      status    //   | ! | * (optional)
	Code        string    // ( Stuff ) (optional)
	Description string    // Spent monie on stuf

	Postings []Posting

	Comments []string // ; Stuff...

	Tags    map[string]bool   // ; :tag:tag:tag:
	KVPairs map[string]string // ; Key: Value

	Location lex.Location // The line number where the transaction starts.
}

Transaction is a single transaction from a ledger file.

func (*Transaction) Balance

func (t *Transaction) Balance() (bool, map[string]int64)

Balance ensures that all postings in the transaction add up to 0 or there is a single null posting. Returns false, nil if there is more than one null posting, otherwise returns the ending balances of all accounts with postings and true if the transaction balances to 0 or there was a null posting.

func (*Transaction) Canonicalize

func (t *Transaction) Canonicalize() error

Canonicalize takes a transaction and sets the value of any null postings that may exist to the required value to make it balance. Returns an error if there are multiple null postings or if there are no null postings and the transaction does not balance.

func (*Transaction) CleanCopy

func (t *Transaction) CleanCopy() *Transaction

CleanCopy takes a perfect copy of the transaction object, safe for editing without making any changes to the parent.

func (*Transaction) Match

func (t *Transaction) Match(account string, matchers []Matcher) bool

Match replaces the given account in the postings with the first matcher that succeeds. If that matcher has a payee, that payee will replace this transaction's description. Returns true if any matcher succeeded, or false otherwise

func (*Transaction) String

func (t *Transaction) String() string

type TransactionDateSorter

type TransactionDateSorter []Transaction

TransactionDateSorter is a helper for sorting a list of transactions by date.

func (TransactionDateSorter) Len

func (tds TransactionDateSorter) Len() int

func (TransactionDateSorter) Less

func (tds TransactionDateSorter) Less(i, j int) bool

func (TransactionDateSorter) Swap

func (tds TransactionDateSorter) Swap(i, j int)

Directories

Path Synopsis
lex
This is a greatly simplified and stripped down version of the core Lexer code that many of my parsers used for years.
This is a greatly simplified and stripped down version of the core Lexer code that many of my parsers used for years.

Jump to

Keyboard shortcuts

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