Class: WhittakerTech::Midas::Ledger::Account

Inherits:
ApplicationRecord
  • Object
show all
Includes:
Poly::Joins
Defined in:
app/models/whittaker_tech/midas/ledger/account.rb

Overview

Ledger::Account is a chart-of-accounts entry for Midas's double-entry ledger. An Account is either a system account (no owner — e.g. a per-currency suspense or platform-revenue account) or an owned account (belongs polymorphically to some domain resource, e.g. a Customer or Organization).

Accounts are additive to Coin/Bankable, not a replacement — most Midas consumers should keep using has_coin/has_coins for simple stored values. Ledger::Account exists for models that need a full double-entry audit trail.

Since:

  • 0.4.0

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.suspense_for(currency_code) ⇒ Account

Finds or creates the singleton suspense account for a given currency.

Wrapped in a bounded retry: concurrent callers (e.g. two webhooks racing to post the first out-of-order event in a currency) can both miss the find_by and attempt to create — the partial unique index on (slug, currency_code) WHERE owner_id IS NULL makes the loser's insert raise RecordNotUnique rather than silently duplicating, and the retry then finds the winner's row.

Parameters:

  • currency_code (String)

    ISO 4217 currency code

Returns:

  • (Account)

Since:

  • 0.4.0



63
64
65
66
67
68
69
70
71
72
73
# File 'app/models/whittaker_tech/midas/ledger/account.rb', line 63

def suspense_for(currency_code)
  iso = currency_code.to_s.strip.upcase
  attempts = 0
  begin
    find_or_create_by!(kind: :suspense, slug: 'suspense', currency_code: iso)
  rescue ActiveRecord::RecordNotUnique
    attempts += 1
    retry if attempts <= 1
    raise
  end
end

Instance Method Details

#balanceInteger

Raw debit-normal balance: sum(debits) - sum(credits), reading the denormalized currency_minor column on Posting directly (not joining Coin) so this stays cheap even before Phase 2 partitioning. Only counts postings on finalized entries — Entry.create! (bypassing record!) is a live, if unsanctioned, path to an unfinalized entry with postings attached, and those must never contribute to a real balance.

This is intentionally kind-agnostic. Presenting a liability/equity/ revenue account's balance as conventionally credit-positive is a display concern layered on top of this raw number, not baked in here.

Returns:

  • (Integer)

Since:

  • 0.4.0



88
89
90
91
92
# File 'app/models/whittaker_tech/midas/ledger/account.rb', line 88

def balance
  entry_class = WhittakerTech::Midas::Ledger::Entry
  finalized = postings.joins(:entry).merge(entry_class.where.not(finalized_at: nil))
  finalized.debit.sum(:currency_minor) - finalized.credit.sum(:currency_minor)
end