At a Glance
Owner: Sysadmin / Finance Manager · Table:tb_period(+tb_period_snapshot) · Used by: GRN, IA, count, spot-check, costing engine · The accounting calendar — gates back-dating and drives costing close.

Periods define the accounting calendar Carmen operates on — one row per fiscal month, identified by YYMM plus fiscal_year / fiscal_month integers and a [start_at, end_at) range. Every period has a status (open, closed, locked) gating which dated documents can post. Periods are the unit at which inventory cost is closed and snapshotted: when finance closes January, no further January GRNs / issues / adjustments may post, and the closing balance becomes February's opening balance.
tb_period_snapshot stores the per-location / per-product / per-lot inventory snapshot at a point in time — generated by the costing engine and used for trial balances, GL postings, and roll-forward.
Maintained by Sysadmin (typically Finance Manager). Read by every posting guard and the costing engine.
| Task | Where | Notes |
|---|---|---|
| Open next period | System Config → Period → New / Open | Auto-generated via roll-forward; status open |
| Close current period | Period row → Close | No new postings; corrections still allowed by Finance |
| Lock a period | Period row → Lock | Terminal under normal operation; unlock requires DB override + audit |
| Reopen a closed period | Period row → Reopen | Requires audit reason; writes tb_period_comment |
| View snapshot | Period detail → Snapshot tab | Read-only per-location balance grid |
| Generate close snapshot | Costing engine job | Writes tb_period_snapshot for every (location, product, lot) |
| Symptom | Cause | Action |
|---|---|---|
| "Period is closed" | Posting date inside a closed/locked period | Use current open period; or raise JV |
| "Period date overlap" | Two periods share dates | Fix range — periods must be contiguous, non-overlapping |
period mismatch with fiscal date |
period != fiscal_year-2000 * 100 + fiscal_month |
Recompute and fix one value |
| Roll-forward discrepancy | Closing N ≠ Opening N+1 | Surfaces in diff_amount; review snapshot |
| Cannot delete period | Snapshots, cost layers, or postings reference | Archive only; soft-delete breaks GL chain |
open → closed, closed → open (reopen), closed → locked. locked is terminal under normal operation.snapshot_at is the recommended audit-preserving pattern.diff_amount.Source: tenant schema.
tb_period| Field | Prisma Type | Nullable | Description |
|---|---|---|---|
id |
String @db.Uuid |
No | Primary key. |
period |
String @db.VarChar |
No | YYMM (e.g. 2601). |
fiscal_year / fiscal_month |
Int @db.Integer |
No | YYYY + 1-12. |
start_at / end_at |
DateTime @db.Timestamptz(6) |
No | Inclusive / exclusive. |
status |
enum_period_status |
No | open (default), closed, locked. |
note / info / dimension |
— | Mixed | Standard metadata. |
| Audit columns | — | Yes | created_*, updated_*, deleted_*. |
Constraints: @@unique([period, deleted_at]) + @@unique([fiscal_year, fiscal_month, deleted_at]). Indexes on [fiscal_year, fiscal_month] and [period]. Reverse relations to tb_period_snapshot, tb_inventory_transaction_cost_layer, tb_period_comment, tb_physical_count_period. enum_period_status: open, closed, locked.
tb_period_snapshot| Field | Prisma Type | Nullable | Description |
|---|---|---|---|
id / period_id |
String @db.Uuid |
No | Keys. |
snapshot_at |
DateTime @db.Timestamptz(6) |
No | Exact snapshot instant (typically close datetime). |
location_id / product_id |
String @db.Uuid |
No | Position keys. |
location_code / location_name / product_code / product_name / product_local_name / product_sku |
String? |
Yes | Denormalised display. |
lot_no / lot_index / lot_at_date / lot_seq_no |
— | Yes | Optional lot identification. |
opening_qty / opening_cost_per_unit / opening_total_cost |
Decimal? @db.Decimal(20,5) |
Yes | Carried from prior period. |
receipt_qty / receipt_total_cost |
Decimal? |
Yes | In-period GRN. |
issue_qty / issue_total_cost |
Decimal? |
Yes | In-period SR. |
adjustment_qty / adjustment_total_cost |
Decimal? |
Yes | In-period IA / count / spot-check. |
closing_qty / closing_cost_per_unit / closing_total_cost |
Decimal? |
Yes | Position at snapshot_at. |
diff_amount |
Decimal? |
Yes | Rounding / true-up residual. |
note / info / dimension |
— | Mixed | Standard metadata. |
| Audit columns | — | Yes | created_*, updated_*, deleted_*. |
Constraints: @@unique([period_id, snapshot_at, deleted_at]). Index on [period_id, snapshot_at]. FK onDelete: NoAction.
period and (fiscal_year, fiscal_month) unique among non-deleted; should agree (period == fiscal_year-2000 * 100 + fiscal_month for 2000-2099).start_at < end_at; periods contiguous, non-overlapping.open → closed, closed → open, closed → locked. locked terminal under normal operation.open period.(period_id, snapshot_at) per (location, product, optional lot); append-at-new-snapshot_at preserves audit.tb_physical_count_period.../carmen-turborepo-backend-v2/packages/prisma-shared-schema-tenant/prisma/schema.prisma — tb_period (lines ~1172-1203), tb_period_snapshot (lines ~1239-1292), enum_period_status (lines ~1166-1170).../carmen-turborepo-frontend/apps/web/app/(app)/configuration/period/.