Year-End Closing
The annual close most Community accounting modules skip, computed, reviewed, posted, and reversible.
Why this module
Year-End Closing
Compute, then look before you post
The run computes a per-account profit-and-loss breakdown read from posted journal entries, so the operator reviews every income and expense balance before a single line posts. Compute is idempotent: re-running unlinks and rebuilds the breakdown without duplicating.
Balanced by construction, every case
One closing entry zeroes all income and expense accounts against retained earnings and balances by construction. Net profit credits retained earnings, net loss debits it, and a net-zero year emits no retained-earnings line yet still balances because income equals expense exactly.
Manager-gated, fully stamped
Post and reverse are restricted to the EH Accounting Manager group. Computed, posted, and reversed each record the user and timestamp, tracked on chatter, with one run per company per fiscal year enforced at the database level.
Day in the life
A controller closes the books on a December fiscal year.
The controller picks 31 December as the fiscal year end; the form derives the start as the prior 1 January automatically, with a leap-day fallback so 29 February year-ends never raise. Compute reads the posted entries and builds one breakdown line per income and expense account, sub-cent rounding residue dropped, all in a single batched insert even on a full chart of accounts. After reviewing the numbers, the manager posts: income accounts are zeroed against expense accounts, the net result lands in retained earnings, and the entry balances to the cent. The optional lock-date advance bumps the standard fiscal-year lock so nothing can be backdated into the closed year. A week later an adjustment is found; the manager reverses, the symmetric inverse posts dated 1 January, both entries stay linked on the run, and a fresh run re-closes the corrected year.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A year where income exactly equals expense produces no retained-earnings line at all, and the close still balances because the income debits and expense credits cancel. The code handles net == 0 explicitly rather than emitting a phantom zero line.
A loss is handled symmetrically to a profit: retained earnings is debited rather than credited. The test suite asserts the loss path, so the close is correct whichever way the year went.
Re-running compute unlinks the existing breakdown and rebuilds it, so a second compute never duplicates lines. The line count is unchanged after a repeat run.
The optional lock-date advance refuses to move the fiscal-year lock backwards. If a later lock already exists, it is preserved, so the close cannot loosen an existing lock.
Account balances with an absolute value at or below 0.005 are dropped, so rounding residue never adds noise lines to the closing entry.
Deriving the fiscal-year start from a 29 February year-end falls back gracefully instead of raising, so calendar arithmetic on leap years does not break the form.
All breakdown lines are written in a single batched create, an N+1 guard that keeps compute fast on a full chart of accounts.
What is inside
Built to do the job, end to end.
- Computed profit-and-loss breakdown. Net profit is computed from posted journal entries in the fiscal year, with one reviewable breakdown row per income and expense account showing its closing balance. Income is sign-flipped to the positive debit side and expense kept on the credit side, with the totals shown before posting.
- One balanced closing entry. A single account.move zeroes every income and expense account against the configured retained earnings account, with one or two retained-earnings lines signed for profit or loss. The entry balances by construction and the test suite asserts the invariant.
- Next-day reversal with linkage. Reverse posts the symmetric inverse entry dated the day after fiscal year end and flips the run to a terminal Reversed state, preserving both the original closing entry and its reversal by record linkage. To re-close, create a fresh run for the year.
- Optional fiscal-year lock. After posting, the run can advance the standard Odoo fiscal-year lock date so backdated entries cannot post against the closed year. The advance is idempotent and never moves the lock backwards.
- Manager gating and audit trail. Post and reverse require the EH Accounting Manager group. Computed, posted, and reversed timestamps and users are stored and tracked on the mail.thread chatter, with one run per company per fiscal year enforced by a database constraint.
Honest about the edges
What this does not do, so nothing surprises you.
- Bypassing the fiscal-year lock relies on Odoo's native lock-date permission; this module adds no separate override flow or override audit of its own.
- A reversed run is terminal. Recompute and re-post of the same reversed run is not wired; to re-close after a reversal, create a fresh run for the year.
- There is no separate reopen action. Reverse is the only way to undo a posted close, and it preserves both entries by linkage.
- The closing entry balances by construction; the module does not validate against an external trial balance and has no partially-locked-year check.
- Closing is manual and button-driven (Compute, Post, Reverse, Cancel). There is no scheduled cron that runs the close on a configured date.
odoo 19 year end closing, odoo community fiscal year close, closing entry retained earnings odoo, year end closing wizard, zero income expense accounts odoo, net profit to retained earnings, fiscal year lock date odoo, period close accounting odoo, reverse closing entry odoo, multi company year end close
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Please log in to comment on this module
There are no ratings yet!
There are no comments yet!