AccountRepository

Trait AccountRepository 

Source
pub trait AccountRepository: Send + Sync {
    // Required methods
    fn create<'life0, 'life1, 'async_trait>(
        &'life0 self,
        account: &'life1 Account,
    ) -> Pin<Box<dyn Future<Output = Result<Account, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn find_by_id<'life0, 'async_trait>(
        &'life0 self,
        id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn find_by_code<'life0, 'life1, 'async_trait>(
        &'life0 self,
        code: &'life1 str,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn find_by_organization<'life0, 'async_trait>(
        &'life0 self,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn find_by_type<'life0, 'async_trait>(
        &'life0 self,
        account_type: AccountType,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn find_by_parent_code<'life0, 'life1, 'async_trait>(
        &'life0 self,
        parent_code: &'life1 str,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn find_direct_use_accounts<'life0, 'async_trait>(
        &'life0 self,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn search_by_code_pattern<'life0, 'life1, 'async_trait>(
        &'life0 self,
        code_pattern: &'life1 str,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn update<'life0, 'life1, 'async_trait>(
        &'life0 self,
        account: &'life1 Account,
    ) -> Pin<Box<dyn Future<Output = Result<Account, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn delete<'life0, 'async_trait>(
        &'life0 self,
        id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn exists<'life0, 'life1, 'async_trait>(
        &'life0 self,
        code: &'life1 str,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<bool, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn count_by_organization<'life0, 'async_trait>(
        &'life0 self,
        organization_id: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<i64, String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

Repository trait for managing accounts in the Belgian accounting plan

This port defines the contract for account persistence operations. Implementations must handle:

  • Multi-tenancy (organization_id filtering)
  • Hierarchical account relationships (parent_code)
  • Account code uniqueness within organization

Inspired by Noalyss Acc_Plan_SQL and Tmp_Pcmn_SQL classes See: include/database/acc_plan_sql.class.php in Noalyss repository

Required Methods§

Source

fn create<'life0, 'life1, 'async_trait>( &'life0 self, account: &'life1 Account, ) -> Pin<Box<dyn Future<Output = Result<Account, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Create a new account in the chart of accounts

§Arguments
  • account - Account to create
§Returns
  • Ok(Account) - Created account with database-generated ID
  • Err(String) - Error message if creation fails
§Errors
  • Duplicate account code within organization
  • Parent account code does not exist
  • Database constraint violation
Source

fn find_by_id<'life0, 'async_trait>( &'life0 self, id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Option<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Find account by ID

§Arguments
  • id - Account ID
§Returns
  • Ok(Some(Account)) - Account found
  • Ok(None) - Account not found
  • Err(String) - Database error
Source

fn find_by_code<'life0, 'life1, 'async_trait>( &'life0 self, code: &'life1 str, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Option<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Find account by code within an organization

§Arguments
  • code - Account code (e.g., “700”, “604001”)
  • organization_id - Organization ID
§Returns
  • Ok(Some(Account)) - Account found
  • Ok(None) - Account not found
  • Err(String) - Database error
Source

fn find_by_organization<'life0, 'async_trait>( &'life0 self, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Find all accounts for an organization

§Arguments
  • organization_id - Organization ID
§Returns
  • Ok(Vec<Account>) - All accounts for the organization (can be empty)
  • Err(String) - Database error

Note: Results are ordered by code ASC for hierarchical display

Source

fn find_by_type<'life0, 'async_trait>( &'life0 self, account_type: AccountType, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Find accounts by type within an organization

§Arguments
  • account_type - Account type (Asset, Liability, Expense, Revenue, OffBalance)
  • organization_id - Organization ID
§Returns
  • Ok(Vec<Account>) - Matching accounts (can be empty)
  • Err(String) - Database error

Useful for generating financial reports:

  • Balance sheet: Asset + Liability accounts
  • Income statement: Expense + Revenue accounts
Source

fn find_by_parent_code<'life0, 'life1, 'async_trait>( &'life0 self, parent_code: &'life1 str, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Find child accounts of a parent account

§Arguments
  • parent_code - Parent account code (e.g., “60” to find “600”, “604”, etc.)
  • organization_id - Organization ID
§Returns
  • Ok(Vec<Account>) - Direct children of the parent account (can be empty)
  • Err(String) - Database error

Note: Returns only direct children, not all descendants

Source

fn find_direct_use_accounts<'life0, 'async_trait>( &'life0 self, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Find accounts that can be used directly in transactions

§Arguments
  • organization_id - Organization ID
§Returns
  • Ok(Vec<Account>) - Accounts with direct_use = true (can be empty)
  • Err(String) - Database error

Summary accounts (direct_use = false) cannot be used in journal entries

Source

fn search_by_code_pattern<'life0, 'life1, 'async_trait>( &'life0 self, code_pattern: &'life1 str, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<Vec<Account>, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Search accounts by code pattern

§Arguments
  • code_pattern - SQL LIKE pattern (e.g., “60%”, “604%”)
  • organization_id - Organization ID
§Returns
  • Ok(Vec<Account>) - Matching accounts (can be empty)
  • Err(String) - Database error

Useful for finding all accounts in a class or sub-class:

  • “6%” - All expenses (class 6)
  • “60%” - All class 60 expenses
  • “604%” - All accounts under 604
Source

fn update<'life0, 'life1, 'async_trait>( &'life0 self, account: &'life1 Account, ) -> Pin<Box<dyn Future<Output = Result<Account, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Update an existing account

§Arguments
  • account - Account with updated fields
§Returns
  • Ok(Account) - Updated account
  • Err(String) - Error message if update fails
§Errors
  • Account not found
  • Code change would create duplicate
  • Parent code does not exist
  • Database constraint violation
Source

fn delete<'life0, 'async_trait>( &'life0 self, id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete an account

§Arguments
  • id - Account ID
§Returns
  • Ok(()) - Account deleted successfully
  • Err(String) - Error message if deletion fails
§Errors
  • Account not found
  • Account has child accounts (cannot delete parent)
  • Account is used in expenses/transactions (referential integrity)

Inspired by Noalyss Acc_Plan_SQL::delete() validation logic

Source

fn exists<'life0, 'life1, 'async_trait>( &'life0 self, code: &'life1 str, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<bool, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Check if an account code exists within an organization

§Arguments
  • code - Account code
  • organization_id - Organization ID
§Returns
  • Ok(true) - Account exists
  • Ok(false) - Account does not exist
  • Err(String) - Database error
Source

fn count_by_organization<'life0, 'async_trait>( &'life0 self, organization_id: Uuid, ) -> Pin<Box<dyn Future<Output = Result<i64, String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Count accounts in an organization

§Arguments
  • organization_id - Organization ID
§Returns
  • Ok(i64) - Number of accounts
  • Err(String) - Database error

Implementors§