DoubleEntryLedger.Stores.InstanceStore (double_entry_ledger v0.1.0)
View SourceProvides functions for managing ledger instances in the double-entry ledger system.
This module serves as the primary interface for all ledger instance operations, including creating, retrieving, updating, and deleting instances. It also provides specialized queries to verify ledger integrity through balance verification across currencies.
Key Functionality
- Instance Management: Create, retrieve, update, and delete ledger instances
- Instance Queries: Find and list instances by various criteria
- Balance Verification: Calculate and verify that total debits equal total credits by currency
- Transaction Safety: Ensures critical operations use appropriate database isolation levels
Usage Examples
Creating a new ledger instance:
{:ok, instance} = DoubleEntryLedger.Stores.InstanceStore.create(%{
address: "Business Ledger",
metadata: %{owner: "ACME Corp"}
})Retrieving and updating an instance:
instance = DoubleEntryLedger.Stores.InstanceStore.get_by_id(instance_id)
{:ok, updated_instance} = DoubleEntryLedger.Stores.InstanceStore.update(
instance.id,
%{address: "Updated:Ledger:address"}
)Verifying ledger balance integrity:
{:ok, currency_balances} = InstanceStore.sum_accounts_debits_and_credits_by_currency(instance.id)
# Check that for each currency, debits = creditsImplementation Notes
All functions perform appropriate validation and return standardized results:
- Success:
{:ok, result} - Error:
{:error, reason}
Balance verification queries run in transactions with REPEATABLE READ isolation to ensure consistency when concurrent operations are taking place.
Summary
Functions
Creates a new ledger instance with the given attributes.
Deletes a ledger instance by its ID.
Retrieves a ledger instance by its ID.
Calculates the sum of debits and credits for all accounts in a ledger instance, grouped by currency.
Updates a ledger instance with the given attributes.
Functions
@spec create(map()) :: {:ok, DoubleEntryLedger.Instance.t()} | {:error, Ecto.Changeset.t()}
Creates a new ledger instance with the given attributes.
Parameters
attrs(map): A map of attributes for the ledger instance.
Returns
{:ok, instance}: On success.{:error, changeset}: If there was an error during creation.
Examples
iex> attrs = %{address: "Test:Ledger"}
iex> {:ok, instance} = InstanceStore.create(attrs)
iex> instance.address
"Test:Ledger"
@spec delete(Ecto.UUID.t()) :: {:ok, DoubleEntryLedger.Instance.t()} | {:error, Ecto.Changeset.t()}
Deletes a ledger instance by its ID.
Ensures that there are no associated transactions or accounts before deletion, as defined in Instance.delete_changeset/1.
Parameters
id(Ecto.UUID.t()): The ID of the ledger instance to delete.
Returns
{:ok, instance}: On success.{:error, changeset}: If there was an error during deletion.
Examples
iex> {:ok, instance} = InstanceStore.create(%{address: "Temporary:Ledger"})
iex> {:ok, _} = InstanceStore.delete(instance.id)
iex> InstanceStore.get_by_id(instance.id) == nil
true
@spec get_by_address(String.t()) :: DoubleEntryLedger.Instance.t() | nil
@spec get_by_id(Ecto.UUID.t()) :: DoubleEntryLedger.Instance.t() | nil
Retrieves a ledger instance by its ID.
Parameters
id(Ecto.UUID.t()): The ID of the ledger instance.
Returns
instance: The ledger instance struct, ornilif not found.
Examples
iex> {:ok, instance} = InstanceStore.create(%{address: "Sample:Ledger"})
iex> retrieved = InstanceStore.get_by_id(instance.id)
iex> retrieved.id == instance.id
true
@spec sum_accounts_debits_and_credits_by_currency(Ecto.UUID.t()) :: {:ok, [map()]} | {:error, Ecto.Changeset.t()}
Calculates the sum of debits and credits for all accounts in a ledger instance, grouped by currency.
This function runs a database query in a transaction with REPEATABLE READ isolation level to ensure consistent results even if accounts are being updated concurrently.
Parameters
instance_id(Ecto.UUID.t()): The ID of the ledger instance.
Returns
{:ok, list(map)}: On success, returns a list of maps containing currency, posted_debit, posted_credit, pending_debit, and pending_credit sums.{:error, reason}: If there was an error during the transaction.
@spec update(Ecto.UUID.t(), map()) :: {:ok, DoubleEntryLedger.Instance.t()} | {:error, Ecto.Changeset.t()}
Updates a ledger instance with the given attributes.
Parameters
id(Ecto.UUID.t()): The ID of the ledger instance to update.attrs(map): The attributes to update.
Returns
{:ok, instance}: On success.{:error, changeset}: If there was an error during update.
Examples
iex> {:ok, instance} = InstanceStore.create(%{address: "Ledger"})
iex> {:ok, updated_instance} = InstanceStore.update(instance.id, %{address: "Updated:Ledger"})
iex> updated_instance.address
"Updated:Ledger"