Requires cboxdk/laravel-geo ^0.6.
Four ways this package could hand back a confident wrong answer, and the seam
that made a multi-tenant host guess.
Breaking
Every seam names the seller it answers for. SalesLedger, PhysicalNexus
and NexusRegistrations take a NexusSubject; NexusEngine::evaluate() and
report() accept one. None of them did. A ledger holding several sellers was
asked only "what are the totals for California" and had to infer who from
ambient request or container state — which is how one tenant's totals get
reported as another's, silently, with every figure looking ordinary. A
single-seller host passes null and nothing changes.
SalesLedger::activityFor() takes an ActivityQuery. The old seam asked an
incomplete question: it never said what to count, so an implementation had to
look the threshold up itself to learn that Florida measures taxable sales over
the previous calendar year while Texas measures gross receipts over a rolling
twelve months — reaching past the contract in order to satisfy it. The query now
carries the basis, the period, and windows(), which turns those rules into
concrete dates once instead of in every implementation.
NexusThresholdSource::thresholdFor() takes an optional $at, so a
back-dated evaluation stops being answered with today's law.
Fixed
The rolling twelve months is a year to the day. It began at the first of the
month eleven months back, dropping the first partial month: a $500,000 sale on
20 August fell outside a window starting 1 September, and a seller who had
unambiguously crossed was reported Below. Texas measures the preceding twelve
months, evaluated at any point in time.
periodStart / periodEnd are finally read. They had been carried since
they were written while nothing looked at them, so a ledger declaring the right
rule over the wrong twelve months — a cache warmed last quarter, an as-of date
computed at boot — was accepted without comment. The check bounds rather than
refuses outright: a shorter range that has already crossed is provably met, a
longer one still below is provably below.
Physical presence in Oregon no longer says "register". It is real presence
and it does establish nexus — but nexus to what? There is no general sales tax
there, and the advice handed a seller a filing obligation, due dates and
penalties in exchange for nothing.
The dataset is verified before it is believed — manifest sha256 and
schemaVersion — where its twin in laravel-tax already was. An unreadable
transaction threshold no longer becomes null, which silently downgraded an OR
rule to sales-only and told a seller over the transaction test they were below
it. A future-only window is no longer served as though it applied today.