fix(statements): an archive is history below the year start, not nothing
c6feae9 excluded imported periods from the current period outright. That is
right for the rows an archive spills into the following January — those already
sit inside the next year's BALANCE FORWARD, which is the sum of the whole
archive, so counting them again would double-book them and file a closed year's
row as current.
It is wrong for everything below the year start. Those rows are what `opening`
exists for, and for a customer whose newest BALANCE FORWARD lives *inside* an
archive they are the only carry there is: the corte skipped NUMid 295 in 2026,
so his floor is the archive's own January 1 and excluding it dropped his entire
2025 closing balance. His statement read 3,592.00 against a true 4,377.46.
So the rule is a window, not an exclusion: an archive row counts below the year
start and never at or above it. Applied identically to statement(), the
edo-cuenta-datos report and the customer-file card, which have to agree.
Spelled as a positive OR rather than NOT(tag AND date). `NOT (col LIKE '...'
AND ...)` is NULL for a row with no legacySourceTable, so the negated form would
have silently dropped every app-captured movement — the same NULL trap the
source-table exclusion was already fixed for.
Verified against prod, which now carries datos2@2025: exactly one customer is
affected and the book moves by his 785.46. NUMid 501 is unchanged at -10,874.33
and still matches the portal; 6 and 173 are unchanged to the cent; the two
customers whose archives spill into January 2026 still keep those rows out of
the current period.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -159,15 +159,18 @@ describe("balance floor", () => {
|
||||
const where = rowsQuery(findMany).where;
|
||||
expect(where.OR).toEqual([
|
||||
{ legacySourceTable: null },
|
||||
{ legacySourceTable: { notIn: expect.arrayContaining(["EFECTIVO"]) } },
|
||||
]);
|
||||
// Imported periods are windowed rather than excluded: history below the
|
||||
// year start (the only carry a floored-by-archive customer has), never
|
||||
// at or above it (those rows sit inside the next BALANCE FORWARD).
|
||||
expect(where.AND).toEqual([
|
||||
{
|
||||
legacySourceTable: {
|
||||
notIn: expect.arrayContaining(["EFECTIVO"]),
|
||||
// Imported prior periods are excluded here too. The floor does not
|
||||
// cover them: a customer whose newest BALANCE FORWARD sits inside
|
||||
// an archive floors at that archive's own Jan 1, and every archive
|
||||
// spills a row or two into the following January.
|
||||
not: { startsWith: "datos2@" },
|
||||
},
|
||||
OR: [
|
||||
{ legacySourceTable: null },
|
||||
{ legacySourceTable: { not: { startsWith: "datos2@" } } },
|
||||
{ transactionDate: { lt: expect.any(Date) } },
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user