/admin/accounting
Path: /admin/accounting
Namespace: admin
Resource: accounting
Overview
The Accounting section provides complete double-entry accounting functionality including chart of accounts, accounting equations (transactions), and accounting entries.
ERPax implements double-entry accounting where:
- Accounting Accounts - Chart of accounts (Assets, Liabilities, Equity, Revenue, Expenses)
- Accounting Equations - Double-entry transactions ensuring debits = credits
- Accounting Transactions - Individual transaction records for auditing
All accounting resources support standard REST operations (GET, POST, PATCH, DELETE).
Relationships
AccountingEquation Relationships
Model Associations
AccountingEquation connects to the following resources:
Invoice (Polymorphic)
- Type:
belongs_topolymorphic viaaccountable_typeandaccountable_id - Fields:
accountable_type,accountable_id - Description: Source document that triggered this accounting equation. Typically an Invoice, but can be other accountable resources.
- Reverse: Invoice has many accounting equations (
invoice.accounting_equations) - API Access:
- Direct:
accounting_equation.accountable_type,accounting_equation.accountable_id - Filter:
GET /admin/accounting_equations.json?q[accountable_type_eq]=Invoice&q[accountable_id_eq]=123 - Nested:
GET /admin/invoices/:id/accounting_equations.json(equations for an invoice)
- Direct:
- Related Documentation: Invoices
- Key Pattern: When an invoice is confirmed, accounting equations are automatically created with entries for seller, buyer, line items, and taxes.
- Example: Get accounting equations for an invoice:javascript
const equations = await fetch('/admin/invoices/123/accounting_equations.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Address
- Type:
belongs_toviaaddress_idandpartner_id(optional) - Fields:
address_id,partner_id - Description: Address perspective and partner address for accounting context. Used for customer/vendor-specific accounting treatment.
- Reverse: Address has many accounting equations (
address.accounting_equations) - API Access:
- Direct:
accounting_equation.address_id,accounting_equation.partner_id - Filter:
GET /admin/accounting_equations.json?q[address_id_eq]=123
- Direct:
- Related Documentation: Addresses
Domain
- Type:
belongs_toviahost_id - Field:
host_id - Description: Tenant domain for multi-tenant scoping. All accounting equations belong to a domain.
- Reverse: Domain has many accounting equations (
domain.accounting_equations) - API Access:
- Direct: Included in accounting equation response as
host_id - Filter:
GET /admin/accounting_equations.json?q[host_id_eq]=1
- Direct: Included in accounting equation response as
- Related Documentation: Domains
AccountingEntry[]
- Type:
has_manyviaaccounting_equation_id - Description: Individual account entries that make up this equation. Each equation has multiple entries (at least one debit and one credit).
- Reverse: AccountingEntry belongs to AccountingEquation (
entry.accounting_equation) - API Access:
- Direct: Included in accounting equation response as
entriesarray - Nested:
GET /admin/accounting_equations/:id/accounting_entries.json
- Direct: Included in accounting equation response as
- Example: Get all entries for an accounting equation:javascript
const entries = await fetch('/admin/accounting_equations/123/accounting_entries.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
AccountingEntry Relationships
Model Associations
AccountingEntry connects to the following resources:
AccountingEquation
- Type:
belongs_toviaaccounting_equation_id - Field:
accounting_equation_id - Description: Parent accounting equation. Each entry belongs to an equation that ensures debits equal credits.
- Reverse: AccountingEquation has many accounting entries (
equation.entries) - API Access:
- Direct: Included in accounting entry response as
accounting_equation_id - Filter:
GET /admin/accounting_entries.json?q[accounting_equation_id_eq]=123 - Nested:
GET /admin/accounting_equations/:id/accounting_entries.json
- Direct: Included in accounting entry response as
- Related Documentation: Accounting Equations
AccountingAccount
- Type:
belongs_toviaaccounting_account_id - Field:
accounting_account_id - Description: Account being debited or credited. Links the entry to the chart of accounts.
- Reverse: AccountingAccount has many accounting entries (
account.entries) - API Access:
- Direct: Included in accounting entry response as
accounting_account_id - Filter:
GET /admin/accounting_entries.json?q[accounting_account_id_eq]=10
- Direct: Included in accounting entry response as
- Related Documentation: Accounting Accounts
- Example: Get all entries for a specific account:javascript
const entries = await fetch('/admin/accounting_entries.json?q[accounting_account_id_eq]=10', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Domain
- Type:
belongs_toviahost_id - Field:
host_id - Description: Tenant domain for multi-tenant scoping. All accounting entries belong to a domain.
- Reverse: Domain has many accounting entries (via accounting equations)
- API Access:
- Direct: Included in accounting entry response as
host_id - Filter:
GET /admin/accounting_entries.json?q[host_id_eq]=1
- Direct: Included in accounting entry response as
- Related Documentation: Domains
AccountingAccount Relationships
Model Associations
AccountingAccount connects to the following resources:
Domain
- Type:
belongs_toviahost_id - Field:
host_id - Description: Tenant domain for multi-tenant scoping. Each domain has its own chart of accounts.
- Reverse: Domain has many accounting accounts (
domain.accounting_accounts) - API Access:
- Direct: Included in accounting account response as
host_id - Filter:
GET /admin/accounting_accounts.json?q[host_id_eq]=1
- Direct: Included in accounting account response as
- Related Documentation: Domains
AccountingEntry[]
- Type:
has_manyviaaccounting_account_id - Description: All accounting entries using this account. Track all debits and credits to the account.
- Reverse: AccountingEntry belongs to AccountingAccount (
entry.account) - API Access:
- Direct: Included in accounting account response as
entriesarray (if present) - Filter:
GET /admin/accounting_entries.json?q[accounting_account_id_eq]=10
- Direct: Included in accounting account response as
- Example: Get all entries for an account:javascript
const entries = await fetch('/admin/accounting_entries.json?q[accounting_account_id_eq]=10', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Reverse Associations
The following resources can have accounting accounts assigned:
Address[]
- Type:
has_manyon Address viacredit_account_idanddebit_account_id - Description: Addresses can have assigned credit and debit accounts for customer/vendor-specific accounting treatment.
- API Access:
- Filter:
GET /admin/addresses.json?q[credit_account_id_eq]=10 - Filter:
GET /admin/addresses.json?q[debit_account_id_eq]=10
- Filter:
- Related Documentation: Addresses
Invoice[]
- Type:
has_manyon Invoice viacredit_account_idanddebit_account_id - Description: Invoices can have assigned credit and debit accounts for automatic accounting.
- API Access:
- Filter:
GET /admin/invoices.json?q[credit_account_id_eq]=10
- Filter:
- Related Documentation: Invoices
Item[]
- Type:
has_manyon Item viacredit_account_id,debit_account_id,tax_credit_account_id,tax_debit_account_id - Description: Items can have assigned accounts for automatic accounting when used in invoice lines.
- API Access:
- Filter:
GET /admin/items.json?q[credit_account_id_eq]=10
- Filter:
- Related Documentation: Items
InvoiceLine[] (ItemTransfer)
- Type:
has_manyon InvoiceLine via same account fields as Item - Description: Invoice lines inherit account assignments from items or can have custom assignments.
- API Access:
- Filter:
GET /admin/item_transfers.json?q[credit_account_id_eq]=10
- Filter:
- Related Documentation: Item Transfers
Relationship Patterns
Automatic Accounting on Invoice Confirmation
- Use Case: When an invoice is confirmed, accounting equations are automatically created
- Example: Confirm an invoice to trigger automatic accounting:javascript
const invoice = await fetch('/admin/invoices/123/confirm', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }).then(r => r.json()); // Accounting equations and entries are automatically created
Accessing Accounting for Invoice
- Use Case: Get all accounting entries created from an invoice
- Example:javascript
// Get accounting equations for invoice const equations = await fetch('/admin/invoices/123/accounting_equations.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json()); // Get all entries from all equations const allEntries = []; for (const equation of equations.accounting_equations) { const entries = await fetch(`/admin/accounting_equations/${equation.id}/accounting_entries.json`, { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json()); allEntries.push(...entries.accounting_entries); }
Account Balance Calculation
- Use Case: Calculate account balance by summing debit and credit entries
- Example:javascript
// Get all entries for an account const entries = await fetch('/admin/accounting_entries.json?q[accounting_account_id_eq]=10', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json()); // Calculate balance const balance = entries.accounting_entries.reduce((sum, entry) => { return sum + (entry.debit_amount_cents || 0) - (entry.credit_amount_cents || 0); }, 0);
Key Features
- Double-Entry Accounting: Automatic balance checking (debits = credits)
- Automatic Integration: Accounting entries created automatically when invoices are confirmed
- Chart of Accounts: Hierarchical account structure with standard numbering
- Transaction Tracking: Complete audit trail of all accounting transactions
Accounting Accounts
Path: /admin/accounting_accounts
Overview
The AccountingAccount resource represents the chart of accounts for double-entry accounting. Accounts are organized hierarchically using codes and support different account types.
Account Structure
- Hierarchical Codes: Accounts use hierarchical codes (e.g., "1000/100/10") separated by
/ - Account Types:
- Balance accounts (Assets, Liabilities, Equity) - permanent accounts
- Statement accounts (Revenue, Expenses) - temporary accounts, reset each period
- Account Codes: Unique per host (multi-tenant)
Standard Account Numbering
- 1000s - Assets: Current assets, cash, accounts receivable, inventory
- 2000s - Liabilities: Current liabilities, accounts payable, accrued expenses
- 3000s - Equity: Capital, retained earnings
- 4000s - Revenue: Sales revenue, service revenue
- 5000s - Expenses: Cost of goods sold, operating expenses
Available Operations
List Accounts (GET)
Endpoint: GET /admin/accounting_accounts.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/accounting_accounts.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/accounting_accounts.json?q[code_cont]=1000" \
-H "Accept: application/json"curl -X GET "https://your-company.erpax.com/admin/accounting_accounts.json?scope=root" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/accounting_accounts.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"accounting_accounts": [
{
"id": 1,
"code": "4000",
"name": "Sales Revenue",
"description": "Revenue from sales",
"account_type": 2,
"created_at": "2024-01-10T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 50
}
}Create Account (POST)
Endpoint: POST /admin/accounting_accounts.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/accounting_accounts.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"accounting_account": {
"code": "4000",
"name": "Sales Revenue",
"description": "Revenue from sales",
"account_type": 2
}
}'Response (201 Created):
{
"accounting_account": {
"id": 1,
"code": "4000",
"name": "Sales Revenue",
"account_type": 2,
"created_at": "2024-01-15T14:30:00Z"
}
}Scopes
- all (default) - All accounts
- root - Root accounts (top-level accounts)
- analytic - Analytic accounts (sub-accounts)
Filters
- code_cont - Search by account code
- name_cont - Search by account name
- description_cont - Search by description
- account_type - Filter by account type (balance, statement)
Accounting Equations
Path: /admin/accounting_equations
Overview
The AccountingEquation resource represents double-entry accounting transactions. Each equation ensures that debits equal credits, maintaining the fundamental accounting equation: Assets = Liabilities + Equity.
Key Features
- Double-Entry Validation: Automatic balance checking (debits = credits)
- Invoice Integration: Accounting equations can be associated with invoices
- Address Association: Equations can be linked to addresses (seller/buyer)
- Entry Tracking: Each equation contains multiple AccountingEntry records (debits and credits)
Accounting Equation Structure
Each AccountingEquation contains:
- Multiple AccountingEntry records (debits and credits)
- Association with Invoice (if created from invoice)
- Association with Address (seller/buyer)
- Automatic validation that debits = credits
Available Operations
List Equations (GET)
Endpoint: GET /admin/accounting_equations.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/accounting_equations.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/accounting_equations.json?q[invoice_id_eq]=123" \
-H "Accept: application/json"curl -X GET "https://your-company.erpax.com/admin/accounting_equations.json?scope=balanced" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/accounting_equations.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"accounting_equations": [
{
"id": 1,
"number": "EQ-2024-001",
"date": "2024-01-15",
"description": "Invoice payment",
"invoice_id": 123,
"currency_code": "USD",
"created_at": "2024-01-15T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 10
}
}Create Equation (POST)
Endpoint: POST /admin/accounting_equations.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/accounting_equations.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"accounting_equation": {
"date": "2024-01-15",
"description": "Invoice payment",
"invoice_id": 123,
"currency_code": "USD"
}
}'Note: Accounting equations are typically created automatically when invoices are accounted via invoice.account!.
Response (201 Created):
{
"accounting_equation": {
"id": 1,
"date": "2024-01-15",
"description": "Invoice payment",
"invoice_id": 123,
"currency_code": "USD",
"created_at": "2024-01-15T14:30:00Z"
}
}Scopes
- all (default) - All accounting equations
- balanced - Equations where debits equal credits
- unbalanced - Equations where debits do not equal credits (should be none in production)
Filters
- number_cont - Search by equation number
- description_cont - Search by description
- invoice - Filter by associated invoice
- address - Filter by associated address
- date - Filter by equation date
- currency_code - Filter by currency code
Nested Resources
- Accounting Entries -
/admin/accounting_equations/:id/accounting_entries- Individual debit and credit entries
Accounting Transactions
Path: /admin/accounting_transactions
Overview
The AccountingTransaction resource provides transaction-level access to accounting entries for auditing and reporting purposes.
Available Operations
List Transactions (GET)
Endpoint: GET /admin/accounting_transactions.json
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/accounting_transactions.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/accounting_transactions.json?q[date_gteq]=2024-01-01" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/accounting_transactions.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"accounting_transactions": [
{
"id": 1,
"date": "2024-01-15",
"accounting_account_id": 10,
"debit_cents": 100000,
"credit_cents": 0,
"created_at": "2024-01-15T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 20
}
}Show Accounting Transaction (GET /:id)
Endpoint: GET /admin/accounting_transactions/:id.json
Request Example:
curl -X GET "https://your-company.erpax.com/admin/accounting_transactions/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/accounting_transactions/1.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"accounting_transaction": {
"id": 1,
"date": "2024-01-15",
"accounting_account_id": 10,
"accounting_equation_id": 5,
"debit_cents": 100000,
"credit_cents": 0,
"description": "Invoice payment entry",
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
}Create Accounting Transaction (POST)
Endpoint: POST /admin/accounting_transactions.json
Note: Accounting transactions are typically created automatically as part of accounting equations when invoices are confirmed and accounted. Manual creation is usually not necessary and may require special permissions.
Request Example:
curl -X POST "https://your-company.erpax.com/admin/accounting_transactions.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"accounting_transaction": {
"date": "2024-01-16",
"accounting_account_id": 10,
"accounting_equation_id": 5,
"debit_cents": 50000,
"credit_cents": 0,
"description": "Manual adjustment entry"
}
}'JavaScript Example:
const response = await fetch('/admin/accounting_transactions.json', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
accounting_transaction: {
date: '2024-01-16',
accounting_account_id: 10,
accounting_equation_id: 5,
debit_cents: 50000,
credit_cents: 0,
description: 'Manual adjustment entry'
}
})
});
const data = await response.json();Response (201 Created):
{
"accounting_transaction": {
"id": 2,
"date": "2024-01-16",
"accounting_account_id": 10,
"accounting_equation_id": 5,
"debit_cents": 50000,
"credit_cents": 0,
"description": "Manual adjustment entry",
"created_at": "2024-01-16T10:00:00Z"
}
}Update Accounting Transaction (PATCH /:id)
Endpoint: PATCH /admin/accounting_transactions/:id.json
Note: Accounting transactions are typically read-only once created to maintain audit integrity. Updates may be restricted or require special permissions.
Request Example:
curl -X PATCH "https://your-company.erpax.com/admin/accounting_transactions/1.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"accounting_transaction": {
"description": "Updated description"
}
}'JavaScript Example:
const response = await fetch('/admin/accounting_transactions/1.json', {
method: 'PATCH',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
accounting_transaction: {
description: 'Updated description'
}
})
});
const data = await response.json();Response (200 OK):
{
"accounting_transaction": {
"id": 1,
"description": "Updated description",
"updated_at": "2024-01-15T15:00:00Z"
}
}Delete Accounting Transaction (DELETE /:id)
Endpoint: DELETE /admin/accounting_transactions/:id.json
Note: Accounting transactions are typically not deletable to maintain audit integrity. Deletion may be restricted or require special permissions. Consider using reversal transactions instead.
Request Example:
curl -X DELETE "https://your-company.erpax.com/admin/accounting_transactions/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/accounting_transactions/1.json', {
method: 'DELETE',
credentials: 'include',
headers: { 'Accept': 'application/json' }
});Response (204 No Content):
(empty response)Business Rules
Double-Entry Accounting
All accounting resources work together to implement double-entry bookkeeping:
- Each transaction (AccountingEquation) must have equal debits and credits
- Debits increase assets and expenses
- Credits increase liabilities, equity, and revenue
- System automatically validates balance before saving
- Accounts track balances and are used in financial reporting
Automatic Accounting
- Invoice Confirmation: When an invoice is confirmed, accounting equations are automatically created
- Entry Generation: Entries are automatically generated for seller, buyer, line items, and taxes
- Balance Validation: System automatically validates that debits equal credits