Investment Accounting Bridge
Accounting policies, draft journal entries from the ledger, and reconciling the ledger with the general ledger.
Module: technovision_investment_accounting (Odoo 19). Depends on technovision_investment_core and account; independent of the statement importer.
Not a compliance claim. The policy options and entry templates below are configurable starting points for your accountant. Nothing in this module states that the result complies with Egyptian Accounting Standards, IFRS, Egyptian tax law, or any other rule set. Your accountant chooses and approves the treatment.
1. How it works
confirmed ledger events ─► proposals (one per event / version / action)
│ idempotent: re-running reuses them
▼
draft account.move (button "Create draft entries")
│
▼
an accountant posts it in Accounting (Odoo's Post button)- Draft-only. The bridge never posts. Posting goes through Odoo, which applies its own lock dates, sequence rules and access rights.
- Rights. Only Investment Accountants (or administrators) generate proposals and create draft entries — and they also need Odoo accounting rights to create journal entries. A Portfolio Operator can do neither and cannot post. Odoo accounting rights alone give no access to the investment ledger, and portfolio restrictions apply to proposals as to everything else.
- No SQL on accounting tables. Entries are created and reversed through the ORM (account.move.create, account.move._reverse_moves).
- Traceability. Each entry's Reference is the proposal name (action + event number); its Narration names the event and portfolio; the entry is linked to the event (invest_event_id) and to its proposals. Reference and narration survive even if the bridge is uninstalled.
2. The policy
One policy per company, optionally overridden per portfolio. A policy must be approved by an investment accountant before anything is proposed; any change to an approved policy withdraws the approval (recorded in the audit trail).
| Setting | Options | Effect |
|---|---|---|
| Classification | Cost · FVTPL · FVOCI | Cost: no valuation entries. FVTPL: valuation adjustments through P&L, cleared on disposal. FVOCI is selectable but blocked: its recycling rules depend on instrument and jurisdiction and are not implemented. |
| Capitalize purchase fees | yes / no | Accounting-only. Independent of the management policy's "purchase fees in cost". |
| Sale fees | reduce proceeds / expense separately | How sale charges enter the realized result. |
| Dividend recognition | on entitlement / on receipt | Entitlement: receivable on the entitlement date, cleared on payment. |
| Opening balances | already in the general ledger / propose opening entries | Default already in ledger: opening positions and cash post nothing, so assets already in Accounting are not doubled. |
Accounts: investment asset, broker cash/clearing (a broker account may override it), purchase payable, sale receivable, realized gain, realized loss, dividend income, dividend receivable, fees, withholding tax, valuation adjustment (balance sheet), unrealized gain, unrealized loss, FX/conversion difference, funding/bank clearing, opening equity/suspense, rounding.
3. Entries per event (Dr + / Cr −)
cash is the broker account's cash account. "Same-day" means the settlement date equals the trade date, in which case no payable/receivable is used.
| Event | Proposal (date) | Lines |
|---|---|---|
| Buy | purchase (trade date) | Dr asset (gross + charges if capitalized), Dr fees (charges if not), Cr payable (net) |
| purchase settlement (settlement date) | Dr payable, Cr cash (net) | |
| Sell | disposal (trade date) | Dr receivable (net), Dr fees (charges, if expensed), Cr asset (allocated cost), Cr valuation adj. (cleared share, FVTPL), Cr gain / Dr loss (result) |
| disposal settlement (settlement date) | Dr cash, Cr receivable (net) | |
| Deposit | deposit (settlement date) | Dr cash, Cr funding clearing |
| Withdrawal | withdrawal | Dr funding clearing, Cr cash |
| Fee | fee | Dr fees, Cr cash |
| Dividend (entitlement) | dividend (entitlement date) | Dr dividend receivable (net), Dr withholding (taxes), Dr fees, Cr dividend income (gross) |
| dividend receipt (payment date) | Dr cash, Cr dividend receivable | |
| Dividend (receipt) | dividend (payment date) | Dr cash (net), Dr withholding, Dr fees, Cr income (gross) |
| Opening position / cash | opening | nothing (default) or Dr asset / cash, Cr opening account |
| Cash transfer | on the outgoing leg | nothing if both legs use the same cash account; else Dr destination cash, Cr source cash |
| Security transfer | on the outgoing leg | nothing if both portfolios carry it on the same accounts; else moves cost (and FVTPL adjustment) between accounts. No gain is realized. |
| Valuation (FVTPL) | valuation (valuation date) | only the change: Dr valuation adj. / Cr unrealized gain, or Dr unrealized loss / Cr valuation adj. |
| Reversed event | reversal | reverses the posted entry (Odoo reversal, linked); a not-yet-posted proposal is cancelled instead |
Cost allocation on disposal uses the core engine (moving weighted average, proportional allocation, full exit takes the whole cost) run under the accounting fee setting — so management and accounting cost can differ, and both are labelled.
Worked example (cost, fees capitalized)
Deposit 10,000 · Buy 100 @ 20 fee 10 · Buy 50 @ 22 fee 5 · Sell 60 @ 25 fee 6.
| Proposal | Dr | Cr |
|---|---|---|
| deposit | cash 10,000 | funding 10,000 |
| purchase 1 | asset 2,010 | payable 2,010 |
| purchase 2 | asset 1,105 | payable 1,105 |
| disposal | receivable 1,494 | asset 1,246 · gain 248 |
| settlements | payable / receivable against cash |
With fees expensed: purchase 1 is asset 2,000 + fees 10; the disposal allocates 3,100 × 60 / 150 = 1,240 and the gain is 254. Management figures (248) are unchanged — the two policies are independent.
Worked example (FVTPL — no double count)
Buy 100 @ 20 (cost 2,000). Valuation at 25: Dr valuation adj. 500 / Cr unrealized gain 500. Sell 100 @ 25 (proceeds 2,500): Cr asset 2,000, Cr valuation adj. 500, no realized gain — the 500 was already in P&L. A partial sale clears the same proportion of the accumulated adjustment.
4. Valuation runs (FVTPL)
- Delta against the accumulated adjustment (earlier valuations minus what disposals cleared) — never the full fair value again.
- Re-running the same date reuses that date's proposal (refreshed while it is not posted). Valuations go forward only: once a later date exists, an earlier one is refused.
- An instrument with no price on or before the date is excluded and listed in the batch's Excluded from valuation note — never valued at zero. An instrument in a currency with no Odoo rate is excluded the same way.
5. Currency
Amounts are computed in Decimal in the event currency and rounded to it; lines carry amount_currency and currency_id. The company-currency balance uses Odoo's own rates (res.currency._convert) at the entry date. Management valuation uses the product's dated FX observations; the two can differ. A foreign-currency entry with no Odoo rate on or before its date is blocked (a rate of 1 is never assumed). A conversion residual goes to the FX account; a rounding residual to the rounding account, so every entry balances per company.
6. Lock dates and corrections
- The proposal keeps the event's economic date (effective date). If that date is in a locked period, the entry date is Odoo's own accounting date for a locked period (account.move._get_accounting_date, always after the lock), and the shift is recorded on the proposal.
- A posted entry is never regenerated. If the ledger changes afterwards (a backdated event, a policy change), re-generation flags a difference on the proposal and the accounting reconciliation reports it; the accountant corrects with a reversal.
- A reversed event: its posted entries are reversed (linked to the original, dated per the lock rules); unposted proposals are cancelled.
7. Accounting reconciliation
Reconciliation run kind Accounting (ledger vs journal) reports:
- missing — a confirmed event without the proposal it needs;
- timing — proposals not yet posted (or blocked, with the reason);
- amount — a posted entry that no longer matches the ledger;
- general-ledger balances — per account and currency, posted entries only: broker cash vs the ledger's settled cash, investment cost vs accounting cost of holdings, valuation adjustment vs the accumulated adjustment (all portfolios of the company using the account). If proposals are still unposted the difference is classed timing, otherwise amount.
Discrepancies link to the event, the proposal and the journal entry.
8. Uninstalling
Posted journal entries belong to Accounting and are never deleted by uninstalling the bridge. What is lost is the link from each entry back to its ledger event (reference and narration still name it). The uninstall is therefore refused while posted linked entries exist, unless the system parameter technovision_investment_accounting.allow_uninstall is set to 1.
9. Known limits (release one)
- FVOCI is not implemented (blocked).
- Transfers between companies are refused by the core (no intercompany accounting).
- A security transfer between two portfolios of one company carries the source's accounting cost; within a single portfolio (between broker accounts) the management transfer cost is used, which differs only if the accounting fee setting differs from the management one.
- Corporate actions, impairment models, tax computations and automatic posting are not included.