module

Finfry

Finfry is a small command-line budget & expense tracker built on the Jargon CLI shard. This file is the library entry point; the executable lives in src/cli.cr. See finfry --help for available commands.

Constants

ACCOUNT_POLICIES = ["strict", "guard", "off"] of ::String

How finfry reacts to a posting naming an account that isn't yet "known" (declared in the chart or already used by a posting).

DEFAULT_ASSET_ACCOUNT = "Assets:Checking"

Default account money is paid from / received into when not specified.

DEFAULT_CHART = ["Assets:Checking", "Assets:Cash", "Liabilities:CreditCard", "Income:Salary", "Expenses:Food", "Expenses:Housing", "Expenses:Transport", "Expenses:Health", "Expenses:Entertainment", "Expenses:Misc"] of ::String

Starter chart seeded into a brand-new ledger so strict mode is usable immediately. Existing ledgers are unaffected — Database.from_json falls back to the empty property default, and their known accounts come from the postings already recorded.

VERSION = "0.2.0"

Class methods

balance_sheet(balances : Hash(String, Int64)) : BalanceSheet

Build a balance sheet from raw account balances (account => signed cents).

Source
in_subtree?(account : String, prefix : String) : Bool

True if account is prefix itself or a descendant of it. Accounts are hierarchical, colon-separated ("Expenses:Food:Coffee"), so a prefix match must respect the ":" boundary — "Expenses:Foodie" is not under "Expenses:Food".

Source
postings_for(kind : String, amount : Int64, account : String, counter : String) : Array(Posting)

Build the balanced posting pair for a kind of transaction. account is the categorization account (Expenses/Income, or the destination of a transfer); counter is the money account (the asset/liability paid from or received into, or the source of a transfer). Both the CLI commands and the AI entry path funnel through here so balance is always assembled the same way.

Source
recurring_items(transactions : Array(Transaction)) : Array(RecurringItem)

Reduce a set of transactions to current recurring commitments. Each recurring stream is identified by its description (or, if blank, its income/expense accounts), and only the most recent occurrence in a stream counts — so recording Netflix every month yields one Netflix commitment, not twelve.

Source

Nested types