Fixed assets carry federal tax basis beside book value; tests sweep stale temp dirs
- core: TaxBasisRule (cost IRC 1012, carryover IRC 723, personal-use conversion Treas. Reg. 1.168(i)-4(b)), TaxBasis with the contributor's adjusted basis, Asset::tax_basis and ::built_in_gain (IRC 704(c)); the register gains tax rule, contributor basis, tax basis, built-in gain, total tax basis, missing count (rules.md B-25; sources vendored in docs/spec/sources/irs-partnership-basis.md) - store: asset.tax_basis_set journaled, replayed, projected (schema v10) - mcp: books.set_asset_tax_basis; register_asset takes tax_basis_rule and contributor_basis, checked before anything registers (found by the spec-blind suite); list_assets and the register export (json, csv) carry tax basis; instructions say to record it for every asset - import: the register's XLSX and PDF gain the federal tax basis table with citations - viewer: tax basis on the Assets page, the asset page (a Tax basis card), the report, the journal, and Needs attention for assets without one - just: check and the mutation recipes sweep this user's test book dirs older than an hour (killed runs had left 23 GB in RAM-backed /tmp) - docs: the parties, attachments, TIN vault, completeness engine, and updates designs (docs/parties-and-attachments.md) - tests: spec-blind tax basis suites in core, store, MCP; register PDF/XLSX and viewer tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
1 parent
6adc7b34c7
commit
ba7373bdb8
30 files changed
+3240
-93
No files matched your search
@@ -53,6 +53,45 @@ fn attachment_name(b: &Books, id: u64) -> String {
|
||||
.unwrap_or_else(|| format!("attachment {id}"))
|
||||
}
|
||||
|
||||
/// "Tax basis of FL-0001: personal-use conversion, contributor's basis
|
||||
/// $1,917.21 → tax basis $1,650.00". The tax basis is ledger-core's
|
||||
/// (`Asset::tax_basis`) for the event's rule and basis on the asset's
|
||||
/// book cost, which never changes once registered.
|
||||
fn tax_basis_text(b: &Books, asset_id: Option<u64>, p: &Value) -> String {
|
||||
let asset = asset_id.and_then(|id| b.ledger.get_asset(id));
|
||||
let name = match (asset, asset_id) {
|
||||
(Some(a), _) => a.tag.clone().unwrap_or_else(|| a.description.clone()),
|
||||
(None, Some(id)) => format!("asset {id}"),
|
||||
(None, None) => "an asset".to_string(),
|
||||
};
|
||||
let rule = ledger_core::TaxBasisRule::parse(s(p, "rule"));
|
||||
let contributor: Option<rust_decimal::Decimal> = p
|
||||
.get("contributor_basis")
|
||||
.and_then(|v| v.as_str())
|
||||
.and_then(|v| v.parse().ok());
|
||||
let Some(rule) = rule else {
|
||||
return format!("Tax basis of {name} recorded");
|
||||
};
|
||||
let tax = asset.and_then(|a| {
|
||||
let mut a = a.clone();
|
||||
a.tax = Some(ledger_core::TaxBasis {
|
||||
rule,
|
||||
contributor_basis: contributor,
|
||||
});
|
||||
a.tax_basis()
|
||||
});
|
||||
let mut text = format!("Tax basis of {name}: {}", super::assets::rule_words(rule));
|
||||
if let Some(c) = contributor {
|
||||
text.push_str(&format!(", contributor's basis {}", fmt::dollars(c)));
|
||||
}
|
||||
match (tax, contributor.is_some()) {
|
||||
(Some(t), true) => text.push_str(&format!(" → tax basis {}", fmt::dollars(t))),
|
||||
(Some(t), false) => text.push_str(&format!(", tax basis {}", fmt::dollars(t))),
|
||||
(None, _) => {}
|
||||
}
|
||||
text
|
||||
}
|
||||
|
||||
/// A sentence for a meaningful event; `None` for the intermediate steps of
|
||||
/// building an entry (created, line added), which the posted event covers.
|
||||
pub fn describe(b: &Books, line: &JournalLine) -> Option<Event> {
|
||||
@@ -267,6 +306,11 @@ pub fn describe(b: &Books, line: &JournalLine) -> Option<Event> {
|
||||
};
|
||||
ev(icon::BARCODE, text, asset_id.map(Route::Asset))
|
||||
}
|
||||
"asset.tax_basis_set" => ev(
|
||||
icon::SCALES,
|
||||
tax_basis_text(b, asset_id, p),
|
||||
asset_id.map(Route::Asset),
|
||||
),
|
||||
"asset.described" => ev(
|
||||
icon::PENCIL_SIMPLE,
|
||||
format!(
|
||||
|
||||
Reference in new issue
Block a user