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:

  1. Close all periods of the old year (except special periods)
  2. 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
  3. Open new year’s number ranges (see Number Ranges)
  4. Copy/roll forward budgets, plans, and effective-dated config
  5. Asset fiscal year change — depreciation areas roll over
  6. 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

Next