Fiscal Periods, Calendars, and Period Control
Time in an ERP is not a timestamp. It’s a set of overlapping calendars, and every one of them changes system behaviour.
The calendars
| Calendar | Controls |
|---|---|
| Fiscal year variant | Which posting periods exist and how dates map to them |
| Factory calendar | Which days are working days at a plant — drives lead times and scheduling |
| Shift calendar | Available capacity per work centre per day |
| Payroll period | Pay cycles |
| Tax period | VAT/GST return periods (may differ from fiscal periods) |
| Depreciation calendar | Asset depreciation periods |
| Public holidays | Per country/region, feeds the factory calendar |
Fiscal year variants
The fiscal year is not always Jan–Dec:
| Company/Country | Fiscal year |
|---|---|
| Most of Europe, US corporates | Jan 1 – Dec 31 |
| UK companies (often) | Apr 1 – Mar 31 |
| India | Apr 1 – Mar 31 (mandatory) |
| Bangladesh (government/most companies) | Jul 1 – Jun 30 |
| Australia, NZ | Jul 1 – Jun 30 |
| Japan (many) | Apr 1 – Mar 31 |
| US retail (NRF 4-5-4) | 52/53 weeks, ends late Jan/early Feb |
A group with entities in several countries runs multiple fiscal year variants simultaneously and must reconcile them for consolidation.
Period structures
- 12 calendar months — the default
- 4-4-5 / 4-5-4 / 5-4-4 — 13-week quarters made of 4+4+5 week months. Retail favourite: every “month” has the same number of weekends, so like-for-like sales compare cleanly. Every 5–6 years there’s a 53-week year.
- 13 periods of 4 weeks — some manufacturers
- Year-dependent variants — for 52/53-week calendars where period end dates shift annually
Special periods
Beyond the 12 normal periods, most ERPs support special periods (13, 14, 15, 16) that all map to the last day of the fiscal year. Used for audit adjustments after the year is technically closed, so that December’s operational numbers aren’t disturbed by the auditor’s entries.
Period 12 = December operations
Period 13 = audit adjustments
Period 14 = tax adjustments
Period 15 = consolidation adjustments
Period 16 = reserved
Posting date vs document date vs entry date
Three distinct dates, and finance needs all three:
| Date | Meaning | Determines |
|---|---|---|
| Document date | Date on the physical/original document (the supplier’s invoice date) | Payment terms baseline, tax point |
| Posting date | Which accounting period this hits | Period, exchange rate, reporting |
| Entry date (created_at) | When it was typed into the system | Audit trail only |
You can, on 5 February, enter an invoice dated 28 January with a posting date of 31 January, provided period 1 is still open. All three dates are different and all three are correct.
Rule: never conflate them. Storing only created_at and calling it the posting date is a mistake that makes correct period reporting impossible.
Period control (open/close)
Periods are opened and closed to control who can post where.
period_status(
company_id, fiscal_year, period,
account_type, -- '+' all, 'S' GL, 'D' customers, 'K' vendors, 'A' assets, 'M' materials
status, -- OPEN | CLOSED
authorised_group -- only this group may post while "restricted"
)
The typical month-end sequence:
Day 1–3 All sub-ledgers open for previous period (late invoices, accruals)
Day 3 Close MM (material/inventory) period — no more backdated stock postings
Day 4 Close AP and AR
Day 5 GL only, restricted to the closing team
Day 6 Close previous period entirely; only special periods remain
Two periods are typically open at once (current and previous) during the first days of the month, then it narrows.
Developers hit this constantly: a batch job that posts with a hardcoded date fails after period close. Always handle “period closed” as an expected error path, not an exception, and make the posting date a parameter.
Material period vs financial period
Inventory has its own period control, and it’s usually closed first and harder than the financial period, because reopening it would change inventory valuation retroactively. Some ERPs only allow posting into the current and immediately previous material period, ever.
Factory calendar
Defines working days per plant:
factory_calendar(
calendar_id, country, region,
workdays: Mon..Fri (or Sun..Thu in the Gulf/Bangladesh)
holidays: list of dates
valid_from, valid_to
)
Drives:
- Lead time calculation — “5 working days” ≠ 5 calendar days
- Scheduling — production and delivery dates land on working days
- MRP — planned order dates
- Availability check — promised dates
Common bug source: a global system defaulting to a Mon–Fri week for a Bangladesh or Saudi plant where the week runs Sunday–Thursday. Every promised date is then wrong by up to two days.
Calendars must be maintained years ahead. A calendar that runs out causes scheduling to fail silently or throw. Put a monitoring check on “calendar valid_to minus today < 12 months”.
Year-end
The year-end process, in order:
- Close all periods of the old year (except special periods)
- Balance carryforward — balance-sheet account balances carry to the new year’s opening; P&L accounts are closed to retained earnings and start at zero
- Open new year’s number ranges (see Number Ranges)
- Copy/roll forward budgets, plans, and effective-dated config
- Asset fiscal year change — depreciation areas roll over
- Auditor’s adjustments land in special periods and re-run the carryforward
Balance carryforward is usually re-runnable and idempotent — if late adjustments post to the old year, you re-run it and the opening balances update. Verify this is true in your product before promising it.
Exchange rates and periods
Period-end FX activities:
- Translation rate for the period (average, closing, historical) — see Currencies
- FX revaluation of open foreign-currency items at the closing rate
- Rate tables must be loaded before close; a missing rate blocks the whole close
Practical checklist for developers
- Never hardcode a posting date; take it as input and default to today
- Always derive the period from posting date + fiscal year variant, never from
MONTH(date) - Handle “period closed” as a business error with a clear message, not a 500
- Batch jobs that post must be safely re-runnable after a period reopen
- Lead time and date calculations use the factory calendar, never
date + N days - Monitor: calendars defined ≥12 months ahead; number ranges created for next year; period status matches the close schedule
- Test your code at a period boundary and at a fiscal year boundary — most bugs live there