backbone-accounting 0.18.2

GL, journals, ledger, reconciliation (extracted from bersihir)
Documentation
# =============================================================================
# Domain: Accounting
# Entity: FiscalPeriod
# Description: Fiscal periods for accounting
# =============================================================================

# =============================================================================
# Enums
# =============================================================================

enums:
  # ---------------------------------------------------------------------------
  # Period Type
  # ---------------------------------------------------------------------------
  - name: PeriodType
    description: "Type of fiscal period"
    variants:
      - name: monthly
        description: "Monthly period"
        default: true
      - name: quarterly
        description: "Quarterly period"
      - name: yearly
        description: "Yearly period"
      - name: custom
        description: "Custom period"

  # ---------------------------------------------------------------------------
  # Period Status
  # ---------------------------------------------------------------------------
  - name: PeriodStatus
    description: "Fiscal period status"
    variants:
      - name: open
        description: "Open for transactions"
        default: true
      - name: closing
        description: "Closing in progress"
      - name: closed
        description: "Closed - no new transactions"
      - name: locked
        description: "Locked - no changes allowed"
      - name: adjusting
        description: "Allowing adjustments only"

# =============================================================================
# Models
# =============================================================================

models:
  # ---------------------------------------------------------------------------
  # FiscalPeriod - Accounting period (monthly/quarterly/yearly)
  # ---------------------------------------------------------------------------
  # Tenancy: none, by design (ADR-0029). Tenant-agnostic and reusable; a composing
  # service's tenancy decorator owns org scoping for this table, including the
  # org-scoped per-unit period-code and fiscal-year/month uniques.
  - name: FiscalPeriod
    collection: fiscal_periods
    description: "Fiscal/Accounting period for financial reporting"

    fields:
      id:
        type: uuid
        attributes: ["@id", "@default(uuid)"]
        description: "Unique period identifier"

      # =======================================================================
      # Period Identification
      # =======================================================================
      period_code:
        type: string
        attributes: ["@required", "@max(20)"]
        description: "Period code (e.g., 2024-01, 2024-Q1, 2024)"

      name:
        type: string
        attributes: ["@required", "@max(50)"]
        description: "Period name (e.g., January 2024)"

      period_type:
        type: PeriodType
        attributes: ["@default(monthly)"]
        description: "Type of period"

      # =======================================================================
      # Date Range
      # =======================================================================
      start_date:
        type: date
        attributes: ["@required"]
        description: "Period start date"

      end_date:
        type: date
        attributes: ["@required"]
        description: "Period end date"

      # =======================================================================
      # Calendar Reference
      # =======================================================================
      fiscal_year:
        type: int
        attributes: ["@required", "@min(2020)", "@max(2100)"]
        description: "Fiscal year"

      fiscal_quarter:
        type: int?
        attributes: ["@min(1)", "@max(4)"]
        description: "Quarter number (1-4)"

      fiscal_month:
        type: int?
        attributes: ["@min(1)", "@max(12)"]
        description: "Month number (1-12)"

      # =======================================================================
      # Hierarchy
      # =======================================================================
      parent_id:
        type: uuid?
        attributes: ["@foreign_key(FiscalPeriod.id)"]
        description: "Parent period (e.g., year for month)"

      level:
        type: int
        attributes: ["@default(0)", "@non_negative"]
        description: "Hierarchy level (0=year, 1=quarter, 2=month)"

      # =======================================================================
      # Status
      # =======================================================================
      status:
        type: PeriodStatus
        attributes: ["@default(open)"]
        lifecycle:
          shape: hand_set
        description: "Period status (hand_set, ADR-0016): open -> closing -> closed -> locked, or closed -> open by a reopen; moved only by the close, lock and reopen verbs, never by a generic write. A locked period is final"

      is_current:
        type: bool
        attributes: ["@default(false)"]
        description: "Current active period"

      # =======================================================================
      # Opening Balance
      # =======================================================================
      opening_balance_set:
        type: bool
        attributes: ["@default(false)"]
        description: "Opening balances have been set"

      opening_balance_date:
        type: datetime?
        description: "When opening balances were set"

      opening_balance_by:
        type: uuid?
        description: "Who set opening balances"

      # =======================================================================
      # Closing Process
      # =======================================================================
      closing_started_at:
        type: datetime?
        lifecycle:
          shape: hand_set
        description: "Closing process started; written only by the close, lock and reopen verbs"

      closing_started_by:
        type: uuid?
        lifecycle:
          shape: hand_set
        description: "Who started closing; written only by the close, lock and reopen verbs"

      closed_at:
        type: datetime?
        lifecycle:
          shape: hand_set
        description: "Period closed timestamp; written only by the close, lock and reopen verbs"

      closed_by:
        type: uuid?
        lifecycle:
          shape: hand_set
        description: "Who closed the period; written only by the close, lock and reopen verbs"

      # =======================================================================
      # Lock
      # =======================================================================
      locked_at:
        type: datetime?
        lifecycle:
          shape: hand_set
        description: "Period locked timestamp; written only by the close, lock and reopen verbs"

      locked_by:
        type: uuid?
        lifecycle:
          shape: hand_set
        description: "Who locked the period; written only by the close, lock and reopen verbs"

      lock_reason:
        type: string?
        attributes: ["@max(255)"]
        lifecycle:
          shape: hand_set
        description: "Reason for locking; written only by the close, lock and reopen verbs"

      # =======================================================================
      # Reopen
      # =======================================================================
      reopened_at:
        type: datetime?
        lifecycle:
          shape: hand_set
        description: "When the period was last reopened; written only by the close, lock and reopen verbs"

      reopened_by:
        type: uuid?
        lifecycle:
          shape: hand_set
        description: "Who last reopened the period; written only by the close, lock and reopen verbs"

      reopen_reason:
        type: string?
        attributes: ["@max(255)"]
        lifecycle:
          shape: hand_set
        description: "Why the period was last reopened; written only by the close, lock and reopen verbs"

      # =======================================================================
      # Adjustments
      # =======================================================================
      allow_adjustments:
        type: bool
        attributes: ["@default(false)"]
        description: "Allow adjusting entries after close"

      adjustment_deadline:
        type: date?
        description: "Deadline for adjustments"

      # =======================================================================
      # Summary Balances and Financial Summary
      # =======================================================================
      # Nothing computes these: the period's totals live in its financial statements. They are
      # projections no generic write may set, so they stay at zero until they are dropped at the
      # next breaking release.
      total_debits:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)", "@non_negative"]
        lifecycle:
          shape: projection
        description: "Total debits in period"

      total_credits:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)", "@non_negative"]
        lifecycle:
          shape: projection
        description: "Total credits in period"

      journal_count:
        type: int
        attributes: ["@default(0)", "@non_negative"]
        lifecycle:
          shape: projection
        description: "Number of journal entries"

      total_revenue:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Total revenue for period"

      total_expenses:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Total expenses for period"

      net_income:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Net income (revenue - expenses)"

      total_assets:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Total assets at period end"

      total_liabilities:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Total liabilities at period end"

      total_equity:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)"]
        lifecycle:
          shape: projection
        description: "Total equity at period end"

      # =======================================================================
      # Statements
      # =======================================================================
      balance_sheet_generated:
        type: bool
        attributes: ["@default(false)"]
        description: "Balance sheet generated"

      income_statement_generated:
        type: bool
        attributes: ["@default(false)"]
        description: "Income statement generated"

      statements_generated_at:
        type: datetime?
        description: "When statements were generated"

      notes:
        type: string?
        attributes: ["@max(1000)"]
        description: "Period notes"

      metadata:
        type: Metadata
        attributes: ["@audit_metadata"]
        description: "Audit metadata (created_at, updated_at, deleted_at, created_by, updated_by, deleted_by)"

    relations:
      parent:
        type: FiscalPeriod?
        attributes: ["@one", "@foreign_key(parent_id)"]
        description: "Parent period"
        inverse: children

      children:
        type: FiscalPeriod[]
        attributes: ["@one_to_many"]
        description: "Child periods"

      journals:
        type: Journal[]
        attributes: ["@one_to_many"]
        description: "Journal entries in this period"
        inverse: fiscal_period

      statements:
        type: FinancialStatement[]
        attributes: ["@one_to_many"]
        description: "Financial statements"
        inverse: fiscal_period

      opening_balance_user:
        type: sapiens.User?
        attributes: ["@one", "@foreign_key(opening_balance_by)"]
        description: "Opening balance user"

      closed_by_user:
        type: sapiens.User?
        attributes: ["@one", "@foreign_key(closed_by)"]
        description: "Closed by user"

      locked_by_user:
        type: sapiens.User?
        attributes: ["@one", "@foreign_key(locked_by)"]
        description: "Locked by user"

    indexes:
      # No tenancy indexes (ADR-0029): the module is tenant-agnostic. The per-unit
      # period-code and fiscal-year/month uniques — one open calendar per org unit —
      # are installed by the composing service's tenancy decorator
      # (org_unit_id-leading), not declared here.
      - type: index
        fields: [parent_id]