P3: the IIF in plain ASCII with every change listed, and the CPA package as of one day (defects 7, 21)
The CPA package's general-journal.iif now holds every posted entry through as_of (closing entries left out, D-36), written as plain ASCII with CR LF, DOCNUM the entry id, QuickBooks Desktop's field limits and subaccount types honoured, and every character written differently listed in the export's warnings and the README (grouped by substitution, TINs masked). The 1099 worksheet stops at as_of too. PDFs print CJK, Arabic, Hebrew, Thai and Devanagari (Noto fallbacks, OFL), and so does the viewer. has_full_tin reads Unicode separators. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
48 files changed
+5661
-317
No files matched your search
@@ -2,29 +2,44 @@
|
||||
//! and the package's `general-journal.iif`.
|
||||
//!
|
||||
//! ```text
|
||||
//! GOAL: the CPA imports every posted entry into QuickBooks Desktop, each
|
||||
//! account declared with the type QuickBooks needs.
|
||||
//! SOURCE: ledger_import::iif (the IIF format and account types).
|
||||
//! GOAL: the CPA imports the books through a day into QuickBooks Desktop,
|
||||
//! each account declared with the type QuickBooks needs, and gets
|
||||
//! the balances and the profit of the package's statements.
|
||||
//! SOURCE: ledger_import::iif (the IIF format and account types); rules.md
|
||||
//! B-33 (as of a day), B-34; DECISION (owner, 2026-10-20, plan
|
||||
//! D-36: closing entries are left out).
|
||||
//! INVARIANTS:
|
||||
//! 1. The cash accounts are BANK; the receivable and payable control
|
||||
//! accounts AR and AP; a registered asset's cost and accumulated
|
||||
//! depreciation FIXASSET; every other account follows its type.
|
||||
//! 2. Every posted entry, and only those.
|
||||
//! accounts AR and AP; the cost and accumulated depreciation accounts
|
||||
//! of an asset bought on or before as_of FIXASSET; every other
|
||||
//! account follows its type. Every account in the chart is declared.
|
||||
//! 2. Every posted entry dated on or before as_of, from the first, in
|
||||
//! the order posted, except period closes: QuickBooks keeps no
|
||||
//! closing entries (it works out retained earnings itself), so an
|
||||
//! imported close would zero its period's profit. The file's
|
||||
//! balances are the trial balance as of as_of without the closes.
|
||||
//! ```
|
||||
|
||||
use chrono::NaiveDate;
|
||||
use ledger_core::{AccountId, AccountType, Ledger};
|
||||
|
||||
/// Render the journal as IIF text via ledger-import, declaring every
|
||||
/// account with its QuickBooks type: the cash accounts (`cash_codes`, the
|
||||
/// books' `cash_accounts`) are BANK, the receivable and payable control
|
||||
/// accounts AR and AP, a registered asset's cost and accumulated
|
||||
/// depreciation FIXASSET, and the rest follow their wanderbooks type
|
||||
/// (other current asset, other current liability, equity, income,
|
||||
/// expense).
|
||||
pub fn export_iif(ledger: &Ledger, cash_codes: &[String]) -> Result<String, String> {
|
||||
/// The journal through `as_of` as IIF, via ledger-import (INVARIANTS 1-2),
|
||||
/// declaring every account with its QuickBooks type: the cash accounts
|
||||
/// (`cash_codes`, the books' `cash_accounts`) are BANK, the receivable and
|
||||
/// payable control accounts AR and AP, the cost and accumulated
|
||||
/// depreciation accounts of an asset bought by `as_of` FIXASSET, and the
|
||||
/// rest follow their wanderbooks type (other current asset, other current
|
||||
/// liability, equity, income, expense). Returns the file and every text it
|
||||
/// writes differently from the books.
|
||||
pub fn export_iif(
|
||||
ledger: &Ledger,
|
||||
cash_codes: &[String],
|
||||
as_of: NaiveDate,
|
||||
) -> Result<ledger_import::Iif, String> {
|
||||
use ledger_import::{QbAccountType as Qb, iif_accounts, journal_to_iif};
|
||||
let fixed: std::collections::HashSet<AccountId> = ledger
|
||||
.registered_assets()
|
||||
.filter(|a| a.purchase_date <= as_of)
|
||||
.flat_map(|a| [a.cost_account, a.accum_depr_account])
|
||||
.collect();
|
||||
let receivables = ledger.role_account(&ledger_core::RECEIVABLES);
|
||||
@@ -48,6 +63,10 @@ pub fn export_iif(ledger: &Ledger, cash_codes: &[String]) -> Result<String, Stri
|
||||
}
|
||||
}
|
||||
});
|
||||
let entries: Vec<_> = ledger.posted_entries().collect();
|
||||
let closes = ledger.closing_entry_ids();
|
||||
let entries: Vec<_> = ledger
|
||||
.posted_entries()
|
||||
.filter(|e| e.date() <= as_of && !closes.contains(&e.id()))
|
||||
.collect();
|
||||
journal_to_iif(&accounts, &entries).map_err(|e| e.to_string())
|
||||
}
|
||||
Reference in new issue
Block a user