expense

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MPL-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package expense implements bwx expense-report tagging, filtering, and rendering. Reports are emergent — entries tagged `expense-report:<id>` in their note are the report's contents; the report id is the tag value.

Index

Constants

View Source
const (
	ExpenseReportKey = "expense-report"
	MerchantKey      = "merchant"
	ReimbursableKey  = "reimbursable"
)

Variables

This section is empty.

Functions

func ComposeTags

func ComposeTags(reportId, merchant string, reimbursable bool) []string

ComposeTags returns a slice of `key:value` tag tokens ready to be joined into an entry's note via the existing composeMemo path. Merchant strings are underscore-encoded to survive the space-delimited tag grammar — the reverse is handled by MerchantFromNote.

func HasReport

func HasReport(note, reportId string) bool

HasReport reports whether the note carries expense-report:<reportId>.

func MerchantFromNote

func MerchantFromNote(note string) string

MerchantFromNote returns the merchant tag value (decoded from underscore encoding), or "".

func ReimbursableFromNote

func ReimbursableFromNote(note string) bool

ReimbursableFromNote reports whether the entry carries reimbursable:true.

func RenderCSV

func RenderCSV(out io.Writer, r Report) error

RenderCSV writes RFC-4180 CSV. encoding/csv handles quoting.

func RenderHTML

func RenderHTML(out io.Writer, r Report) error

func RenderJSON

func RenderJSON(out io.Writer, r Report) error

func RenderQIF

func RenderQIF(out io.Writer, r Report) error

RenderQIF emits a minimal QIF !Type:Cash block. One ^-terminated record per Line. T is negated (QIF cash records expect outflow as negative).

func RenderText

func RenderText(out io.Writer, r Report) error

func ReportIdFromNote

func ReportIdFromNote(note string) string

ReportIdFromNote returns the expense-report tag value from a note, or "" if no such tag exists. Strips a leading `;` and any free-form prose.

Types

type Filter

type Filter struct {
	ReportId string
	From, To time.Time
}

Filter selects which entries land in a report.

type Line

type Line struct {
	Date         time.Time
	Payee        string
	Merchant     string
	Account      string
	Category     string
	Amount       *big.Rat
	Currency     string
	Reimbursable bool
	Note         string
	EntryId      string
}

Line is one row in the rendered report — flattens an entry down to its expense-side posting (the debit into an Expenses:* / Liabilities:* account). Postings that net to zero or non-expense legs are ignored.

type Report

type Report struct {
	ReportId    string
	From, To    time.Time
	GeneratedAt time.Time
	Lines       []Line
	Totals      Totals
}

Report is the fully-built, render-ready view.

func Build

func Build(entries []model.Entry, f Filter) (Report, error)

Build filters entries to those tagged expense-report:<ReportId> within the optional date window and emits a Report.

type Totals

type Totals struct {
	Grand                     *big.Rat
	Reimbursable              *big.Rat
	NonReimbursable           *big.Rat
	ByCategory                map[string]*big.Rat
	ByCurrency                map[string]*big.Rat
	ReimbursableByCurrency    map[string]*big.Rat
	NonReimbursableByCurrency map[string]*big.Rat
}

Totals summarises a Report. Grand / Reimbursable / NonReimbursable are only meaningful for single-currency reports — for multi-currency reports consumers should walk ByCurrency / ReimbursableByCurrency / etc.

Jump to

Keyboard shortcuts

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