feat(iif): carry each line's project in CLASS, the classes declared first
The P3 cutover review's open point 1: entries carry projects (classes, B-37), but the QuickBooks Desktop file (B-34) left the CLASS field empty on every line, and neither B-34 nor the README said so, though B-34 rule 6 says nothing changes silently. Intuit's IIF Import Kit (vendored in docs/spec/sources/intuit-iif.md, the kit's SHA-256 unchanged): the `!CLASS` header help says "Only the NAME column is required" and a subclass's NAME is its parents' names first, joined by colons; the kit's "Import First - List Declarations" example declares `!CLASS` rows before any transaction, and its "2004 Deposit (Income)" example names the class line by line in CLASS. So the file now declares every class in a `!CLASS` list after the accounts and before `!TRNS`, and writes each line's class in CLASS (empty where the line has none). Books with no class write no list, byte for byte as before. A line whose class wasn't declared is refused (IifError::UndeclaredClass), never written classless. A class's NAME follows B-34's rules for an account's own name: plain ASCII (rule 3), a colon written '-' (it would start a subclass), trimmed, '?' if nothing is left, cut to 31 characters: Intuit's qbXML Onscreen Reference gives `ClassAdd`'s Name "maxDT" : 31 (and 31 in the Canadian, UK and Australian desktop editions; 100 only in Online), the same as its `AccountAdd` Name (both JSON files vendored by SHA-256); Conductor's QuickBooks Desktop API reference agrees and says the name is case-insensitive. Classes whose NAMEs would match ignoring case get " (id)", round after round, as accounts get " (code)", except that among names that match, those already written differently from the books (made safe, or tagged) yield first, a second " (id)" if need be: a class's own name is kept unless another class's own name is the same ignoring case (classes 1 "Café", 2 "Cafe", 3 "Cafe (1)" are written "Cafe (1) (1)", "Cafe", "Cafe (1)"). Each class is tagged twice at most and ids differ, so none is left alike (a hand-built list is refused). Each class name written differently is an IifChange (IifField::ClassName), said one line each in the warnings and in the package README, whose "written differently" paragraph now names class names' limits; its IIF line says CLASS is each line's project when there are classes. The MCP and viewer notes count "account or class name(s)". API: `iif_classes(ledger)` builds the list; `journal_to_iif` takes it (`&[]` for none). Docs: rules.md B-34 rule 8 with its sources; intuit-iif.md (the `!CLASS` help, the list declarations and deposit examples, Intuit's SDK department page, the qbXML Onscreen Reference's ClassAdd and AccountAdd and Conductor's class reference, each with SHA-256); mcp-interface.md (books.export iif, the package note); the bookspec example iif-quickbooks-journal-file.toml (two projects: one carried and renamed, one only declared; every line derived by hand); testing.md; STATUS (open point 1 done; point 3 waits for the close, the owner said). Tests: ledger-import `iif_writes_each_lines_class_and_declares_the_classes_first`, `iif_class_names_fit_quickbooks_and_every_change_is_listed`, `iif_class_names_written_as_the_books_have_them_are_kept`, `iif_refuses_an_undeclared_or_unfit_class`, property `iif_class_names_never_clash`; ledger-package `the_package_iif_carries_each_lines_project` and the bookspec example. Broken to confirm: CLASS written empty fails the two exact-file tests, the package test and the bookspec example; the " (id)" tag dropped fails the names test and the property; tagging every name that meets (no yielding) fails the kept-names test and the property (its shrunk case, "A-B" beside "A\uFF1AB", kept in the regressions file). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
17 files changed
+1026
-89
No files matched your search
+15
-3
@@ -188,11 +188,23 @@ its invoices. The handbook's caveat is gone for books with the feature.
|
||||
`projects` but not it, so until the owner's next format upgrade
|
||||
(`wanderbooks books upgrade`, D-39) their invoices and bills still take
|
||||
none (the handbook says so).
|
||||
- Raised by the cutover review (private change log, "Open points"): the
|
||||
IIF leaves its CLASS field empty although entries carry projects; a
|
||||
- Raised by the cutover review (private change log, "Open points"): a
|
||||
state filing fee is classed as cash paid to suppliers where ASC
|
||||
230-10-45-17(c) suggests other operating payments; ties in the per-entry
|
||||
member split all go to the first member.
|
||||
member split all go to the first member (the owner, 2026-10-22: nothing
|
||||
is posted until the year-end close, three weeks off, so it waits).
|
||||
Its first point is done (2026-10-22, B-34 rule 8): the IIF writes each
|
||||
line's project in CLASS, the projects declared first in a `!CLASS`
|
||||
list, their names held to QuickBooks' 31 characters, no two alike, and
|
||||
listed in the README when written differently (tests
|
||||
`iif_writes_each_lines_class_and_declares_the_classes_first`,
|
||||
`iif_class_names_fit_quickbooks_and_every_change_is_listed`,
|
||||
`iif_class_names_written_as_the_books_have_them_are_kept`,
|
||||
`iif_refuses_an_undeclared_or_unfit_class`, the property
|
||||
`iif_class_names_never_clash`, `the_package_iif_carries_each_lines_project`;
|
||||
bookspec `iif-quickbooks-journal-file`). The first company's
|
||||
package changes at its next build: its project-tagged lines carry
|
||||
the class, and the class list is new.
|
||||
- The viewer recomputes a long-life asset's whole schedule every frame
|
||||
(`ledger-gui` `pages/assets.rs` `schedule`, called from the asset
|
||||
page's draw; defect 22's note: slow, never wrong).
|
||||
|
||||
Reference in new issue
Block a user