Attachments, statements, reconciliations, TIN vault, counterparty policy
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
MCP: books.link_attachment, unlink_attachment, attachments; link_to on attach_receipt and file_document; record_statement, statements; books.reconcile previews and, confirmed against a recorded statement, records the reconciliation; void_reconciliation, reconciliations; import_bank_csv links its source file; digest lists unreconciled accounts. TIN vault: books.set_w9 takes the TIN and the form into the encrypted vault (last four in the books); books.vendor_1099 include_tins and save_csv_to for the CPA's copy; books.get_w9; books.purge_tin. A leak test scans every tool output, the journal, the database, and the blobs. [books] parties = off | suggest | require (default suggest): every preview names the entry's party or suggests likely ones; require refuses to post until it names one or is marked as having none (entry.no_party). Viewer: documents on every subject page; statements and reconciliation history per account; reconciliation pages; reconcile and no-counterparty attention items; party money by period (paid out, received in, net, what for, by month); Needs attention gets its own full-width section. 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
e265ed4339
commit
ae927c3f73
41 files changed
+8463
-465
No files matched your search
@@ -1164,58 +1164,16 @@ pub fn show_asset(ui: &mut Ui, b: &Books, id: AssetId, shell: &mut Shell<'_>) {
|
||||
},
|
||||
);
|
||||
ui.add_space(14.0);
|
||||
let docs: Vec<_> = b
|
||||
.attachments
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
x.withdrawn_at.is_none() && x.entry_id.is_some_and(|e| entries.contains(&e))
|
||||
})
|
||||
.collect();
|
||||
widgets::titled_card(
|
||||
let mut subjects = vec![ledger_store::Subject::Asset(id)];
|
||||
subjects.extend(entries.iter().map(|e| ledger_store::Subject::Entry(*e)));
|
||||
super::documents::documents_card_with(
|
||||
ui,
|
||||
b,
|
||||
"Receipts and documents",
|
||||
|_| {},
|
||||
|ui| {
|
||||
if docs.is_empty() {
|
||||
ui.label(
|
||||
RichText::new("None linked to its entries (depreciation needs none: the schedule is its evidence).")
|
||||
.color(p.muted),
|
||||
);
|
||||
}
|
||||
for d in &docs {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(
|
||||
RichText::new(if d.mime_type == "application/pdf" {
|
||||
icon::FILE_PDF
|
||||
} else {
|
||||
icon::FILE_IMAGE
|
||||
})
|
||||
.color(p.muted),
|
||||
);
|
||||
if widgets::link_truncated(
|
||||
ui,
|
||||
RichText::new(format!(
|
||||
"{} · {} · entry #{}",
|
||||
d.file_name,
|
||||
fmt::label(&d.category),
|
||||
d.entry_id.unwrap_or(0)
|
||||
))
|
||||
.font(theme::regular(13.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
go = Some(Route::Document(d.id));
|
||||
}
|
||||
});
|
||||
if let Some(desc) = &d.description {
|
||||
ui.label(
|
||||
RichText::new(desc)
|
||||
.font(theme::regular(11.5))
|
||||
.color(p.faint),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
&subjects,
|
||||
&[ledger_store::Subject::Asset(id)],
|
||||
"None linked to it or its entries (photos, the warranty, the manual; depreciation needs none: the schedule is its evidence).",
|
||||
&mut go,
|
||||
);
|
||||
ui.add_space(14.0);
|
||||
|
||||
|
||||
Reference in new issue
Block a user