---
title: "Periods & the close"
description: "The month-end close in accounting software: fiscal calendars, period states, cutoff, reconciliation vs tie-out, adjusting entries and restatement."
canonical: "https://lopifi.com/docs/domain/periods-and-close"
---

# Periods & the close

> The month-end close in accounting software: fiscal calendars, period states, cutoff, reconciliation vs tie-out, adjusting entries and restatement.

Source: https://lopifi.com/docs/domain/periods-and-close
Part of: Lopifi — Planned: US GAAP books on autopilot, checked by a CPA (https://lopifi.com)

---

# Periods & the close

<!-- description: The month-end close in accounting software: fiscal calendars, period states, cutoff, reconciliation vs tie-out, adjusting entries and restatement. -->

The month-end close is the central workflow of accounting software, and generic dashboard components can't express it. They have no notion that **a period has a state, and the state decides what the UI may offer.**

---

## 1. Fiscal calendars

```ts
type FiscalCalendar = {
  /** 1–12. A June year-end means fiscalYearStartMonth = 7. */
  fiscalYearStartMonth: number;
  /** How periods are cut. */
  type: "calendar" | "4-4-5" | "4-5-4" | "5-4-4" | "13-period";
  /** Which calendar year labels the FY. A FY starting Jul 2026 may be "FY26" or "FY27". */
  yearLabelConvention: "start" | "end";
  /** Some entities run a 53-week year periodically. */
  weekAlignedYearEnd?: boolean;
};
```

**Never assume January.** It's the most common fiscal bug in finance UI, and nothing flags it. A Q1 label that means Jan–Mar for an entity whose Q1 is Jul–Sep produces confident, wrong analysis.

**Retail calendars (4-4-5 and friends) are common.** They make every "month" a whole number of weeks so week-over-week comparison works. That means:
- A "month" is 28 or 35 days, not a calendar month.
- Period boundaries fall mid-calendar-month.
- Every 5–6 years there is a 53rd week, and the extra week distorts every year-over-year comparison in that year. **Flag it.** A component that shows `+8.4% YoY` in a 53-week year without a note is misleading.

**UI rules:**
- `PeriodPicker` renders the fiscal label **and** the resolved dates, always: `FY26 Q1 (Jul 1 – Sep 30, 2026)`.
- Never render a bare `Q1`, `Sep`, or `Last quarter`.
- Comparative columns state their own resolved period; the header never says "Prior".

---

## 2. Period states

A period is a date range with a state machine attached, and the state determines which actions exist.

```
┌──────────┐   ┌─────────────┐   ┌────────────┐   ┌────────┐   ┌───────┐
│  future  ├───┤    open     ├───┤ soft close ├───┤ closed ├───┤ filed │
└──────────┘   └─────────────┘   └────────────┘   └────────┘   └───────┘
                      ↑                                │
                      └────── reopen (approval) ───────┘
```

| State | Posting | Who can post | UI treatment |
|---|---|---|---|
| **future** | Blocked | — | Greyed in every picker; selecting it explains why |
| **open** | Free | Anyone with the role | Normal |
| **soft close** | Adjusting entries only | Controller and above | Amber banner; the entry form defaults to `adjusting` |
| **closed** | **Blocked** | Nobody without a reopen | Lock glyph; statements marked final |
| **filed** | **Blocked** | Nobody. Never reopened; corrections go through restatement, revision or a current-period adjustment. | Lock + "Filed" badge; restatement workflow only |

### The `PeriodStatus` banner
Every surface scoped to a period displays its state. It answers "why can't I post this?" before the user has to ask.

```
🔒  September 2026 · Closed Oct 4, 2026 by A. Rivera
    Entries dated in this period must be posted to October and will
    be flagged for cutoff review.                        [Request reopen]
```

The banner carries the state, who closed it and when, and **the next action**. A lock icon alone is a dead end.

### Reopening
- Requires an approval from a role that did not request it.
- Writes to the audit trail with a mandatory reason.
- **Invalidates every statement generated from that period.** Any export or saved report carrying that period is marked stale, because a PDF someone emailed to a lender is now wrong.
- The UI states the blast radius before confirming: "Reopening September will mark 4 published statements as superseded."

---

## 3. Cutoff

Cutoff is the boundary problem, where a transaction is dated in one period and entered in another. Get it wrong and revenue or expense lands in the wrong period, the most common unintentional misstatement there is.

**The `CutoffWarning` component fires when:**
- An entry's transaction date falls in a closed or soft-closed period.
- An entry's date is within N days of a period boundary (configurable, default 5) and the period is in close.
- A bank transaction settles in one period but was initiated in another.
- An invoice dated in the prior period arrives after close.

The warning sits **inline at the date field**, never in a toast, and states the consequence and both legitimate remedies instead of only blocking:

> This is dated Sep 29, which is in a closed period. It will post to October. If it belongs in September, request a reopen, or record it in October as an out-of-period adjustment.
---

## 4. The close pipeline

Lopifi models the close as seven gated sections, in the order controllers run them. The same structure drives `CloseChecklist`, `CloseStatus` and the dashboard.

| # | Section | Gate — what "done" means |
|---|---|---|
| 1 | **Cutoff & capture** | All source documents in; AP and AR cutoff tested |
| 2 | **Cash** | Every bank and card account reconciled; exceptions explained |
| 3 | **Subledgers** | AR and AP agree to the GL control accounts |
| 4 | **Schedules** | Prepaids, accruals, deferred revenue, fixed assets rolled forward and tied |
| 5 | **Adjusting entries** | Accruals, depreciation, amortization, provisions, reclasses posted |
| 6 | **Balance sheet tie-out** | Every BS account supported by a schedule or reconciliation |
| 7 | **Review & flux** | Material variances explained; statements reviewed and signed off |

**Rules:**
- **Sections gate in order.** You cannot tie out the balance sheet before the schedules are rolled. The UI shows downstream sections as blocked, with the blocker named.
- **Every check has an owner, a due date, and a state**: `not started` → `in progress` → `blocked` → `done` → `reviewed`.
- **A blocked item names its blocker and who owns it.** "Blocked: waiting on Sep bank statement — Treasury."
- **Sign-off is irreversible and audited.** It uses `HoldToConfirm` and writes who, when, and on what version of the numbers.
- **The close percentage is by weighted check, not by count.** Ten trivial checks and one bank rec is not 91% done.

---

## 5. Reconciliation vs tie-out

People mix these two controls up constantly. They answer different questions, and each has its own component.

| | **Bank reconciliation** | **Balance sheet tie-out** |
|---|---|---|
| Question | Does our cash record match the bank's? | Is this balance supported by evidence? |
| Compares | Book cash vs. bank statement | GL balance vs. a supporting schedule |
| Output | Reconciling items (timing differences) | A walk-down with a difference of zero or an explanation |
| Component | `ReconciliationView` | `AccountTieOut` |
| Applies to | Cash and card accounts | **Every balance sheet account** |

### The bank reconciliation summary
The component renders the standard form, line for line:

```
  Bank statement balance                    412,880.14
  Add: deposits in transit                    8,420.00
  Less: outstanding checks                  (22,140.55)
  Add/less: other reconciling items               0.00
                                           ────────────
  Adjusted bank balance                     399,159.59
  Book (GL) balance                         399,159.59
                                           ════════════
  Difference                                      0.00   ✓
```

**The difference line is the whole component.** It never scrolls out of view, because it's the number the user is working to zero. While it's non-zero, it's the primary state of the screen.

### The tie-out walk-down
```
  1310 · Prepaid expenses
  GL balance at Sep 30, 2026                  84,220.00
  Supporting schedule closing balance         84,220.00
                                           ────────────
  Difference                                       0.00   ✓  Tied
  Supported by: Prepaid schedule (14 items) · reviewed A. Rivera Oct 3
```

Every balance sheet account gets one. An account with no supporting evidence is a finding in itself, so `AccountTieOut` renders an explicit "Unsupported" state instead of an empty panel.

---

## 6. Reconciling items and exceptions

A reconciling item is a legitimate timing difference. An exception is a break someone has to work, and the UI keeps the two apart.

| Kind | Meaning | Aging behavior |
|---|---|---|
| **Deposit in transit** | Booked, not yet on the bank statement | Should clear next period; flag if > 5 days |
| **Outstanding check** | Issued, not yet cashed | Flag if > 90 days; stale-dated after six months (a bank may refuse it, UCC §4-404). Still a liability — void and reissue, or escheat under state unclaimed-property law after the dormancy period. Never write it back to income |
| **Bank-only item** | Fee, interest, NSF the bank booked and we didn't | **Requires a journal entry.** Should never age. |
| **Book-only item** | We booked something the bank has no record of | Investigate immediately |
| **Unmatched** | No counterpart found | The actual exception |

**Aging is the priority signal.** A 3-day-old outstanding check is normal; a 200-day-old one is a control finding. `ReconciliationView` sorts exceptions oldest first by default, ahead of amount, because old breaks are what auditors find.

---

## 7. Adjusting entries

These are the entries that make accrual accounting work. Each has its own shape, so `AdjustingEntryForm` offers them as templates instead of a blank journal entry.

| Type | Pattern | Auto-reverses? |
|---|---|---|
| **Accrual** | Dr Expense / Cr Accrued liability | **Yes** — day 1 of next period |
| **Deferral** | Dr Prepaid asset / Cr Expense | No — released by schedule |
| **Depreciation** | Dr Depreciation expense / Cr Accumulated depreciation | No |
| **Amortization** | Dr Amortization expense / Cr Accumulated amortization | No |
| **Revenue recognition** | Dr Deferred revenue / Cr Revenue | No — released by schedule |
| **Provision / allowance** | Dr Bad debt expense / Cr Allowance | No — trued up each period |
| **Reclassification** | Dr Account A / Cr Account B | Sometimes |
| **True-up** | Adjusts an estimate to actual | No |

**Accruals auto-reverse.** One that doesn't double-counts the expense when the invoice arrives and is coded to expense, and leaving it to the user's memory is how that happens. `AdjustingEntryForm` **defaults `autoReverse` to true for accruals** and shows the reversal date inline ("Reverses Oct 1, 2026"). The reversal is created at posting time as a scheduled entry, so a reviewer can see it in the next period before it posts.

---

## 8. Subsequent events

Events after the period end but before the statements are issued (or available to be issued, for an entity that is not an SEC filer). There are two types. ASC 855 calls them **recognized** and **nonrecognized** subsequent events; IAS 10 calls them **adjusting** and **non-adjusting**.

| | Type 1 — Adjusting | Type 2 — Non-adjusting |
|---|---|---|
| Condition | Existed at the balance sheet date | Arose after |
| Example | A customer whose finances were already deteriorating at Sep 30 files for bankruptcy in October; a lawsuit about a September incident settles | A fire destroys a warehouse in October; the company issues debt or equity, or acquires a business |
| Treatment | **Adjust the statements** (ASC 855-10-25-1) | **Disclose** the nature and an estimate of the effect, if material (ASC 855-10-25-3, -50-2) |

`SubsequentEventLog` captures these during the review window with the type, the date discovered and the treatment decision. Classify an event wrong and you get either a misstatement or a missing disclosure.

---

## 9. Restatement

This is what happens when a closed and filed period turns out to be materially wrong.

- A **restatement** ("Big R", ASC 250-10-45-23) is required when the error is material to the previously issued statements: they are reissued, the cumulative effect lands in opening retained earnings of the earliest period presented, and the error is disclosed.
- The prior period is **never edited in place**. A restatement entry is posted, and the comparative column is labeled **"Restated"** everywhere it appears, with no exceptions. A prior-year column that changed between two reports without a label destroys trust faster than the original error.
- `StatementTable` supports a `restated` flag per period column, rendering the label in the header and a footnote naming the reason.
- Errors immaterial to the prior period but material if corrected now revise the comparatives, labeled **"As revised"**. Errors immaterial either way are corrected in the current period as an out-of-period adjustment. Materiality is assessed under both the rollover and iron-curtain approaches (SEC SAB No. 108), quantitatively and qualitatively (SAB No. 99). The materiality policy decides which, and the decision is recorded.

---

## 10. Period-scoped UI rules

On top of the rules above (resolved dates on every label, state on every surface, superseded statements after a reopen), every component follows these:

1. **Every figure declares its period.**
2. **A closed period's numbers can't change**, so any affordance implying they can is removed outright.
3. **Comparatives share basis, framework, entity set and currency.** Mixing is blocked at the type level, before anything renders.
