Finance technical architecture
Comprehensive technical architecture, data models, entity relationships, transaction state machines, security access groups, and automated crons.
This document provides the definitive technical and architectural reference for SmartERP 19 Financial Operations.

Entity Relationship Schema & Core Models#
SmartERP Financial Operations integrates core general ledger models with localized Ethiopian compliance modules:
+----------------------------------------------------------------------------------------------------+
| SMARTERP FINANCE ENTITY RELATIONSHIP MAP |
+----------------------------------------------------------------------------------------------------+
| |
| +-----------------------------+ +------------------------------+ |
| | account.move |1 * | account.move.line | |
| |-----------------------------|----------------->|------------------------------| |
| | id | | id | |
| | name (Sequential Number) | | move_id (FK account.move) | |
| | move_type (invoice/entry) | | account_id (FK acc.account) | |
| | date (Gregorian ISO) | | debit (Monetary) | |
| | state (draft/posted/cancel) | | credit (Monetary) | |
| | approval_state | | partner_id (FK res.partner) | |
| | payment_delivery_type | | currency_id | |
| | cpv_sequence_number | | amount_currency | |
| | wht_applicable | +------------------------------+ |
| | wht_tax_id | | |
| +-----------------------------+ | |
| | 1 v * |
| | +------------------------------+ |
| | | account.account | |
| | |------------------------------| |
| | | id | |
| | | code (e.g. 111200, 211000) | |
| v 0..1 | name | |
| +-----------------------------+ | account_type | |
| | account.payment | +------------------------------+ |
| |-----------------------------| |
| | id | +------------------------------+ |
| | payment_type (in/out) | | petty.cash.fund | |
| | amount | |------------------------------| |
| | payment_delivery_type | | id | |
| | cpv_state | | name | |
| | wht_tax_id | | custodian_id (FK res.users) | |
| | wht_amount | | float_amount | |
| | wht_taxable_base | | current_balance | |
| +-----------------------------+ | state (draft/active/closed) | |
| +------------------------------+ |
| | 1 |
| | |
| v * |
| +------------------------------+ |
| | petty.cash.voucher | |
| |------------------------------| |
| | id | |
| | name (PCV-YYYY-XXXXX) | |
| | fund_id | |
| | paid_to_id (FK res.partner) | |
| | amount | |
| | prepared_by_id | |
| | checked_by_id | |
| | approved_by_id | |
| | state (draft/check/app/paid) | |
| | move_id (FK account.move) | |
| +------------------------------+ |
+----------------------------------------------------------------------------------------------------+
Model Data Dictionary#
| Model Identifier | Database Table | Primary Keys & Foreign Keys | Description & Business Rules |
|---|---|---|---|
account.move | account_move | PK id, FK company_id, FK partner_id, FK journal_id | Header for all financial documents (vendor bills, invoices, vouchers). |
account.move.line | account_move_line | PK id, FK move_id, FK account_id, FK partner_id | Double-entry debit and credit lines. Sum(Debit) = Sum(Credit). |
account.payment | account_payment | PK id, FK journal_id, FK partner_id, FK wht_tax_id | Payment execution records generating BPV, CRV, and CPV vouchers. |
account.payment.register | Transient Model | In-memory wizard | Hooks into write-off lines to dynamically inject withholding tax debits/credits. |
wht.declaration.export.wizard | Transient Model | In-memory wizard | Generates official pixel-accurate ERCA Excel declarations. |
petty.cash.fund | petty_cash_fund | PK id, FK custodian_id, FK journal_id, FK company_id | Imprest fund master managing float capital and custodian liability. |
petty.cash.voucher | petty_cash_voucher | PK id, FK fund_id, FK paid_to_id, FK move_id | Petty cash disbursement slips enforcing maker-checker segregation. |
smart.et.calendar | Python Engine | Standalone algorithm | Astronomical JDN engine converting Ethiopian and Gregorian dates. |
peachtree.bank.statement | peachtree_bank_statement | PK id, FK account_id, FK company_id | Peachtree/Sage style statement reconciliation matching GL cash lines. |
accounting.dashboard | accounting_dashboard | Singleton PK id | Singleton engine computing ~95 financial intelligence KPIs across 9 groups. |
Transaction Lifecycle State Machine#
1. Vendor Bill Approval State Transitions#
[draft] ---> action_confirm_bill() ---> [confirmed]
|
v
action_check()
|
v
[checked]
|
v
action_approve() <--- Gated by smarterp.approval.request
|
v
[approved]
|
v
action_post() <--- Intercepted by _post()
|
v
[posted]
2. Petty Cash Voucher State Transitions#
[draft] ---> action_check() -------------------> [checked] (Constraint: checked_by != prepared_by)
|
v
action_approve() <--- Gated by 'PCV' approval
|
v
[approved]
|
v
action_post() <--- Creates & posts account.move
|
v
[paid] (Immutable: Cannot be deleted)
Security Architecture and Segregation of Duties (SoD)#
SmartERP enforces strict role-based access control (RBAC) and Segregation of Duties (SoD) across financial operations:
+----------------------------------------------------------------------------------------------------+
| FINANCIAL SECURITY ACCESS GROUP HIERARCHY |
+----------------------------------------------------------------------------------------------------+
| |
| Auditor / Read-Only (`account.group_account_readonly`) |
| βββ Full read access to Trial Balance, General Ledger, Vouchers, and Tax Reports |
| |
| Billing Clerk & Cashier (`account.group_account_invoice`) |
| βββ Create customer invoices, register payments (CRV), create draft petty cash vouchers (PCPS) |
| βββ CANNOT validate journal entries, open fiscal periods, or modify tax settings |
| |
| Senior Accountant (`account.group_account_user`) |
| βββ Validate vendor bills, reconcile bank statements, execute BPV/CPV, prepare tax returns |
| βββ CANNOT close fiscal years, override lock dates, or bypass DoA approval gates |
| |
| Financial Controller / CFO (`account.group_account_manager`) |
| βββ Full administrative authority: open/close fiscal years, set lock dates, configure COA/Taxes |
| βββ Authorize Tier 3/4 expenditures and approve budget override exceptions |
+----------------------------------------------------------------------------------------------------+
Enforced Toxic SoD Pairs#
- Cashier vs. Approver: A user with Cashier permissions (
group_account_invoice) cannot approve disbursements or petty cash vouchers. - Maker vs. Checker: The user who compiles a petty cash voucher or CPV is strictly blocked by code constraints from checking or approving it (
prepared_by != checked_by). - Master Data Creator vs. Disburser: A user who creates or edits vendor bank details cannot approve payments to that vendor.
- Bank Reconciler vs. Cash Disburser: The user who executes cash disbursements cannot independently mark bank reconciliation statements as
done.
Automated Crons and Scheduled Actions#
SmartERP operates background scheduled actions to guarantee ledger integrity:
| Cron Job Name | Technical Interval | Model Triggered | Operational Purpose |
|---|---|---|---|
| Bank Feed Sync | Hourly | account.journal._cron_sync_bank_feeds | Ingests electronic statement lines from connected bank APIs. |
| SLA Escalation Watcher | Every 15 Minutes | smarterp.approval.request._cron_check_sla | Evaluates working-hour timers and escalates overdue approvals. |
| Fiscal Period Lock Validator | Daily at Midnight | account.fiscal.year._cron_enforce_locks | Enforces period_lock_date across all active companies. |
| Holiday Engine Sync | Annually | smart.et.holiday._cron_generate_annual_holidays | Computes Bahire Hasab and Islamic lunar holidays for the fiscal year. |
| Tax Filing Reminder | Monthly on the 20th | wht.declaration.export.wizard._cron_tax_alert | Notifies finance team of upcoming MOR declaration filing deadlines. |
Developer Extension API and Hooks#
Developers extending SmartERP Financial Operations should adhere to these established extension patterns:
1. Extending the Payment Register with Custom Withholding Lines#
class CustomPaymentRegister(models.TransientModel):
_inherit = 'account.payment.register'
def _create_payment_vals_from_wizard(self, batch_result):
payment_vals = super()._create_payment_vals_from_wizard(batch_result)
# Custom withholding logic must inject write_off_line_vals:
# Positive balance = Debit (Asset for Inbound)
# Negative balance = Credit (Liability for Outbound)
return payment_vals
2. Safely Gating Document Posting#
class CustomFinancialMove(models.Model):
_inherit = 'account.move'
def _post(self, soft=True):
# Always gate inside _post(), NOT action_post(), to intercept API calls
for move in self:
if move.custom_control_condition:
move._check_custom_financial_compliance()
return super()._post(soft=soft)
Last updated: 2026-10-16