P3: the cash flow statement by ASC 230 (defect 1, D-35, D-42)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
64 files changed
+12128
-1567
No files matched your search
@@ -170,19 +170,19 @@ pub fn build_package<B: PackageBooks + ?Sized>(
|
||||
),
|
||||
(
|
||||
"cash-flow",
|
||||
report::cash_flow(
|
||||
&cash_flow_for(
|
||||
ledger,
|
||||
settings,
|
||||
Some(&fy_start),
|
||||
Some(&as_of_s),
|
||||
req.cash_accounts,
|
||||
req.financing_accounts,
|
||||
req.investing_accounts,
|
||||
today,
|
||||
)?,
|
||||
&members,
|
||||
),
|
||||
// The package's one list of each (INVARIANT 7); investing
|
||||
// accounts are the cash flow's alone (the request's, else the
|
||||
// settings').
|
||||
report::cash_flow(&cash_flow_for(
|
||||
ledger,
|
||||
settings,
|
||||
Some(&fy_start),
|
||||
Some(&as_of_s),
|
||||
cash_codes,
|
||||
financing_codes,
|
||||
req.investing_accounts,
|
||||
today,
|
||||
)?),
|
||||
),
|
||||
];
|
||||
let mut k1_csv: Option<(String, Vec<u8>)> = None;
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
//! refused.
|
||||
//! 2. The cash flow statement needs at least one cash account, and
|
||||
//! every code it is given must be in the chart; account lists a call
|
||||
//! leaves empty default to the settings' roles.
|
||||
//! leaves empty default to the settings' roles. It foots, or it is
|
||||
//! refused (an engine error, never a figure: rules.md B-14 rule 9);
|
||||
//! roles that contradict each other or the chart are refused by the
|
||||
//! engine, naming the setting, so the viewer and the server refuse
|
||||
//! alike. Members are named on their contributions and
|
||||
//! distributions (D-35).
|
||||
//! 3. The year's earnings split net income year to date from the part
|
||||
//! not yet closed into equity (closes are cumulative).
|
||||
//! ```
|
||||
@@ -98,6 +103,9 @@ pub fn bs_statement(
|
||||
/// Build the cash flow statement from account codes, as the exports need it:
|
||||
/// `start` defaults to the beginning of time, `end` to `today`, and at
|
||||
/// least one cash account is required (the statement reconciles to them).
|
||||
/// A member whose capital account the chart lacks is left unnamed (equity
|
||||
/// is then named by account), never a refusal of the statement.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn cash_flow_statement(
|
||||
ledger: &Ledger,
|
||||
start: Option<&str>,
|
||||
@@ -105,6 +113,7 @@ pub fn cash_flow_statement(
|
||||
cash_codes: &[String],
|
||||
financing_codes: &[String],
|
||||
investing_codes: &[String],
|
||||
members: &[Member],
|
||||
today: NaiveDate,
|
||||
) -> Result<ledger_core::reports::CashFlowStatement, String> {
|
||||
let resolve = |codes: &[String], what: &str| -> Result<Vec<AccountId>, String> {
|
||||
@@ -129,6 +138,22 @@ pub fn cash_flow_statement(
|
||||
let financing_accounts = resolve(financing_codes, "financing")?;
|
||||
let investing_accounts = resolve(investing_codes, "investing")?;
|
||||
let (start, end) = statement_range(ledger, start, end, today)?;
|
||||
let chart = ledger.chart();
|
||||
let members = members
|
||||
.iter()
|
||||
.filter_map(|m| {
|
||||
Some(ledger_core::MemberCapital {
|
||||
name: m.name.clone(),
|
||||
capital_account: chart.find_by_code(&m.capital_account)?.id,
|
||||
distribution_account: m
|
||||
.distribution_account
|
||||
.as_deref()
|
||||
.and_then(|c| chart.find_by_code(c))
|
||||
.map(|a| a.id),
|
||||
share: m.share,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
ledger_core::cash_flow(
|
||||
ledger,
|
||||
&ledger_core::CashFlowParams {
|
||||
@@ -137,6 +162,7 @@ pub fn cash_flow_statement(
|
||||
cash_accounts,
|
||||
financing_accounts,
|
||||
investing_accounts,
|
||||
members,
|
||||
},
|
||||
)
|
||||
.map_err(|e| e.to_string())
|
||||
@@ -169,6 +195,7 @@ pub fn cash_flow_for(
|
||||
&or(cash, settings.cash_accounts),
|
||||
&or(financing, settings.financing_accounts),
|
||||
&or(investing, settings.investing_accounts),
|
||||
&settings.company.members,
|
||||
today,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use chrono::NaiveDate;
|
||||
use rust_decimal::Decimal;
|
||||
|
||||
/// A money amount as a decimal string with at least two places: "0.00",
|
||||
/// "207.68", "1000.00". Padding only, never rounding: an exact amount with
|
||||
/// "318.42", "1000.00". Padding only, never rounding: an exact amount with
|
||||
/// more places (an FX-converted line) keeps them. Never "-0".
|
||||
pub fn money(n: Decimal) -> String {
|
||||
let mut n = if n.is_zero() { Decimal::ZERO } else { n };
|
||||
@@ -89,7 +89,7 @@ mod tests {
|
||||
assert_eq!(m("-0"), "0.00");
|
||||
assert_eq!(m("1000"), "1000.00");
|
||||
assert_eq!(m("5.8"), "5.80");
|
||||
assert_eq!(m("-207.68"), "-207.68");
|
||||
assert_eq!(m("-318.42"), "-318.42");
|
||||
assert_eq!(m("12.3456"), "12.3456");
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user