Files
MattssonandClaude Fable 5.1 9a8291f454 feat(reports): list a booked 8999 in Resultatrapport instead of hiding it (#2457)
* feat(reports): list a booked 8999 in Resultatrapport instead of hiding it

Resultatrapport and dimension-pnl filtered account 8999 out and printed a
computed result row, so a user who books or imports the omföring of årets
resultat by hand saw huvudboken and the account-level report disagree.

Why it occurred: the filter was copied from the formal Resultaträkning,
where it is right (ÅRL's uppställningsform has no 8999 line). In the
operational report it hid a real balance. Our own bokslut verifikat never
posts 8999 (it zeroes each P&L account straight against 2099), so the only
8999 balances that exist are manual or SIE-imported ones, exactly the case
the report suppressed.

What was removed: the exclusion itself, in both operational reports, so
they keep reconciling. The XLSX bottom row is renamed to "Beräknat resultat"
to match the UI and PDF. Beräknat resultat now reads zero after such an
omföring, the Fortnox/Visma resultatrapport convention.

Why this and not the proposed shape: the user asked about Resultaträkning,
which stays as is on purpose. The bigger version (Stage 2 of #1051, showing
the bokslut verifikat via exclude-final) would zero every row of a closed
year given our closing-entry shape and is a separate decision; recorded in
DECISIONS.md.

Fixes #2455

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131jmfXGzSdyjaQoGiCoo1t

* test(reports): pin the deliberate 8999 gap between Resultatrapport and Resultaträkning

The cross-surface agreement test claimed the two operational reports are
identical; after #2455 they differ by exactly a booked 8999 omföring, and
the fixture had no such row so the invariant went silently false. Pin the
gap explicitly, and note in DECISIONS.md that this supersedes the
2026-07-29 same-profit line.

Refs #2455

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131jmfXGzSdyjaQoGiCoo1t

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 13:57:38 +02:00

607 lines
23 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
vi.mock('../trial-balance', () => ({
generateTrialBalance: vi.fn(),
}))
// Mocked rather than fed through the queued Supabase stub: the queue resolves
// in strict call order, so an extra real query inside the engine would shift
// every enqueued response in this file.
vi.mock('../latest-vouchers', () => ({
getLatestPostedVouchers: vi.fn(),
}))
import { generateResultatrapport, shiftDateOneYearBack } from '../resultatrapport'
import { generateTrialBalance } from '../trial-balance'
import { getLatestPostedVouchers } from '../latest-vouchers'
import { createQueuedMockSupabase } from '@/tests/helpers'
import type { TrialBalanceRow } from '@/types'
const mockTrialBalance = vi.mocked(generateTrialBalance)
const mockLatestVouchers = vi.mocked(getLatestPostedVouchers)
beforeEach(() => {
vi.clearAllMocks()
mockLatestVouchers.mockResolvedValue([])
})
function makeRow(overrides: Partial<TrialBalanceRow>): TrialBalanceRow {
const row: TrialBalanceRow = {
account_number: '3001',
account_name: 'Test',
account_class: 3,
opening_debit: 0,
opening_credit: 0,
period_debit: 0,
period_credit: 0,
closing_debit: 0,
closing_credit: 0,
...overrides,
}
// Full-period P&L reality: no opening balance, so window activity equals
// closing. Tests specify closing_*; mirror into period_* unless the test
// sets period activity explicitly.
if (row.period_debit === 0 && row.period_credit === 0) {
row.period_debit = row.closing_debit
row.period_credit = row.closing_credit
}
return row
}
function tb(rows: TrialBalanceRow[]) {
const totalDebit = rows.reduce((s, r) => s + r.closing_debit, 0)
const totalCredit = rows.reduce((s, r) => s + r.closing_credit, 0)
return {
rows,
totalDebit: Math.round(totalDebit * 100) / 100,
totalCredit: Math.round(totalCredit * 100) / 100,
isBalanced: Math.abs(totalDebit - totalCredit) < 0.01,
}
}
describe('generateResultatrapport', () => {
it('groups P&L accounts by class with current and prior period values', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Försäljning 25%', account_class: 3, closing_credit: 100000 }),
makeRow({ account_number: '5010', account_name: 'Lokalhyra', account_class: 5, closing_debit: 30000 }),
makeRow({ account_number: '7210', account_name: 'Löner', account_class: 7, closing_debit: 50000 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.groups).toHaveLength(3)
expect(report.groups.map((g) => g.class)).toEqual([3, 5, 7])
expect(report.groups[0].rows[0]).toEqual({
account_number: '3001',
account_name: 'Försäljning 25%',
current_period: 100000,
prior_period: 0,
})
// Expense rows shown as negative (credit - debit)
expect(report.groups[1].rows[0].current_period).toBe(-30000)
expect(report.groups[2].rows[0].current_period).toBe(-50000)
// Net result = revenue - expenses = 100000 - 30000 - 50000 = 20000
expect(report.net_result_current).toBe(20000)
expect(report.net_result_prior).toBe(0)
expect(report.prior_period).toBeNull()
})
it('joins prior-period values onto current accounts', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: 'period-0' },
error: null,
})
q.enqueue({
data: { period_start: '2025-01-01', period_end: '2025-12-31' },
error: null,
})
mockTrialBalance
.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Försäljning', account_class: 3, closing_credit: 200000 }),
makeRow({ account_number: '5010', account_name: 'Lokalhyra', account_class: 5, closing_debit: 60000 }),
])
)
.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Försäljning', account_class: 3, closing_credit: 150000 }),
makeRow({ account_number: '5010', account_name: 'Lokalhyra', account_class: 5, closing_debit: 45000 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
const revenueRow = report.groups[0].rows[0]
expect(revenueRow.current_period).toBe(200000)
expect(revenueRow.prior_period).toBe(150000)
const expenseRow = report.groups[1].rows[0]
expect(expenseRow.current_period).toBe(-60000)
expect(expenseRow.prior_period).toBe(-45000)
expect(report.net_result_current).toBe(140000)
expect(report.net_result_prior).toBe(105000)
expect(report.prior_period).toEqual({ start: '2025-01-01', end: '2025-12-31' })
})
it('includes accounts that exist only in prior period (with current=0)', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: 'period-0' },
error: null,
})
q.enqueue({
data: { period_start: '2025-01-01', period_end: '2025-12-31' },
error: null,
})
mockTrialBalance
.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Försäljning', account_class: 3, closing_credit: 100000 }),
])
)
.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Försäljning', account_class: 3, closing_credit: 80000 }),
// Account discontinued this year
makeRow({ account_number: '3002', account_name: 'Gammal intäkt', account_class: 3, closing_credit: 5000 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
const class3 = report.groups.find((g) => g.class === 3)!
expect(class3.rows).toHaveLength(2)
const discontinued = class3.rows.find((r) => r.account_number === '3002')!
expect(discontinued.current_period).toBe(0)
expect(discontinued.prior_period).toBe(5000)
})
it('lists a booked 8999 as a class-8 row and nets it into beräknat resultat (#2455)', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Revenue', account_class: 3, closing_credit: 100000 }),
makeRow({ account_number: '8999', account_name: 'Årets resultat', account_class: 8, closing_debit: 100000 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
const class8 = report.groups.find((g) => g.class === 8)
const row8999 = class8?.rows.find((r) => r.account_number === '8999')
expect(row8999?.current_period).toBe(-100000)
// The omföring of årets resultat zeroes the operational result, exactly
// as a Fortnox/Visma resultatrapport reads after bokslut.
expect(report.net_result_current).toBe(0)
})
it('ignores balance accounts (class 1-2)', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([
makeRow({ account_number: '1930', account_name: 'Bank', account_class: 1, closing_debit: 50000 }),
makeRow({ account_number: '2440', account_name: 'Lev.skuld', account_class: 2, closing_credit: 10000 }),
makeRow({ account_number: '3001', account_name: 'Revenue', account_class: 3, closing_credit: 40000 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.groups).toHaveLength(1)
expect(report.groups[0].class).toBe(3)
})
it('drops rows where both current and prior are zero', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([
makeRow({ account_number: '3001', account_name: 'Revenue', account_class: 3, closing_credit: 50000 }),
makeRow({ account_number: '3002', account_name: 'Tom rad', account_class: 3, closing_credit: 0 }),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.groups[0].rows).toHaveLength(1)
expect(report.groups[0].rows[0].account_number).toBe('3001')
})
it('falls back to the date-adjacent prior period when previous_period_id is null', async () => {
// Reproduces the multi-year-SIE bug: the continuity chain was never linked,
// so the comparison must resolve the prior year by date instead.
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
// Date-range fallback finds the immediately-preceding period.
q.enqueue({ data: [{ id: 'period-0' }], error: null })
// Prior-period dates.
q.enqueue({ data: { period_start: '2025-01-01', period_end: '2025-12-31' }, error: null })
mockTrialBalance
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 200000 })])
)
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 150000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.groups[0].rows[0].current_period).toBe(200000)
expect(report.groups[0].rows[0].prior_period).toBe(150000)
expect(report.prior_period).toEqual({ start: '2025-01-01', end: '2025-12-31' })
// The fallback resolved 'period-0' and the prior TB was fetched for it.
expect(mockTrialBalance).toHaveBeenNthCalledWith(2, expect.anything(), 'company-1', 'period-0', {
closingEntry: 'exclude-all-year-end',
})
})
it('leaves the prior column empty when there is no earlier period at all', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
q.enqueue({ data: [], error: null }) // no date-adjacent predecessor
mockTrialBalance.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 100000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.prior_period).toBeNull()
expect(report.net_result_prior).toBe(0)
expect(mockTrialBalance).toHaveBeenCalledTimes(1)
})
it('throws when fiscal period not found', async () => {
const q = createQueuedMockSupabase()
q.enqueue({ data: null, error: null })
await expect(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
generateResultatrapport(q.supabase as any, 'company-1', 'missing')
).rejects.toThrow('Fiscal period not found')
})
it('compares a date range against the same window shifted one year back', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: 'period-0' },
error: null,
})
// Fiscal periods covering the shifted window 2025-01-01..2025-03-31.
q.enqueue({
data: [{ id: 'period-0', period_start: '2025-01-01', period_end: '2025-12-31' }],
error: null,
})
mockTrialBalance
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 90000 })])
)
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 60000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1', {
fromDate: '2026-01-01',
toDate: '2026-03-31',
})
expect(report.groups[0].rows[0].current_period).toBe(90000)
expect(report.groups[0].rows[0].prior_period).toBe(60000)
expect(report.prior_period).toEqual({ start: '2025-01-01', end: '2025-03-31' })
expect(mockTrialBalance).toHaveBeenNthCalledWith(2, expect.anything(), 'company-1', 'period-0', {
closingEntry: 'exclude-all-year-end',
fromDate: '2025-01-01',
toDate: '2025-03-31',
})
})
it('merges the shifted window across two fiscal periods (brutet räkenskapsår)', async () => {
const q = createQueuedMockSupabase()
// Current period: brutet räkenskapsår Jul 2025 - Jun 2026; window is the
// calendar Q1 2026, so the shifted window Jan-Mar 2025 spans FY 24/25
// only. Use a window that straddles instead: Jun-Jul 2026 shifted to
// Jun-Jul 2025, split across FY 24/25 (ends Jun 30) and FY 25/26.
q.enqueue({
data: { period_start: '2025-07-01', period_end: '2026-06-30', previous_period_id: 'period-0' },
error: null,
})
q.enqueue({
data: [
{ id: 'period-old', period_start: '2024-07-01', period_end: '2025-06-30' },
{ id: 'period-1', period_start: '2025-07-01', period_end: '2026-06-30' },
],
error: null,
})
mockTrialBalance
// Current window
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 50000 })])
)
// Prior part 1: 2025-06-01..2025-06-30 in period-old
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 10000 })])
)
// Prior part 2: 2025-07-01..2025-07-31 in period-1 (current period is a
// legitimate source when the shifted window reaches into it)
.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 15000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1', {
fromDate: '2026-06-01',
toDate: '2026-07-31',
})
expect(report.groups[0].rows[0].prior_period).toBe(25000)
expect(report.prior_period).toEqual({ start: '2025-06-01', end: '2025-07-31' })
expect(mockTrialBalance).toHaveBeenNthCalledWith(2, expect.anything(), 'company-1', 'period-old', {
closingEntry: 'exclude-all-year-end',
fromDate: '2025-06-01',
toDate: '2025-06-30',
})
expect(mockTrialBalance).toHaveBeenNthCalledWith(3, expect.anything(), 'company-1', 'period-1', {
closingEntry: 'exclude-all-year-end',
fromDate: '2025-07-01',
toDate: '2025-07-31',
})
})
it('drops the comparison when the shifted window would overlap the current one', async () => {
const q = createQueuedMockSupabase()
// 18-month fiscal period with a 14-month window: shifting back one year
// overlaps the window itself, so no comparison is possible.
q.enqueue({
data: { period_start: '2025-01-01', period_end: '2026-06-30', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 100000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1', {
fromDate: '2025-01-01',
toDate: '2026-02-28',
})
expect(report.prior_period).toBeNull()
expect(mockTrialBalance).toHaveBeenCalledTimes(1)
})
it('still drops the comparison for dimension-filtered ranges', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: 'period-0' },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(
tb([makeRow({ account_number: '3001', account_class: 3, closing_credit: 100000 })])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1', {
fromDate: '2026-01-01',
toDate: '2026-03-31',
dimensions: { '6': 'P001' },
})
expect(report.prior_period).toBeNull()
expect(mockTrialBalance).toHaveBeenCalledTimes(1)
})
it('reports window activity, not rolled-forward YTD closing', async () => {
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
q.enqueue({ data: [], error: null }) // no fiscal period covers the shifted window
// A June window: trial balance rolls Jan-May (60 000) into opening, so
// closing shows 100 000 YTD while the window's own activity is 40 000.
mockTrialBalance.mockResolvedValueOnce(
tb([
makeRow({
account_number: '3001',
account_class: 3,
opening_credit: 60000,
period_credit: 40000,
closing_credit: 100000,
}),
])
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1', {
fromDate: '2026-06-01',
toDate: '2026-06-30',
})
expect(report.groups[0].rows[0].current_period).toBe(40000)
expect(report.net_result_current).toBe(40000)
})
describe('latest_vouchers header line', () => {
function enqueuePeriod(q: ReturnType<typeof createQueuedMockSupabase>) {
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: null },
error: null,
})
mockTrialBalance.mockResolvedValueOnce(tb([]))
}
it('carries the last posted voucher per series', async () => {
const q = createQueuedMockSupabase()
enqueuePeriod(q)
mockLatestVouchers.mockResolvedValueOnce([
{ series: 'A', last_number: 214 },
{ series: 'B', last_number: 37 },
])
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.latest_vouchers).toEqual([
{ series: 'A', last_number: 214 },
{ series: 'B', last_number: 37 },
])
})
it('omits the field entirely when the period has no vouchers', async () => {
const q = createQueuedMockSupabase()
enqueuePeriod(q)
mockLatestVouchers.mockResolvedValueOnce([])
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect('latest_vouchers' in report).toBe(false)
})
it('still returns the report when the lookup fails', async () => {
const q = createQueuedMockSupabase()
enqueuePeriod(q)
mockLatestVouchers.mockRejectedValueOnce(new Error('boom'))
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
expect(report.latest_vouchers).toBeUndefined()
expect(report.net_result_current).toBe(0)
})
it('scopes the window to the reported date range', async () => {
const q = createQueuedMockSupabase()
enqueuePeriod(q)
await generateResultatrapport(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.supabase as any,
'company-1',
'period-1',
{ fromDate: '2026-01-01', toDate: '2026-03-31' }
)
expect(mockLatestVouchers).toHaveBeenCalledWith(
expect.anything(),
'company-1',
'period-1',
{ fromDate: '2026-01-01', toDate: '2026-03-31' }
)
})
it('skips the lookup entirely on a dimension-filtered report', async () => {
const q = createQueuedMockSupabase()
enqueuePeriod(q)
const report = await generateResultatrapport(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
q.supabase as any,
'company-1',
'period-1',
{ dimensions: { '6': 'P001' } }
)
// The report already discloses that it is partial; an unfiltered voucher
// range next to a filtered result would invite the wrong conclusion.
expect(mockLatestVouchers).not.toHaveBeenCalled()
expect(report.latest_vouchers).toBeUndefined()
})
})
})
describe('shiftDateOneYearBack', () => {
it('shifts a plain date one year back', () => {
expect(shiftDateOneYearBack('2026-03-15')).toBe('2025-03-15')
expect(shiftDateOneYearBack('2026-01-01')).toBe('2025-01-01')
expect(shiftDateOneYearBack('2026-12-31')).toBe('2025-12-31')
})
it('clamps leap day to the last day of February', () => {
expect(shiftDateOneYearBack('2028-02-29')).toBe('2027-02-28')
})
it('keeps Feb 29 when the target year is also a leap year divisible correctly', () => {
// 2001 -> 2000 is a leap year (divisible by 400)
expect(shiftDateOneYearBack('2001-02-28')).toBe('2000-02-28')
})
})
describe('closed fiscal year', () => {
it('excludes year-end closing entries on every trial-balance pass', async () => {
// Regression: the resultatavslut posts the mirror image of each P&L
// account into 2099 inside the same period, so without this exclusion the
// period movements this report sums cancel out and a closed year reads 0
// on every line. Reported against INK2R on the same ledger 2026-07-29.
const q = createQueuedMockSupabase()
q.enqueue({
data: { period_start: '2026-01-01', period_end: '2026-12-31', previous_period_id: 'period-0' },
})
q.enqueue({ data: { period_start: '2025-01-01', period_end: '2025-12-31' } })
mockTrialBalance.mockResolvedValue({
rows: [makeRow({ account_number: '3001', period_credit: 500000 })],
totalDebit: 0,
totalCredit: 0,
isBalanced: true,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const report = await generateResultatrapport(q.supabase as any, 'company-1', 'period-1')
// Both the current pass and the prior-year comparison pass must exclude:
// a prior year is almost always closed.
for (const call of mockTrialBalance.mock.calls) {
expect(call[3]).toMatchObject({ closingEntry: 'exclude-all-year-end' })
}
expect(report.groups[0].rows[0].current_period).toBe(500000)
})
})