P3 review: asset bases and the tax-basis K-1
Schema 13 is as shipped and the asset columns are schema 14 (shipped migrations pinned by hash); the tax-basis K-1 leaves net income open (only the return has it) and takes a contributed prepaid plan at its book amount as its section 723 basis; a disposal of contributed property names its 704(c) gain or loss; aliases compare by meaning; fixture amounts made up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
24 files changed
+860
-127
No files matched your search
@@ -203,8 +203,11 @@ pub fn book_vs_tax(rule: Option<BasisRule>) -> &'static str {
|
||||
Some(BasisRule::Purchase) => {
|
||||
"Book cost and tax basis are both what the company paid; tax depreciation starts from the tax basis — the CPA's."
|
||||
}
|
||||
_ => {
|
||||
"Book value is the fair market value at contribution; the tax figures are at contribution, and tax depreciation starts from the depreciable basis — the CPA's."
|
||||
Some(BasisRule::Carryover723 | BasisRule::PersonalUseConversion) => {
|
||||
"Book cost is the fair market value at contribution, and book value that cost less the depreciation posted; the tax figures are at contribution, and tax depreciation starts from the depreciable basis — the CPA's."
|
||||
}
|
||||
None => {
|
||||
"No tax basis is recorded: book value is cost less the depreciation posted; the tax figures follow once the basis is recorded."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1433,7 +1436,7 @@ fn tax_card(ui: &mut Ui, a: &Asset) {
|
||||
ui.add(
|
||||
egui::Label::new(
|
||||
RichText::new(
|
||||
"Ask the bookkeeper to record it (books.set_asset_tax_basis): was it bought by the company, contributed by a member from business use, or converted from personal use? Book value is the fair market value at contribution; tax depreciation starts from the tax basis — the CPA's.",
|
||||
"Ask the bookkeeper to record it (books.set_asset_tax_basis): was it bought by the company, contributed by a member from business use, or converted from personal use? For a contribution, book cost is the fair market value at contribution; tax depreciation starts from the depreciable basis — the CPA's.",
|
||||
)
|
||||
.font(theme::regular(12.5))
|
||||
.color(p.muted),
|
||||
|
||||
@@ -363,6 +363,9 @@ fn assets(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) {
|
||||
AssetStatus::Disposed { date, .. } if *date <= b.today => Some(*date),
|
||||
_ => None,
|
||||
};
|
||||
// Not on the books until its acquired date: no book value
|
||||
// yet (the register leaves it out the same way).
|
||||
let later = b.ledger.asset_acquired_date(a.id).filter(|d| *d > b.today);
|
||||
let acc = b.ledger.accumulated_posted(a.id, b.today);
|
||||
let scheduled = accumulated_scheduled_through(a, b.today);
|
||||
let dep = a.cost.amount - a.salvage_value.amount;
|
||||
@@ -391,6 +394,10 @@ fn assets(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) {
|
||||
);
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
let text = match (&acc, disposed) {
|
||||
_ if later.is_some() => format!(
|
||||
"not on the books until {}",
|
||||
fmt::date(later.expect("checked"))
|
||||
),
|
||||
(_, Some(_)) => format!("book value {}", fmt::dollars(Decimal::ZERO)),
|
||||
(Ok(acc), None) => {
|
||||
format!("book value {}", fmt::dollars(a.cost.amount - *acc))
|
||||
|
||||
@@ -65,7 +65,10 @@ fn attachment_name(b: &Books, id: u64) -> String {
|
||||
/// depreciable basis $1,440.00, built-in loss $248.40". The figures are
|
||||
/// ledger-core's (`Asset::basis_figures`) for the event's facts on the
|
||||
/// asset; a pre-P3 `asset.tax_basis_set` (`legacy`: its rule by its old
|
||||
/// name, no value) reads the value as the book cost, as it was recorded.
|
||||
/// name, no value) reads the value as the asset's book cost today, which
|
||||
/// is the cost it was recorded against unless the cost was corrected since
|
||||
/// (a correction moves a pre-P3 record's built-in gain, and the line shows
|
||||
/// today's figure).
|
||||
fn tax_basis_text(b: &Books, asset_id: Option<u64>, p: &Value, legacy: bool) -> String {
|
||||
let asset = asset_id.and_then(|id| b.ledger.get_asset(id));
|
||||
let name = match (asset, asset_id) {
|
||||
|
||||
@@ -1148,17 +1148,20 @@ fn aging(
|
||||
|
||||
/// The fixed asset register on `as_of`: ledger-core's
|
||||
/// `fixed_asset_register`, laid out, with its reconciliation to the
|
||||
/// general ledger and what that says (the Assets page's notices). Each
|
||||
/// asset's federal tax basis sits beside its book figures: contributor's
|
||||
/// basis, tax basis, and built-in gain (loss), the register row's own,
|
||||
/// with its rule (and citation) in the detail; the tax basis total is the
|
||||
/// general ledger and what that says (the Assets page's notices). The
|
||||
/// book figures in the Assets page's order (cost, posted, book value =
|
||||
/// cost less posted, then the schedule's figure); beside them each
|
||||
/// asset's tax figures at contribution, the register row's own: §723
|
||||
/// basis, depreciable basis and §704(c) built-in gain (loss), with its
|
||||
/// rule (and citation), value at contribution, method and, for a built-in
|
||||
/// loss, the IRC §704(c)(1)(C) note in the detail; the totals are the
|
||||
/// register's.
|
||||
fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
let mut t = Table::new(vec![
|
||||
"Cost".into(),
|
||||
"Scheduled".into(),
|
||||
"Posted".into(),
|
||||
"Book value".into(),
|
||||
"Scheduled".into(),
|
||||
// Short enough for the columns: the note says what each is.
|
||||
"§723 basis".into(),
|
||||
"Depr. basis".into(),
|
||||
@@ -1217,6 +1220,12 @@ fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
ledger_import::asset_register::method_cited(m)
|
||||
));
|
||||
}
|
||||
if tax.built_in_gain_704c.is_some_and(|g| g < Decimal::ZERO) {
|
||||
detail.push(
|
||||
"a built-in loss counts only for the contributing member (IRC §704(c)(1)(C))"
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
let opt = |v: Option<Decimal>| Cell {
|
||||
value: v,
|
||||
drill: None,
|
||||
@@ -1232,9 +1241,9 @@ fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
}
|
||||
None => vec![
|
||||
Cell::of(x.cost),
|
||||
Cell::of(x.accumulated_scheduled),
|
||||
Cell::of(x.accumulated_posted),
|
||||
Cell::of(x.book_value),
|
||||
Cell::of(x.accumulated_scheduled),
|
||||
opt(tax.tax_basis_723),
|
||||
opt(tax.depreciable_basis),
|
||||
opt(tax.built_in_gain_704c),
|
||||
@@ -1252,9 +1261,9 @@ fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
"Total held",
|
||||
vec![
|
||||
Cell::of(r.total_cost),
|
||||
Cell::of(r.total_accumulated_scheduled),
|
||||
Cell::of(r.total_accumulated_posted),
|
||||
Cell::of(r.total_book_value),
|
||||
Cell::of(r.total_accumulated_scheduled),
|
||||
Cell::of(r.total_tax_basis_723),
|
||||
Cell::of(r.total_depreciable_basis),
|
||||
Cell::none(),
|
||||
@@ -1292,11 +1301,11 @@ fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
value: Some(r.ledger_accumulated),
|
||||
drill: accum_drill,
|
||||
},
|
||||
Cell::of(r.ledger_cost - r.ledger_accumulated),
|
||||
Cell {
|
||||
value: Some(r.ledger_accumulated),
|
||||
drill: accum_drill,
|
||||
},
|
||||
Cell::of(r.ledger_cost - r.ledger_accumulated),
|
||||
Cell::none(),
|
||||
Cell::none(),
|
||||
Cell::none(),
|
||||
@@ -1307,9 +1316,9 @@ fn asset_register(b: &Books, as_of: NaiveDate) -> Table {
|
||||
"Register less books",
|
||||
vec![
|
||||
Cell::of(-r.unregistered_cost()),
|
||||
Cell::of(r.unposted_depreciation()),
|
||||
Cell::of(-r.unattributed_accumulated()),
|
||||
Cell::of(r.total_book_value - (r.ledger_cost - r.ledger_accumulated)),
|
||||
Cell::of(r.unposted_depreciation()),
|
||||
Cell::none(),
|
||||
Cell::none(),
|
||||
Cell::none(),
|
||||
@@ -2441,9 +2450,9 @@ mod tests {
|
||||
t.columns,
|
||||
[
|
||||
"Cost",
|
||||
"Scheduled",
|
||||
"Posted",
|
||||
"Book value",
|
||||
"Scheduled",
|
||||
"§723 basis",
|
||||
"Depr. basis",
|
||||
"Built-in gain"
|
||||
@@ -2462,9 +2471,9 @@ mod tests {
|
||||
v,
|
||||
[
|
||||
Some(x.cost),
|
||||
Some(x.accumulated_scheduled),
|
||||
Some(x.accumulated_posted),
|
||||
Some(x.book_value),
|
||||
Some(x.accumulated_scheduled),
|
||||
f.tax_basis_723,
|
||||
Some(f.depreciable_basis),
|
||||
f.built_in_gain_704c,
|
||||
@@ -2476,7 +2485,9 @@ mod tests {
|
||||
let total = t.rows.iter().find(|row| row.label == "Total held").unwrap();
|
||||
assert_eq!(total.cells[5].value, Some(r.total_depreciable_basis));
|
||||
assert_eq!(total.cells[5].value, r.rows[0].depreciable_basis);
|
||||
assert_eq!(total.cells[2].value, Some(r.total_accumulated_posted));
|
||||
assert_eq!(total.cells[1].value, Some(r.total_accumulated_posted));
|
||||
assert_eq!(total.cells[2].value, Some(r.total_book_value));
|
||||
assert_eq!(total.cells[3].value, Some(r.total_accumulated_scheduled));
|
||||
assert!(
|
||||
t.rows
|
||||
.iter()
|
||||
|
||||
Reference in new issue
Block a user