From 10d9d7d534139198c93647a1717e6b1e0c3f6fd8 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Tue, 20 Oct 2026 18:10:47 -0600 Subject: [PATCH] P3: the cash flow statement by ASC 230 (defect 1, D-35, D-42) Direct method with the operating reconciliation and noncash schedules; it foots by construction (Lean and Kani). Every non-cash account belongs to one section; reversals net; a member or lender paying for the company is cash borrowed and spent (D-42, constructive receipt and disbursement); property a member contributes stays noncash. The bookspec seed: one loader checks every example. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj --- README.md | 181 +++++++ examples/1099-worksheet-through-as-of.toml | 30 +- examples/as-of-package-stops-at-as-of.toml | 33 +- examples/cash-flow.debt-to-equity.toml | 94 ++++ ...cash-flow.paid-on-the-companys-behalf.toml | 187 ++++++++ examples/cash-flow.part-cash-purchase.toml | 90 ++++ .../cash-flow.reversal-of-a-reversal.toml | 90 ++++ ...h-flow.reversed-property-contribution.toml | 84 ++++ .../cash-flow.two-member-llc-first-year.toml | 443 ++++++++++++++++++ examples/iif-quickbooks-journal-file.toml | 31 +- 10 files changed, 1213 insertions(+), 50 deletions(-) create mode 100644 README.md create mode 100644 examples/cash-flow.debt-to-equity.toml create mode 100644 examples/cash-flow.paid-on-the-companys-behalf.toml create mode 100644 examples/cash-flow.part-cash-purchase.toml create mode 100644 examples/cash-flow.reversal-of-a-reversal.toml create mode 100644 examples/cash-flow.reversed-property-contribution.toml create mode 100644 examples/cash-flow.two-member-llc-first-year.toml diff --git a/README.md b/README.md new file mode 100644 index 0000000..42db595 --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# bookspec: examples (seed) + +bookspec is the formal accounting specification planned in +`plan/served.md` (P13, D-34): every rule stated normatively, sourced to its +authority, with a symbolic form and concrete examples, independent of any +engine. Its own repository comes later. Until then this directory holds its +first examples: P3's regression tests, each written here as it is built, so +the spec starts from cases a real engine got wrong. + +Every example is checked against wanderbooks on every `cargo test` +(`crates/ledger-core/tests/bookspec.rs`, and for the formats appendix +`crates/ledger-package/tests/package.rs`): an example the engine disagrees +with fails the build, so the examples can't rot. An expected value is worked +by hand from the cited source, never copied from an engine's output. + +## The shape of an example + +One TOML file per example in `examples/`, named for its `id`. + +```toml +id = "cash-flow.reversed-property-contribution" # stable; never reused +title = "A property contribution reversed the same day" +rule = "One normative sentence: what MUST (or MUST NOT) hold." +status = "AUTHORITY" # AUTHORITY | CONVENTION | CHOICE +sources = ["ASC 230-10-45-24", "ASC 230-10-50-3"] # exact citations +tags = ["accrual", "book", "us"] # applicability + +[setup] +currency = "USD" # ISO 4217 +fiscal_year_start = "01-01" # MM-DD +basis = "accrual" # accrual | cash +rounding = "half-even" # half-even | half-away-from-zero | + # largest-remainder: how a figure is + # rounded to the currency's minor unit, + # where a rule rounds (none here) + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" # asset | liability | equity | revenue | expense + +[[events]] # in order; event N is entry #N +date = "2026-01-10" +description = "Property contributed" +lines = [ + { account = "1500", side = "debit", amount = "2340.00" }, + { account = "3000", side = "credit", amount = "2340.00" }, +] + +[[events]] +date = "2026-01-10" +description = "Reverse entry 1" +reverses = 1 # the event (1-based) this one reverses: + # its lines, sides flipped; no `lines` here + +[[expect]] +query = "cash_flow" # what is asked of the books (see below) +from = "2026-01-01" # inclusive +to = "2026-12-31" # inclusive (a query as of a day: as_of) + +[expect.values] # every value an exact decimal string +operating = "0.00" +``` + +Events count from 1, as entries do: the first `[[events]]` is event 1 +(entry #1), and `reverses = N` reverses the Nth event, one before it; +`reverses = 0` names no event and is refused. An event is an entry +(`lines`), a reversal (`reverses`) or a close (`close`, below), exactly +one of them, and posts entry #N. A key the shape doesn't have is refused +too, never ignored. + +`rounding` names the rule the example's figures are rounded by where one +rounds: `half-even` or `half-away-from-zero` to the currency's minor unit, +or `largest-remainder` for an amount split among parts (each part rounded +down, the units left over to the largest remainders, ties to the part +listed first; rules.md B-13). An example that closes to the members +declares `largest-remainder`, the rule a members close splits by. + +Required everywhere: the top-level keys, `[setup]` with its four keys and +its accounts, the events, and at least one `[[expect]]` with values: a +figure query's are exact decimal strings (`"2340.00"`, `"-12.50"`; never a +float), a format query's are text (below). Amounts on lines are positive; +the side gives the direction. + +### Optional keys, for the rules that need them + +- `appendix = "formats"` (top level): the example shows an interchange + format, not an accounting rule (P13's appendix of formats; the IIF + file today). It loads like any other; only it may ask a format query. +- `parent` on an account: its parent account's code. A parent is declared + before its subaccounts. +- `cash_accounts`, `financing_accounts`, `investing_accounts`: arrays of + account codes, the statement of cash flows' account roles (ASC + 230-10-45-10 to 45-15). The cash and financing accounts are also what a + payee is paid from, for `vendor_1099_paid` (a payment card is neither: + its charges go on Form 1099-K; rules.md B-19), and the cash accounts + are an IIF file's bank accounts (B-34). +- `[[setup.fixed_assets]]` `{ cost_account, accumulated_account, + expense_account }`: accounts that hold property and equipment (their + cost and accumulated depreciation are investing; ASC 230-10-45-12(c), + 45-13(c)). +- `[[setup.members]]` `{ name, capital_account, share? }`: the members of + a multi-member LLC. `share` is the member's share of income, an exact + decimal fraction (`"0.5"`, `"0.3333"`); every member has one or none + does, and the shares sum to 1. A close to the members and + `members_equity` need them. +- `[[setup.payees]]` `{ name, form }`: a payee marked for an information + return, `form` `"1099-NEC"` or `"1099-MISC"`; each name once. +- `payee` on an event: the payee (by name, one of `setup.payees`) the + entry paid. Not on a reversal, which takes its original's, nor on a + close. +- `close = { start, to, rounding? }` as an event: closes the period from + `start` through the event's `date` (rules.md B-11, B-13), `to` + `"members"` (split by share, in the order listed) or + `"retained_earnings"`. A close to the members splits cumulatively, each + close giving each member their split of everything the members' closes + have closed less what earlier closes gave them; `rounding = "per-close"` + splits that close's net on its own instead (books from an engine that + rounded each close by itself). A close must have something to close: it + posts entry #N like any other event. +- `after = N` on an expectation: asked of the books after event N, not + after the last (1 to the number of events; not on a format query). + +### Queries and their values + +A query over a period takes `from` and `to`; a query as of a day takes +`as_of`; the other is refused. A query no crate answers is refused, never +skipped. + +| query | dates | values | checked by | +|---|---|---|---| +| `cash_flow` | `from`, `to` | figures (below) | `ledger-core` `tests/bookspec.rs` | +| `trial_balance` | `as_of` | each account's balance by code, debits less credits (a credit balance negative), every account listed | `ledger-core` `tests/bookspec.rs` | +| `profit_and_loss` | `from`, `to` | each revenue and expense account's activity by code, on its normal side, closing entries left out, every one listed; `net_income`, revenue less expenses | `ledger-core` `tests/bookspec.rs` | +| `entry` | `entry = N`, no dates | entry N's lines, `".debit"` and `".credit"` each the sum of that account's lines on that side, every line of the entry named | `ledger-core` `tests/bookspec.rs` | +| `balances` | `as_of` | each account named by code, its balance on its normal side (a member's capital after a loss is negative); the example names the accounts it shows | `ledger-core` `tests/bookspec.rs` | +| `members_equity` | `from`, `to` | the statement of changes in members' equity (rules.md B-13): `".beginning"`, `.contributions`, `.net_income`, `.distributions`, `.other`, `.ending`; the example names the figures it shows | `ledger-core` `tests/bookspec.rs` | +| `vendor_1099_paid` | `from` (January 1 of `to`'s year), `to` | each payee's payments by name, out of the cash and financing accounts (`cash_accounts` required), every payee listed | `ledger-core` `tests/bookspec.rs` | +| `iif_lines` | `as_of` | formats appendix: the file's lines in order, each its fields joined by tabs, without the CR LF that ends each | `ledger-package` `the_bookspec_iif_example_matches_the_engine` | +| `iif_changes` | `as_of` | formats appendix: each text the file writes differently from the books, in file order, as `[what, books' text, file's text]` (the example's header gives `what`) | `ledger-package` `the_bookspec_iif_example_matches_the_engine` | + +A figure query is a table (`[expect.values]`, or `values = { ... }`); a +format query is an array (`values = [ ... ]`). + +`cash_flow` (rules.md B-14): the statement of cash flows for `[from, to]`. + +| key | the value | +|---|---| +| `operating`, `investing`, `financing` | each section's net cash, + in | +| `net_change`, `cash_beginning`, `cash_ending` | the cash accounts' change and balances | +| `difference` | sections less the change in cash: always `"0.00"` | +| `net_income` | revenue less expenses, closing entries excluded | +| `
.` | entry N's cash in that section (`financing.4`) | +| `
..on_behalf` | of it, what a member or a lender paid or received for the company, no cash account moving (constructive receipt and disbursement) | +| `
.count` | how many entries the section lists | +| `noncash.` | entry N's noncash investing and financing disclosure | +| `noncash.count` | how many entries are disclosed | +| `reconciliation.depreciation` | depreciation added back | +| `reconciliation.investing_gain_loss` | gains and losses whose cash is investing, taken out | +| `reconciliation.noncash_through.` | operating movements no cash settled, through that account | +| `reconciliation.other_noncash` | other operating movements no cash settled | +| `reconciliation.balance_change.` | minus the change in an operating asset or liability | + +An entry named in a `
.` (or `.on_behalf`) or `noncash.` +key must be the only such entries when `
.count` or +`noncash.count` is given too; a +reconciliation key not given must be zero or absent. + +Every example, in any appendix, is loaded by +`crates/ledger-core/tests/bookspec.rs` (`every_bookspec_example_holds`): +its shape (a key the shape doesn't have is refused), its setup, and every +event posted. Each query is then checked by the crate that answers it (the +table above), so the shape never rots either. + +## Licence and sources + +The examples state rules in their own words with the paragraph cited +(FASB's Codification is copyrighted: cited, never copied; see +`docs/spec/sources/fasb-asc.md`). The examples are MIT OR Apache-2.0, as +the rest of this repository, until bookspec moves to its own repository +(planned: the spec under CC BY 4.0). diff --git a/examples/1099-worksheet-through-as-of.toml b/examples/1099-worksheet-through-as-of.toml index cb930ef..4d17f2d 100644 --- a/examples/1099-worksheet-through-as-of.toml +++ b/examples/1099-worksheet-through-as-of.toml @@ -6,13 +6,13 @@ # rules.md B-19, B-33; regression test `the_1099_worksheet_stops_at_as_of` # (ledger-package tests/package.rs). # -# Setup beyond the accounts: `cash_accounts` are the accounts payments -# are made from; each `[[setup.payees]]` is a payee marked for a form; -# an event's `payee` tags the payment to them. Expected values: -# vendor_1099_paid gives each marked payee's payments counted from `from` -# through `to` (both in one calendar year). The 2026 threshold is $2,000 -# (B-19), so the payee is not yet reportable as of June 30 (1400.00) and -# is for the year (3050.00). +# Setup beyond the accounts (bookspec/README.md): `cash_accounts` are the +# accounts payments are made from; each `[[setup.payees]]` is a payee +# marked for a form; an event's `payee` tags the payment to them. Event N +# is entry N. Expected values: vendor_1099_paid gives each marked payee's +# payments counted from `from`, January 1, through `to`, every payee +# listed. The 2026 threshold is $2,000 (B-19), so the payee is not yet +# reportable as of June 30 (1400.00) and is for the year (3050.00). id = "1099-worksheet-through-as-of" title = "A 1099 worksheet as of a day counts the year's payments through that day" @@ -29,7 +29,7 @@ tags = ["1099", "as-of", "calendar-year", "information-return", "period-boundary currency = "USD" fiscal_year_start = "01-01" basis = "cash" -rounding = "half_away_from_zero" +rounding = "half-away-from-zero" cash_accounts = ["1000"] [[setup.accounts]] @@ -56,7 +56,7 @@ type = "expense" name = "Contractor A" form = "1099-NEC" -# 0: the year before. +# Entry 1: the year before. [[events]] date = "2025-12-31" description = "Contract work, December" @@ -66,7 +66,7 @@ lines = [ { account = "1000", side = "credit", amount = "100.00" }, ] -# 1 +# Entry 2. [[events]] date = "2026-01-02" description = "Owner contribution" @@ -75,7 +75,7 @@ lines = [ { account = "3000", side = "credit", amount = "10000.00" }, ] -# 2 +# Entry 3. [[events]] date = "2026-03-15" description = "Contract work, March" @@ -85,7 +85,7 @@ lines = [ { account = "1000", side = "credit", amount = "900.00" }, ] -# 3: by card, so reported on Form 1099-K, never counted here. +# Entry 4: by card, so reported on Form 1099-K, never counted here. [[events]] date = "2026-06-10" description = "Contract work, June, by card" @@ -95,7 +95,7 @@ lines = [ { account = "2200", side = "credit", amount = "300.00" }, ] -# 4: made on the day itself, so counted. +# Entry 5: made on the day itself, so counted. [[events]] date = "2026-06-30" description = "Contract work, June" @@ -105,7 +105,7 @@ lines = [ { account = "1000", side = "credit", amount = "500.00" }, ] -# 5: the day after. +# Entry 6: the day after. [[events]] date = "2026-07-01" description = "Contract work, July" @@ -115,7 +115,7 @@ lines = [ { account = "1000", side = "credit", amount = "700.00" }, ] -# 6 +# Entry 7. [[events]] date = "2026-11-20" description = "Contract work, November" diff --git a/examples/as-of-package-stops-at-as-of.toml b/examples/as-of-package-stops-at-as-of.toml index 4a19df7..0994451 100644 --- a/examples/as-of-package-stops-at-as-of.toml +++ b/examples/as-of-package-stops-at-as-of.toml @@ -6,10 +6,11 @@ # `every_file_in_an_as_of_package_stops_at_as_of` and # `as_of_package_iif_stops_at_as_of` (ledger-package tests/package.rs). # -# Expected values: trial_balance gives each account's balance, debit -# positive and credit negative, every account listed; profit_and_loss -# gives each revenue and expense account's activity for the period as a -# positive amount, and net_income (revenue less expenses). +# Expected values (bookspec/README.md): trial_balance gives each +# account's balance as of the day, debit positive and credit negative, +# every account listed; profit_and_loss gives each revenue and expense +# account's activity for the period on its normal side, every one +# listed, and net_income (revenue less expenses). id = "as-of-package-stops-at-as-of" title = "A report as of a day leaves out what is dated after it" @@ -25,7 +26,7 @@ tags = ["as-of", "trial-balance", "profit-and-loss", "reversal", "period-boundar currency = "USD" fiscal_year_start = "01-01" basis = "accrual" -rounding = "half_away_from_zero" +rounding = "half-away-from-zero" [[setup.accounts]] code = "1000" @@ -47,7 +48,7 @@ code = "6000" name = "Rent" type = "expense" -# 0 +# Entry 1. [[events]] date = "2026-01-02" description = "Owner contribution" @@ -56,7 +57,7 @@ lines = [ { account = "3000", side = "credit", amount = "10000.00" }, ] -# 1 +# Entry 2. [[events]] date = "2026-02-01" description = "Sale" @@ -65,7 +66,7 @@ lines = [ { account = "4000", side = "credit", amount = "4000.00" }, ] -# 2: dated the day itself, so in. +# Entry 3: dated the day itself, so in. [[events]] date = "2026-06-30" description = "June rent" @@ -74,7 +75,7 @@ lines = [ { account = "1000", side = "credit", amount = "1200.00" }, ] -# 3: the day after, so out of anything as of 2026-06-30. +# Entry 4: the day after, so out of anything as of 2026-06-30. [[events]] date = "2026-07-01" description = "July rent" @@ -83,20 +84,15 @@ lines = [ { account = "1000", side = "credit", amount = "1200.00" }, ] -# 4: a reversal dated after the day leaves its original in. +# Entry 5: a reversal dated after the day leaves its original in. [[events]] date = "2026-07-15" description = "Reversal of the February sale" -reverses = 1 -lines = [ - { account = "4000", side = "debit", amount = "4000.00" }, - { account = "1000", side = "credit", amount = "4000.00" }, -] +reverses = 2 [[expect]] query = "trial_balance" -from = "2026-01-01" -to = "2026-06-30" +as_of = "2026-06-30" values = { "1000" = "12800.00", "3000" = "-10000.00", "4000" = "-4000.00", "6000" = "1200.00" } [[expect]] @@ -108,8 +104,7 @@ values = { "4000" = "4000.00", "6000" = "1200.00", net_income = "2800.00" } # The same books a month later: the July rent and the reversal are in. [[expect]] query = "trial_balance" -from = "2026-01-01" -to = "2026-07-31" +as_of = "2026-07-31" values = { "1000" = "7600.00", "3000" = "-10000.00", "4000" = "0.00", "6000" = "2400.00" } [[expect]] diff --git a/examples/cash-flow.debt-to-equity.toml b/examples/cash-flow.debt-to-equity.toml new file mode 100644 index 0000000..d170594 --- /dev/null +++ b/examples/cash-flow.debt-to-equity.toml @@ -0,0 +1,94 @@ +id = "cash-flow.debt-to-equity" +title = "An expense a member paid personally, then the member's advance converted to capital" +rule = "An expense a member pays for the company on credit to the member MUST be shown as cash borrowed from the member and spent, on its date; converting that debt to equity MUST be disclosed as a noncash financing activity, not reported as a cash flow, though both its accounts are financing." +# CHOICE: entry 1. ASC 230 doesn't address a payment a third party makes +# on the entity's behalf; the firm guides present it by substance as a +# constructive receipt and disbursement (a financing inflow and an +# operating outflow), and the owner chose that (wanderbooks D-42, revising +# D-35's noncash presentation). Entry 2's disclosure is 50-4's own example. +status = "CHOICE" +sources = [ + "ASC 230-10-45-14(b)", + "ASC 230-10-45-17(b)", + "ASC 230-10-50-3", + "ASC 230-10-50-4", + "PwC Viewpoint, Financial statement presentation 6.9.3.1 (ASC 230 does not address cash a third party receives or pays on the entity's behalf; include it as though through the entity's accounts)", + "Deloitte Roadmap, Statement of cash flows 7.2 (constructive receipt and disbursement)", + "BDO Blueprint, Statement of cash flows under ASC 230 (December 2025) 3.4", + "wanderbooks D-42 (owner, 2026-10-20: a member or lender paying for the company is cash borrowed and spent)", +] +tags = ["accrual", "book", "us", "cash-flow", "noncash", "constructive", "partnership"] + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] +financing_accounts = ["2100"] + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" + +[[setup.accounts]] +code = "2100" +name = "Due to members" +type = "liability" + +[[setup.accounts]] +code = "3000" +name = "Capital — Member A" +type = "equity" + +[[setup.accounts]] +code = "6000" +name = "Supplies" +type = "expense" + +[[setup.members]] +name = "Member A" +capital_account = "3000" + +[[events]] +date = "2026-02-03" +description = "Supplies, paid by Member A personally" +lines = [ + { account = "6000", side = "debit", amount = "500.00" }, + { account = "2100", side = "credit", amount = "500.00" }, +] + +[[events]] +date = "2026-02-10" +description = "Member A's advance converted to capital" +lines = [ + { account = "2100", side = "debit", amount = "500.00" }, + { account = "3000", side = "credit", amount = "500.00" }, +] + +# By hand: no company cash moved. Entry 1 is borrowed from the member +# (financing +500.00, 45-14(b)) and spent (operating -500.00, class (d), +# 45-17(b)) on 2026-02-03, all of it on the company's behalf; net income +# -500.00 needs no reconciling item. Entry 2 converts debt to equity, 50-4's +# first example: disclosed 500.00, though both its accounts are financing. +[[expect]] +query = "cash_flow" +from = "2026-02-01" +to = "2026-02-28" + +[expect.values] +operating = "-500.00" +investing = "0.00" +financing = "500.00" +net_change = "0.00" +difference = "0.00" +net_income = "-500.00" +"operating.1" = "-500.00" +"operating.1.on_behalf" = "-500.00" +"operating.count" = "1" +"financing.1" = "500.00" +"financing.1.on_behalf" = "500.00" +"financing.count" = "1" +"noncash.2" = "500.00" +"noncash.count" = "1" diff --git a/examples/cash-flow.paid-on-the-companys-behalf.toml b/examples/cash-flow.paid-on-the-companys-behalf.toml new file mode 100644 index 0000000..6757237 --- /dev/null +++ b/examples/cash-flow.paid-on-the-companys-behalf.toml @@ -0,0 +1,187 @@ +id = "cash-flow.paid-on-the-companys-behalf" +title = "A member and a lender pay for the company directly; the member is repaid" +rule = "When a member or a lender pays a company expense or purchase directly, with no cash account moving, the statement of cash flows MUST show a financing inflow (borrowed from the member or lender, or contributed when the member's capital is credited for an expense) and the operating or investing outflow, both on that payment's date; repaying the member or lender MUST be a financing outflow; such a payment and its reversal MUST net out together." +# CHOICE: ASC 230 does not address cash a third party pays on the entity's +# behalf. The firm guides present it by substance as a constructive +# receipt and disbursement (PwC 6.9.3.1; Deloitte 7.2, Example 7-2, a +# lender paying an insurer; BDO 3.4, Example 3-5, a bank paying the +# supplier of equipment, and a parent paying a subsidiary's expenses), +# and the owner chose that (wanderbooks D-42). KPMG also accepts a noncash +# presentation for equipment a lender pays for. +status = "CHOICE" +sources = [ + "ASC 230-10-45-13(c)", + "ASC 230-10-45-14(a)", + "ASC 230-10-45-14(b)", + "ASC 230-10-45-15(b)", + "ASC 230-10-45-17(b)", + "PwC Viewpoint, Financial statement presentation 6.9.3.1 (cash a third party receives or pays on the entity's behalf is included as though through the entity's accounts)", + "Deloitte Roadmap, Statement of cash flows 7.2 (constructive receipt and disbursement; Example 7-2)", + "BDO Blueprint, Statement of cash flows under ASC 230 (December 2025) 3.4 and Example 3-5", + "EY Financial reporting developments, Statement of cash flows (July 2026) 4.6.2 and 5.3.1", + "wanderbooks D-42 (owner, 2026-10-20: a member or lender paying for the company is cash borrowed and spent)", +] +tags = ["accrual", "book", "us", "cash-flow", "constructive", "partnership"] + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] +financing_accounts = ["2100", "2500"] + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" + +[[setup.accounts]] +code = "1500" +name = "Equipment" +type = "asset" + +[[setup.accounts]] +code = "1510" +name = "Accumulated depreciation" +type = "asset" + +[[setup.accounts]] +code = "2100" +name = "Due to members" +type = "liability" + +[[setup.accounts]] +code = "2500" +name = "Bank loan" +type = "liability" + +[[setup.accounts]] +code = "3000" +name = "Capital — Member A" +type = "equity" + +[[setup.accounts]] +code = "6000" +name = "Supplies" +type = "expense" + +[[setup.accounts]] +code = "6100" +name = "Depreciation" +type = "expense" + +[[setup.fixed_assets]] +cost_account = "1500" +accumulated_account = "1510" +expense_account = "6100" + +[[setup.members]] +name = "Member A" +capital_account = "3000" + +[[events]] +date = "2026-03-02" +description = "Member A contributes cash" +lines = [ + { account = "1000", side = "debit", amount = "1000.00" }, + { account = "3000", side = "credit", amount = "1000.00" }, +] + +[[events]] +date = "2026-03-05" +description = "Supplies, paid by Member A personally (owed back)" +lines = [ + { account = "6000", side = "debit", amount = "120.00" }, + { account = "2100", side = "credit", amount = "120.00" }, +] + +[[events]] +date = "2026-03-09" +description = "Equipment, paid to the seller by the bank (a loan)" +lines = [ + { account = "1500", side = "debit", amount = "2400.00" }, + { account = "2500", side = "credit", amount = "2400.00" }, +] + +[[events]] +date = "2026-03-12" +description = "Supplies, paid by Member A personally (contributed)" +lines = [ + { account = "6000", side = "debit", amount = "45.00" }, + { account = "3000", side = "credit", amount = "45.00" }, +] + +[[events]] +date = "2026-03-15" +description = "Supplies, paid by Member A personally (posted in error)" +lines = [ + { account = "6000", side = "debit", amount = "30.00" }, + { account = "2100", side = "credit", amount = "30.00" }, +] + +[[events]] +date = "2026-03-16" +description = "Reverse entry 5" +reverses = 5 + +[[events]] +date = "2026-03-20" +description = "Reimburse Member A" +lines = [ + { account = "2100", side = "debit", amount = "120.00" }, + { account = "1000", side = "credit", amount = "120.00" }, +] + +[[events]] +date = "2026-03-28" +description = "Loan payment" +lines = [ + { account = "2500", side = "debit", amount = "200.00" }, + { account = "1000", side = "credit", amount = "200.00" }, +] + +# By hand, March. Operating: entry 2, -120.00, and entry 4, -45.00 (cash +# paid to suppliers, 45-17(b), by the member for the company): -165.00; +# entries 5 and 6 net out. Investing: entry 3, -2,400.00 (equipment, +# 45-13(c), paid by the bank). Financing: entry 1 +1,000.00 and entry 4 +# +45.00 (contributions, 45-14(a)), entry 2 +120.00 and entry 3 +2,400.00 +# (borrowing, 45-14(b)), entry 7 -120.00 and entry 8 -200.00 (repayments, +# 45-15(b)): +3,245.00. Sum -165.00 - 2,400.00 + 3,245.00 = +680.00, the +# change in cash (1,000.00 - 120.00 - 200.00). Net income -165.00 equals +# operating: no reconciling item. Nothing is disclosed: no part of any +# entry went unsettled. +[[expect]] +query = "cash_flow" +from = "2026-03-01" +to = "2026-03-31" + +[expect.values] +operating = "-165.00" +investing = "-2400.00" +financing = "3245.00" +net_change = "680.00" +cash_beginning = "0.00" +cash_ending = "680.00" +difference = "0.00" +net_income = "-165.00" +"operating.2" = "-120.00" +"operating.2.on_behalf" = "-120.00" +"operating.4" = "-45.00" +"operating.count" = "2" +"investing.3" = "-2400.00" +"investing.3.on_behalf" = "-2400.00" +"investing.count" = "1" +"financing.1" = "1000.00" +"financing.1.on_behalf" = "0.00" +"financing.2" = "120.00" +"financing.2.on_behalf" = "120.00" +"financing.3" = "2400.00" +"financing.3.on_behalf" = "2400.00" +"financing.4" = "45.00" +"financing.4.on_behalf" = "45.00" +"financing.7" = "-120.00" +"financing.7.on_behalf" = "0.00" +"financing.8" = "-200.00" +"financing.count" = "6" +"noncash.count" = "0" diff --git a/examples/cash-flow.part-cash-purchase.toml b/examples/cash-flow.part-cash-purchase.toml new file mode 100644 index 0000000..3fc8ea4 --- /dev/null +++ b/examples/cash-flow.part-cash-purchase.toml @@ -0,0 +1,90 @@ +id = "cash-flow.part-cash-purchase" +title = "Equipment bought part for cash, part on the seller's note" +rule = "Of a transaction that is part cash and part noncash, only the cash portion MUST be reported in the statement of cash flows; the rest MUST be disclosed as a noncash investing and financing activity." +status = "AUTHORITY" +sources = ["ASC 230-10-50-5", "ASC 230-10-50-3", "ASC 230-10-50-4", "ASC 230-10-45-13(c)", "EY Financial reporting developments, Statement of cash flows (July 2026) 5.3.1 (seller-financed purchases are noncash to the extent of the seller's financing)"] +tags = ["accrual", "book", "us", "cash-flow", "noncash"] + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] +# The note is the seller's own credit, not a lender's: it is not listed as +# financing (a lender that paid the seller would be: the purchase would +# then be borrowed and invested, cash-flow.paid-on-the-companys-behalf). + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" + +[[setup.accounts]] +code = "1520" +name = "Vehicles" +type = "asset" + +[[setup.accounts]] +code = "1530" +name = "Accumulated depreciation, vehicles" +type = "asset" + +[[setup.accounts]] +code = "2500" +name = "Note payable to the seller" +type = "liability" + +[[setup.accounts]] +code = "3000" +name = "Capital" +type = "equity" + +[[setup.accounts]] +code = "6100" +name = "Depreciation" +type = "expense" + +[[setup.fixed_assets]] +cost_account = "1520" +accumulated_account = "1530" +expense_account = "6100" + +[[events]] +date = "2026-01-02" +description = "Opening contribution" +lines = [ + { account = "1000", side = "debit", amount = "10000.00" }, + { account = "3000", side = "credit", amount = "10000.00" }, +] + +[[events]] +date = "2026-02-08" +description = "Vehicle: 300 down, 700 on the seller's note" +lines = [ + { account = "1520", side = "debit", amount = "1000.00" }, + { account = "1000", side = "credit", amount = "300.00" }, + { account = "2500", side = "credit", amount = "700.00" }, +] + +# By hand: 300 left the bank for the vehicle (investing, 45-13(c)); the +# 700 the seller financed moved no cash, to anyone, and is disclosed (50-4: +# acquiring an asset by assuming a directly related liability). Cash +# 10,000.00 to 9,700.00 in February. +[[expect]] +query = "cash_flow" +from = "2026-02-01" +to = "2026-02-28" + +[expect.values] +operating = "0.00" +investing = "-300.00" +financing = "0.00" +net_change = "-300.00" +cash_beginning = "10000.00" +cash_ending = "9700.00" +difference = "0.00" +"investing.2" = "-300.00" +"investing.count" = "1" +"noncash.2" = "700.00" +"noncash.count" = "1" diff --git a/examples/cash-flow.reversal-of-a-reversal.toml b/examples/cash-flow.reversal-of-a-reversal.toml new file mode 100644 index 0000000..abbf567 --- /dev/null +++ b/examples/cash-flow.reversal-of-a-reversal.toml @@ -0,0 +1,90 @@ +id = "cash-flow.reversal-of-a-reversal" +title = "A contribution, its reversal and the reversal's reversal" +rule = "Reversals MUST pair along the chain from its root: an entry and its reversal both in the period drop out together, and a reversal of a reversal whose partner is already paired MUST be reported, as its root would be." +status = "AUTHORITY" +sources = [ + "ASC 230-10-45-14(a)", + "ASC 230-10-45-24", + "Pacioli, Summa (1494), ch. 31 (the correcting entry)", +] +tags = ["accrual", "book", "us", "cash-flow", "reversal"] + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" + +[[setup.accounts]] +code = "3001" +name = "Capital — Member B" +type = "equity" + +[[setup.members]] +name = "Member B" +capital_account = "3001" + +[[events]] +date = "2026-01-20" +description = "Opening contribution" +lines = [ + { account = "1000", side = "debit", amount = "1000.00" }, + { account = "3001", side = "credit", amount = "1000.00" }, +] + +[[events]] +date = "2026-02-02" +description = "Contribution — Member B" +lines = [ + { account = "1000", side = "debit", amount = "300.00" }, + { account = "3001", side = "credit", amount = "300.00" }, +] + +[[events]] +date = "2026-02-03" +description = "Reverse entry 2" +reverses = 2 + +[[events]] +date = "2026-02-04" +description = "Reverse entry 3: the contribution stands" +reverses = 3 + +# By hand, February: entries 2 and 3 pair (the root and its reversal); +# entry 4 reinstates the contribution and is reported: financing +300.00, +# the change in cash. +[[expect]] +query = "cash_flow" +from = "2026-02-01" +to = "2026-02-28" + +[expect.values] +financing = "300.00" +net_change = "300.00" +cash_beginning = "1000.00" +cash_ending = "1300.00" +difference = "0.00" +"financing.4" = "300.00" +"financing.count" = "1" +"noncash.count" = "0" + +# From February 3 the root is before the period: entries 3 and 4 pair, and +# nothing is reported (no cash moved net, 1,300.00 to 1,300.00). +[[expect]] +query = "cash_flow" +from = "2026-02-03" +to = "2026-02-28" + +[expect.values] +financing = "0.00" +net_change = "0.00" +cash_beginning = "1300.00" +cash_ending = "1300.00" +difference = "0.00" +"financing.count" = "0" diff --git a/examples/cash-flow.reversed-property-contribution.toml b/examples/cash-flow.reversed-property-contribution.toml new file mode 100644 index 0000000..97ccd5a --- /dev/null +++ b/examples/cash-flow.reversed-property-contribution.toml @@ -0,0 +1,84 @@ +id = "cash-flow.reversed-property-contribution" +title = "A property contribution reversed the same day leaves the statement of cash flows empty" +rule = "An entry and its reversal both in the period MUST contribute nothing to any section or disclosure, and the sections MUST sum to the change in cash." +status = "AUTHORITY" +sources = [ + "ASC 230-10-45-1", + "ASC 230-10-45-24", + "ASC 230-10-50-3", + "Pacioli, Summa (1494), ch. 31 (the correcting entry)", +] +tags = ["accrual", "book", "us", "cash-flow", "reversal", "regression:p3-defect-1"] + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] + +[[setup.accounts]] +code = "1000" +name = "Cash" +type = "asset" + +[[setup.accounts]] +code = "1500" +name = "Equipment" +type = "asset" + +[[setup.accounts]] +code = "1510" +name = "Accumulated depreciation" +type = "asset" + +[[setup.accounts]] +code = "6100" +name = "Depreciation" +type = "expense" + +[[setup.accounts]] +code = "3000" +name = "Capital" +type = "equity" + +[[setup.fixed_assets]] +cost_account = "1500" +accumulated_account = "1510" +expense_account = "6100" + +[[events]] +date = "2026-01-10" +description = "Property contributed" +lines = [ + { account = "1500", side = "debit", amount = "2340.00" }, + { account = "3000", side = "credit", amount = "2340.00" }, +] + +[[events]] +date = "2026-01-10" +description = "Reverse entry 1" +reverses = 1 + +# By hand: no cash moved (sections 0.00, change in cash 0.00), and the +# entry and its reversal cancel, so nothing is disclosed either. Before the +# fix (wanderbooks P3, defect 1) investing showed -2,340.00 against a +# change of 0.00: the reversal's credit to equipment fell in no section. +[[expect]] +query = "cash_flow" +from = "2026-01-01" +to = "2026-12-31" + +[expect.values] +operating = "0.00" +investing = "0.00" +financing = "0.00" +net_change = "0.00" +cash_beginning = "0.00" +cash_ending = "0.00" +difference = "0.00" +net_income = "0.00" +"operating.count" = "0" +"investing.count" = "0" +"financing.count" = "0" +"noncash.count" = "0" diff --git a/examples/cash-flow.two-member-llc-first-year.toml b/examples/cash-flow.two-member-llc-first-year.toml new file mode 100644 index 0000000..47a877c --- /dev/null +++ b/examples/cash-flow.two-member-llc-first-year.toml @@ -0,0 +1,443 @@ +id = "cash-flow.two-member-llc-first-year" +title = "A two-member LLC's first weeks: contributions, member-paid expenses, property contributed, corrections" +rule = "The statement of cash flows MUST report cash receipts and payments, by section, with each reversal netted against its original in the period; expenses members paid personally on credit to them MUST be shown as cash borrowed from the members and spent, on each payment's date; property the members contributed MUST be disclosed as a noncash activity; the sections MUST sum to the change in cash." +# CHOICE: the member-paid expenses. ASC 230 doesn't address a payment made +# on the entity's behalf; the firm guides present it by substance as a +# constructive receipt and disbursement (a financing inflow and an +# operating outflow), and the owner chose that (D-42, revising D-35's +# noncash presentation). The rest is the Codification's. +status = "CHOICE" +sources = [ + "ASC 230-10-10-1", + "ASC 230-10-45-14(a)", + "ASC 230-10-45-14(b)", + "ASC 230-10-45-15(b)", + "ASC 230-10-45-17(b)", + "ASC 230-10-45-24", + "ASC 230-10-45-28", + "ASC 230-10-45-30", + "ASC 230-10-50-3", + "ASC 230-10-50-4", + "PwC Viewpoint, Financial statement presentation 6.9.3.1 (cash a third party receives or pays on the entity's behalf is included as though through the entity's accounts)", + "Deloitte Roadmap, Statement of cash flows 7.2 (constructive receipt and disbursement)", + "BDO Blueprint, Statement of cash flows under ASC 230 (December 2025) 3.4 (a parent paying a subsidiary's expenses)", + "wanderbooks D-42 (owner, 2026-10-20: a member or lender paying for the company is cash borrowed and spent)", +] +tags = ["accrual", "book", "us", "cash-flow", "partnership", "constructive", "regression:p3-defect-1"] + +# A two-member LLC's first weeks, in the shape of the books P3 defect 1 +# was found in: the same 23 entries in the same order, on the same +# accounts and roles (two contributions in cash, expenses the members paid +# personally through Due to Members and two reimbursements, a domain +# expensed then corrected to a prepaid, two card charges, four devices the +# members owned contributed, two of them first entered wrongly and +# reversed), with every amount and date this example's own. Before the fix +# the statement didn't foot: the reversals' credits to equipment (#13, +# #18) belonged to no section, and the contributed devices read as +# purchases. + +[setup] +currency = "USD" +fiscal_year_start = "01-01" +basis = "accrual" +rounding = "half-even" +cash_accounts = ["1000"] +financing_accounts = ["2100"] + +[[setup.accounts]] +code = "1000" +name = "Checking" +type = "asset" + +[[setup.accounts]] +code = "1300" +name = "Prepaid Expenses" +type = "asset" + +[[setup.accounts]] +code = "1500" +name = "Equipment" +type = "asset" + +[[setup.accounts]] +code = "1510" +name = "Accumulated Depreciation" +type = "asset" + +[[setup.accounts]] +code = "2050" +name = "Business Card" +type = "liability" + +[[setup.accounts]] +code = "2100" +name = "Due to Members" +type = "liability" + +[[setup.accounts]] +code = "3000" +name = "Capital — Member A" +type = "equity" + +[[setup.accounts]] +code = "3001" +name = "Capital — Member B" +type = "equity" + +[[setup.accounts]] +code = "6000" +name = "Organizational Costs" +type = "expense" + +[[setup.accounts]] +code = "6050" +name = "Domain & Hosting" +type = "expense" + +[[setup.accounts]] +code = "6200" +name = "Developer Fees" +type = "expense" + +[[setup.accounts]] +code = "6300" +name = "Software & Subscriptions" +type = "expense" + +[[setup.accounts]] +code = "6400" +name = "Memberships & Licenses" +type = "expense" + +[[setup.accounts]] +code = "6500" +name = "Depreciation Expense" +type = "expense" + +[[setup.fixed_assets]] +cost_account = "1500" +accumulated_account = "1510" +expense_account = "6500" + +[[setup.members]] +name = "Member A" +capital_account = "3000" + +[[setup.members]] +name = "Member B" +capital_account = "3001" + +# Entry 1. +[[events]] +date = "2026-03-02" +description = "Formation filing fee, paid by the members" +lines = [ + { account = "6000", side = "debit", amount = "85.00" }, + { account = "2100", side = "credit", amount = "85.00" }, +] + +# Entry 2. +[[events]] +date = "2026-03-03" +description = "Domain, 1 year, paid by the members" +lines = [ + { account = "6050", side = "debit", amount = "12.97" }, + { account = "2100", side = "credit", amount = "12.97" }, +] + +# Entry 3. +[[events]] +date = "2026-03-05" +description = "Developer registration, paid by the members" +lines = [ + { account = "6200", side = "debit", amount = "99.00" }, + { account = "2100", side = "credit", amount = "99.00" }, +] + +# Entry 4. +[[events]] +date = "2026-03-09" +description = "Contribution — Member A" +lines = [ + { account = "1000", side = "debit", amount = "1200.00" }, + { account = "3000", side = "credit", amount = "1200.00" }, +] + +# Entry 5. +[[events]] +date = "2026-03-10" +description = "Contribution — Member B" +lines = [ + { account = "1000", side = "debit", amount = "800.00" }, + { account = "3001", side = "credit", amount = "800.00" }, +] + +# Entry 6. +[[events]] +date = "2026-03-11" +description = "Subscription top-up, paid by the members" +lines = [ + { account = "6300", side = "debit", amount = "7.49" }, + { account = "2100", side = "credit", amount = "7.49" }, +] + +# Entry 7. +[[events]] +date = "2026-03-16" +description = "Developer membership, paid by the members" +lines = [ + { account = "6400", side = "debit", amount = "129.00" }, + { account = "2100", side = "credit", amount = "129.00" }, +] + +# Entry 8. +[[events]] +date = "2026-03-23" +description = "Reimburse members" +lines = [ + { account = "2100", side = "debit", amount = "333.46" }, + { account = "1000", side = "credit", amount = "333.46" }, +] + +# Entry 9. +[[events]] +date = "2026-03-20" +description = "Domain, 2 years, paid by the members" +lines = [ + { account = "6050", side = "debit", amount = "46.38" }, + { account = "2100", side = "credit", amount = "46.38" }, +] + +# Entry 10. +[[events]] +date = "2026-03-25" +description = "API credits on the card" +lines = [ + { account = "6300", side = "debit", amount = "14.20" }, + { account = "2050", side = "credit", amount = "14.20" }, +] + +# Entry 11. +[[events]] +date = "2026-03-26" +description = "Reimburse members" +lines = [ + { account = "2100", side = "debit", amount = "46.38" }, + { account = "1000", side = "credit", amount = "46.38" }, +] + +# Entry 12. +[[events]] +date = "2026-03-27" +description = "Laptop contributed by Member A" +lines = [ + { account = "1500", side = "debit", amount = "1480.00" }, + { account = "3000", side = "credit", amount = "1480.00" }, +] + +# Entry 13. +[[events]] +date = "2026-03-27" +description = "Reverse entry 12: contributed jointly" +reverses = 12 + +# Entry 14. +[[events]] +date = "2026-03-27" +description = "Laptop contributed jointly" +lines = [ + { account = "1500", side = "debit", amount = "1480.00" }, + { account = "3000", side = "credit", amount = "740.00" }, + { account = "3001", side = "credit", amount = "740.00" }, +] + +# Entry 15. +[[events]] +date = "2026-03-27" +description = "Laptop contributed jointly" +lines = [ + { account = "1500", side = "debit", amount = "1190.00" }, + { account = "3000", side = "credit", amount = "595.00" }, + { account = "3001", side = "credit", amount = "595.00" }, +] + +# Entry 16. +[[events]] +date = "2026-03-27" +description = "Desktop contributed jointly" +lines = [ + { account = "1500", side = "debit", amount = "2210.00" }, + { account = "3000", side = "credit", amount = "1105.00" }, + { account = "3001", side = "credit", amount = "1105.00" }, +] + +# Entry 17. +[[events]] +date = "2026-03-27" +description = "Tablet contributed jointly" +lines = [ + { account = "1500", side = "debit", amount = "630.00" }, + { account = "3000", side = "credit", amount = "315.00" }, + { account = "3001", side = "credit", amount = "315.00" }, +] + +# Entry 18. +[[events]] +date = "2026-03-27" +description = "Reverse entry 15: the service plan is separate" +reverses = 15 + +# Entry 19. +[[events]] +date = "2026-03-27" +description = "Laptop and its service plan contributed jointly" +lines = [ + { account = "1500", side = "debit", amount = "1151.00" }, + { account = "1300", side = "debit", amount = "39.00" }, + { account = "3000", side = "credit", amount = "595.00" }, + { account = "3001", side = "credit", amount = "595.00" }, +] + +# Entry 20. +[[events]] +date = "2026-03-20" +description = "Domain, 2 years, paid by the members, prepaid" +lines = [ + { account = "1300", side = "debit", amount = "46.38" }, + { account = "2100", side = "credit", amount = "46.38" }, +] + +# Entry 21. +[[events]] +date = "2026-03-12" +description = "Subscription, paid by the members" +lines = [ + { account = "6300", side = "debit", amount = "216.40" }, + { account = "2100", side = "credit", amount = "216.40" }, +] + +# Entry 22. +[[events]] +date = "2026-03-20" +description = "Reverse entry 9: prepaid, not expensed" +reverses = 9 + +# Entry 23. +[[events]] +date = "2026-03-30" +description = "API credits on the card" +lines = [ + { account = "6300", side = "debit", amount = "42.75" }, + { account = "2050", side = "credit", amount = "42.75" }, +] +# By hand, the year to 2026-03-31 (rules.md B-14; D-42 for what the +# members paid). Cash is 1000; 2100 (Due to Members) is financing. +# - Operating: the members paid #1 85.00, #2 12.97, #3 99.00, #6 7.49, +# #21 216.40, #7 129.00 and #20 46.38 (the prepaid domain) for the +# company through 2100, each borrowed (financing, 45-14(b)) and spent +# (operating, 45-17(b)) on its date: 85.00 + 12.97 + 99.00 + 7.49 + +# 216.40 + 129.00 + 46.38 = 596.24, so operating -596.24, all cash paid +# to suppliers. #9 and its reversal #22 net out (rule 6). The card's #10 +# and #23 moved no cash and 2050 is not financing: no line. +# - Investing 0.00: every device was property the members owned (50-4), +# disclosed below; #12/#13 and #15/#18 net out. +# - Financing: #4 +1,200.00 and #5 +800.00 (contributions, 45-14(a)); +# +596.24 borrowed from the members (the seven above); the +# reimbursements #8 -333.46 (#1, #2, #3, #6 and #7: 85.00 + 12.97 + +# 99.00 + 7.49 + 129.00) and #11 -46.38 (#20), 45-15(b): 1,200.00 + +# 800.00 + 596.24 - 333.46 - 46.38 = +2,216.40. +# - Sum: -596.24 + 0.00 + 2,216.40 = +1,620.16, the change in cash (in +# 1,200.00 + 800.00, out 333.46 + 46.38; 0.00 to 1,620.16); difference +# 0.00. +# - Reconciliation (45-28 to 45-30): net income is minus the expenses, +# 85.00 + 12.97 + 99.00 + 7.49 + 129.00 + 46.38 - 46.38 + 14.20 + 216.40 +# + 42.75 = 606.81, so -606.81; other noncash +39.00 (#19's service +# plan, contributed with the laptop); increase in 1300, 39.00 + 46.38, +# so -85.38; increase in 2050, 14.20 + 42.75, so +56.95. Total -606.81 + +# 39.00 - 85.38 + 56.95 = -596.24, the operating section. +# - Disclosed (50-3, 50-4), the property contributed: #14 1,480.00, #16 +# 2,210.00, #17 630.00, #19 1,190.00 (1,151.00 equipment and 39.00 a +# prepaid service plan), 5,510.00 in all; #12/#13 and #15/#18 drop out. +[[expect]] +query = "cash_flow" +from = "2026-01-01" +to = "2026-03-31" + +[expect.values] +operating = "-596.24" +investing = "0.00" +financing = "2216.40" +net_change = "1620.16" +cash_beginning = "0.00" +cash_ending = "1620.16" +difference = "0.00" +net_income = "-606.81" +"operating.1" = "-85.00" +"operating.2" = "-12.97" +"operating.3" = "-99.00" +"operating.6" = "-7.49" +"operating.7" = "-129.00" +"operating.20" = "-46.38" +"operating.21" = "-216.40" +"operating.count" = "7" +"investing.count" = "0" +"financing.1" = "85.00" +"financing.1.on_behalf" = "85.00" +"financing.2" = "12.97" +"financing.3" = "99.00" +"financing.4" = "1200.00" +"financing.4.on_behalf" = "0.00" +"financing.5" = "800.00" +"financing.6" = "7.49" +"financing.7" = "129.00" +"financing.8" = "-333.46" +"financing.11" = "-46.38" +"financing.20" = "46.38" +"financing.20.on_behalf" = "46.38" +"financing.21" = "216.40" +"financing.count" = "11" +"reconciliation.other_noncash" = "39.00" +"reconciliation.balance_change.1300" = "-85.38" +"reconciliation.balance_change.2050" = "56.95" +"noncash.14" = "1480.00" +"noncash.16" = "2210.00" +"noncash.17" = "630.00" +"noncash.19" = "1190.00" +"noncash.count" = "4" + +# The same books to 2026-03-18: #1 to #7 and #21 are dated by then (#9, +# #20 and #22 on 03-20, the rest later). The members paid #1, #2, #3, #6, +# #7 and #21 for the company, 85.00 + 12.97 + 99.00 + 7.49 + 129.00 + +# 216.40 = 549.86: operating -549.86; financing #4 +1,200.00, #5 +800.00 +# and the 549.86 borrowed, +2,549.86; the change in cash 2,000.00 +# (-549.86 + 2,549.86); net income -549.86 with no reconciling item (no +# operating balance has moved yet); nothing disclosed. +[[expect]] +query = "cash_flow" +from = "2026-01-01" +to = "2026-03-18" + +[expect.values] +operating = "-549.86" +investing = "0.00" +financing = "2549.86" +net_change = "2000.00" +difference = "0.00" +net_income = "-549.86" +"operating.1" = "-85.00" +"operating.2" = "-12.97" +"operating.3" = "-99.00" +"operating.6" = "-7.49" +"operating.7" = "-129.00" +"operating.21" = "-216.40" +"operating.count" = "6" +"financing.1" = "85.00" +"financing.2" = "12.97" +"financing.3" = "99.00" +"financing.4" = "1200.00" +"financing.5" = "800.00" +"financing.6" = "7.49" +"financing.7" = "129.00" +"financing.21" = "216.40" +"financing.count" = "8" +"noncash.count" = "0" diff --git a/examples/iif-quickbooks-journal-file.toml b/examples/iif-quickbooks-journal-file.toml index 483cc3e..5a3192a 100644 --- a/examples/iif-quickbooks-journal-file.toml +++ b/examples/iif-quickbooks-journal-file.toml @@ -18,16 +18,15 @@ # Setup beyond the accounts: `cash_accounts` are the bank accounts (BANK); # an account's QuickBooks type otherwise follows its type (asset OCASSET, # liability OCLIAB, equity EQUITY, revenue INC, expense EXP); an account's -# `parent` is its parent's code. Each event is a posted entry, its id one -# more than its index. Expected values: iif_lines gives the file's lines -# in order, each a string of fields joined by tabs ("\t"), every line -# ending CR LF in the file; iif_changes gives each text written -# differently from the books, in file order (the accounts as declared: -# by code, each after its parent; then the entries), as [what, books' -# text, file's text], where what is "name ", "number" (left out of -# ACCNUM when the file's text is empty), "top level " (written -# apart from its parent, the books' text: the parent's code) or -# "memo ". +# `parent` is its parent's code. Event N is entry N (bookspec/README.md). +# Expected values: iif_lines gives the file's lines in order, each a +# string of fields joined by tabs ("\t"), every line ending CR LF in the +# file; iif_changes gives each text written differently from the books, +# in file order (the accounts as declared: by code, each after its +# parent; then the entries), as [what, books' text, file's text], where +# what is "name ", "number" (left out of ACCNUM when the file's +# text is empty), "top level " (written apart from its parent, the +# books' text: the parent's code) or "memo ". id = "iif-quickbooks-journal-file" appendix = "formats" @@ -48,7 +47,7 @@ tags = ["iif", "quickbooks", "as-of", "format", "transliteration"] currency = "USD" fiscal_year_start = "01-01" basis = "cash" -rounding = "half_away_from_zero" +rounding = "half-away-from-zero" cash_accounts = ["1000"] [[setup.accounts]] @@ -96,7 +95,7 @@ code = "6100" name = "Professional services and consulting fees" type = "expense" -# 0: entry 1. +# Entry 1. [[events]] date = "2026-01-02" description = "Owner contribution" @@ -105,7 +104,7 @@ lines = [ { account = "3000", side = "credit", amount = "5000.00" }, ] -# 1: entry 2. An em dash and double quotes. +# Entry 2. An em dash and double quotes. [[events]] date = "2026-01-15" description = "Lunch — \"team\"" @@ -114,7 +113,7 @@ lines = [ { account = "1000", side = "credit", amount = "42.50" }, ] -# 2: entry 3. An account named past 31 characters. +# Entry 3. An account named past 31 characters. [[events]] date = "2026-01-20" description = "Consulting" @@ -123,7 +122,7 @@ lines = [ { account = "1000", side = "credit", amount = "300.00" }, ] -# 3: entry 4, dated the day itself: in. +# Entry 4, dated the day itself: in. [[events]] date = "2026-02-01" description = "Sale" @@ -132,7 +131,7 @@ lines = [ { account = "4000", side = "credit", amount = "1000.00" }, ] -# 4: entry 5, the day after: out. +# Entry 5, the day after: out. [[events]] date = "2026-02-02" description = "Second sale"