Skip to content

AR: the aging, the statement and the invoices agree - #153

Merged
futurebuildai merged 36 commits into
refactor/v1from
refactor/g1-ar-agree
Oct 15, 2026
Merged

futurebuildai merged 36 commits into
refactor/v1from
refactor/g1-ar-agree

Conversation

@futurebuildai

Copy link
Copy Markdown
Contributor

Item 130, G1 walk notes N12 and N13.

Why. The base seed dated each paying check a fixed step after its invoice, so an invoice made late in the seed's span had a check from the future. The aging counts an application only on or before its as of day, so it showed that invoice open while the invoice read PAID, and the dashboard's Outstanding AR carried the same figure. The statement dated every row from the subledger row's stamp, which the base seed left at the moment it ran.

What changed

  • Seed: a check the rule would date later is received on the seed's own day (chosen over leaving the invoice unpaid because the walk wants the history paid as designed; an invoice dated after the seed's day is left unpaid, and the seed no longer dates an invoice past that day). The base seed restamps its subledger, payment and ledger rows to the documents' days (new RestampDay in the AR core, stamps only).
  • AR core: a payment received, an application, a credit memo application, a write off and both refunds dated after the business day in the branch's time zone are refused in words (400 naming the field). Void and reversal acts are not covered: their day is always computed on the server.
  • Statement: each row is dated from its document (invoice day, credit memo day, received day, applied day, refunded day; a void or a reversal by its own day); the opening balance, the period and the order split on that day.
  • Found on the way: the aging by customer answered 500 on any page that was not the last (an empty group id in the cursor). Fixed with its own red leg.

Red legs, each committed alone first

  1. TestDemoImport/no money is dated after the seed's day and the aging agrees with the documents
  2. TestDemoImport/the dashboard's Outstanding AR equals the aging summary's total (and the documents)
  3. TestARRefusesAPaymentReceivedOnADayToCome, TestARRefusesAnApplicationOnADayToCome
  4. TestARStatementDatesEachRowFromItsDocument
  5. TestARAgingByCustomerPagesThroughItsCursor

Existing tests that relied on a later day (three, listed for the reviewer): TestARDiscountTakenAndReversed (late discount case now an invoice whose discount date has gone, applied today) and two POS payment tests that used a day far ahead as a stand in for any day (now a day in the past).

Goldens moved (clockwindow, gl_accounts_entries, reporting_reports), with a CONTRACT-CHANGES row. No wire shape changes.

🤖 Generated with Claude Code

futurebuildai and others added 30 commits October 14, 2026 13:18
… is refused

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…h the documents

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… on the seeded database

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
A payment received, an application, a credit memo application, a write off
and both refunds on a day after the business day in the branch's time zone
are refused in words. RestampDay lets the base seed put documents' days on
its rows for invoices that are part paid or unpaid.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…documents' days

A check the rule would date later is received on the seed's own day; an
invoice dated after that day is left unpaid and never dated past it. The base
seed restamps its subledger rows to the documents' days.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… days

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…er dated after today

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…e, and the branch's own day rules

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…lance

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… not come

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
The subledger writes a row when cash is applied, never on receipt. Each
currency now carries the payments still unapplied as of the statement's last
day, their sum and the net balance, which equals the aging's total that day.
Contract, goldens, the page and the seeded sweep follow.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…rvice

The invoice day is now refused when it has not come, so a test that moves the
order service's clock moves the account service's too.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… and a future invoice day names invoiced_at

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…n its day is unread, the contract row names every moved value

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… and the balance stays whole

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…e yard and the balance covers the account

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…ces stay whole; WithClockForTest

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…eption to net equals aging

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
… and the unapplied cash at other yards is named

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…plied cash at other yards is named

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…hours when UTC's day is ahead

The core refuses money dated after the branch's own day; a leg that dated
today by the UTC clock was refused between UTC's midnight and the branch's.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Between UTC's midnight and the branch's, the UTC date is a day the AR core
refuses, so the history's documents dated by it were not posted. The history
now trades the default branch's calendar day, and its today check skips when
the server's UTC day is ahead of it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
The seed's business day is its branches' calendar day. The harness seeded in
the branches' own zone and pinned them to UTC afterwards, so between UTC's
midnight and that zone's the seeded days and the server's day cut differed
and clockwindow and gl_accounts_entries drifted. The seed now takes its
branch zone from SEED_BRANCH_TIMEZONE (the production seed leaves it unset
and keeps its zone) and the harness sets it to the server's zone. The goldens
pass unchanged at an hour when UTC's date is ahead of the branch's.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
futurebuildai and others added 6 commits October 14, 2026 18:31
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Signed-off-by: colton <colton@futurebuild.ai>
…atabase

payment, pos and migration legs date by the branch's day; the account legs
read it from the database, so a zone Go cannot load (a day behind UTC at every
hour) is read as the core reads it; the legacy row's stamp is noon in the
branch's zone; the dashboard leg's yards sit in the default branch's zone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…d by grants with no yard chosen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
…ed settings; the page names unapplied cash at other yards for any scoped caller

SEED_NOW is set by tests and unset in production. Both seed runs of
TestDemoImport read one instant. SEED_BRANCH_TIMEZONE and SEED_NOW are checked
at start and refused in words.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: colton <colton@futurebuild.ai>
Signed-off-by: colton <colton@futurebuild.ai>
@futurebuildai
futurebuildai merged commit 68edfcb into refactor/v1 Oct 15, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant