cash flow: financing and investing gross; account roles are a setting

From ASC 230 (via Deloitte DART and PwC Viewpoint), replacing two
formerly assumed behaviors:

- Financing and investing are gross (230-10-45-7): per account, cash in
  and cash out are separate lines (contributions apart from
  distributions, borrowing apart from repayment), netted only within
  one entry. Lines come in code order, in before out.
- Investing includes making and collecting loans and buying investments
  (230-10-20, 45-13), not only registered fixed assets:
  CashFlowParams gains investing_accounts.
- The roles are per-company settings: [books] financing_accounts and
  investing_accounts in wanderbooks.toml (beside cash_accounts). The MCP
  tools (cash_flow, export, CPA package) default every list to them and
  share one path; the viewer reads them too, falling back to its name
  guess for debt. A due-to-owners liability listed as financing gives
  PwC 6.9.3.1's constructive treatment of expenses an owner paid.

rules.md B-14 quotes the sources; new tests cite them; docs/testing.md
#8 is resolved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-13 18:36:21 -06:00
1 parent cced14fa52
commit fbe496566b
13 files changed
+521 -126

No files matched your search

+17 -1
View File
@@ -97,6 +97,14 @@ pub struct BooksSettings {
/// savings, cash on hand), for cash reports and dashboards. Empty:
/// callers decide (e.g. by account name).
pub cash_accounts: Vec<String>,
/// `[books] financing_accounts`: liability account codes the cash flow
/// statement treats as financing (loans, and what owners advanced:
/// ASC 230-10-45-14(2)). Empty: callers decide.
pub financing_accounts: Vec<String>,
/// `[books] investing_accounts`: asset account codes the cash flow
/// statement treats as investing (loans the company makes, investments
/// it buys: ASC 230-10-20). Registered fixed assets need not be listed.
pub investing_accounts: Vec<String>,
}
#[derive(Deserialize)]
@@ -134,6 +142,10 @@ struct BooksSection {
close_sweep: Vec<String>,
#[serde(default)]
cash_accounts: Vec<String>,
#[serde(default)]
financing_accounts: Vec<String>,
#[serde(default)]
investing_accounts: Vec<String>,
}
/// The return a federal tax classification files: "partnership" → 1065,
@@ -269,6 +281,8 @@ pub fn parse(text: &str) -> Result<BooksSettings, String> {
company,
receipt_threshold,
cash_accounts: raw.books.cash_accounts,
financing_accounts: raw.books.financing_accounts,
investing_accounts: raw.books.investing_accounts,
})
}
@@ -337,7 +351,7 @@ mod tests {
#[test]
fn keeps_the_whole_profile_in_order() {
let s = parse(
"[company]\nname = \"Acme LLC\"\nein = \"12-3456789\"\nformed = \"2026-10-04\"\n[books]\ncash_accounts = [\"1000\", \"1010\"]\n",
"[company]\nname = \"Acme LLC\"\nein = \"12-3456789\"\nformed = \"2026-10-04\"\n[books]\ncash_accounts = [\"1000\", \"1010\"]\nfinancing_accounts = [\"2100\"]\ninvesting_accounts = [\"1400\"]\n",
)
.unwrap();
assert_eq!(
@@ -349,6 +363,8 @@ mod tests {
]
);
assert_eq!(s.cash_accounts, ["1000", "1010"]);
assert_eq!(s.financing_accounts, ["2100"]);
assert_eq!(s.investing_accounts, ["1400"]);
}
#[test]