Case study · Anonymized · Credit operations

Put the loan book on Odoo only after the ledger can hold it

Connect the credit engine on day one and every test disbursement becomes a journal nobody asked for. The pipeline is not the ledger. On an East African agricultural lender, we kept them apart until the chart could carry principal, interest, and penalties.

In plain terms: build the chart of accounts, the tax setup, and the three loan accounts before any disbursement is allowed to post. Use CRM for the application. Use helpdesk for disputes. Use the phone system so a collections call opens the borrower and writes an internal note, not an accidental email.

Why the loan engine stays off

The lender already had a system that calculated principal, interest, and penalties. Odoo was being introduced as the ledger, the pipeline, and the place agents work. Switching both on together means the first sandbox loan creates entries in a chart that still uses default names and the wrong account types. Unpicking that is harder than waiting.

Phase one is accounting setup only. No live disbursement crosses from the credit engine. The chief accountant can still see what the books will look like, because the accounts exist and the types are right.

The code is not what Odoo obeys

People rename the account number to match the old chart and expect tax, reconciliation, and year-end close to follow the number. They follow the account type. A trade receivable that has been relabelled but left as the wrong type will not reconcile, will not age, and will not close the way the old books did.

The practical sequence:

  • Set the fiscal localization for the country the lender files in. Confirm the sales and purchase tax rates and a monthly return period if that is what the revenue authority expects.
  • Walk the default chart with the accountant. Rename labels so staff recognise them. Do not change a type unless the type is actually wrong, and write down every type change.
  • Add the accounts the credit events need, before integration: principal outstanding as a current asset, interest as income, late penalties as income. Separate them. A single “loan income” account makes a waiver impossible to explain.
  • Turn on a second currency before the first foreign-currency facility. A dollar line and a local repayment cannot share one rate decided later.

Only when those accounts exist, and a manual journal can post a sample disbursement, repayment, interest accrual, and penalty, is the credit engine allowed to talk to Odoo.

The pipeline is not a disbursement

CRM holds the application: who the borrower is, the amount they asked for, the stage from first call to qualified. Moving a card to Qualified means an officer believes the file is ready. It does not mean cash left the bank. Agents who treat the stage as the loan will report a book the ledger has never seen.

What belongs on the opportunity, before any integration:

  • The borrower as a contact, not a free-text name that will be retyped later.
  • An internal note for each call. That note must not send email. The button that emails the borrower is a different control, and staff have to be shown the difference on day one.
  • A scheduled next action, assigned to a person, with a date. “Someone should call” is not an activity.

When the engines are connected later, qualified applications can be pushed and status can come back. Until then, nobody reconciles the kanban to the trial balance. They are different questions.

Disputes need a ticket, not a chat

“I already paid.” “Remove the penalty.” “The amount is wrong.” Those are helpdesk cases with an owner, a queue, and a clock. Left in a messaging app, they have no deadline and no record on the borrower.

The details that stop the queue becoming another inbox:

  • A collections queue, separate from general support, so a penalty waiver is not buried under password resets.
  • Tags that finance can filter: interest dispute, penalty waiver, proof of payment.
  • A working-hours clock. A ticket logged on Friday evening must not burn the weekend and show as breached on Monday. The timer pauses outside the hours the team actually works.
  • Solved is not closed. If the borrower replies, it comes back. If nobody touches it for an agreed number of days, it can close on its own. Closing it the moment the agent says “done” hides the reply that arrives the next morning.

The call should open the borrower

Collections fails when the agent answers on a handset, writes the outcome in a notebook, and pastes it somewhere later. The incoming number should find the contact and open it. The agent types an internal note on that record. Scheduling the follow-up is the same screen.

Two failures to design out:

  • The note button sends a customer email. Agents stop writing notes, or they write notes that the borrower receives.
  • The phone system and the contact phone field use different formats, so the screen never pops and the team decides the integration “does not work.”

Test with a known number, a known contact, and one internal note that does not leave the system. Then test a real message, on purpose, to a test address. Then talk about go-live.

What “ready to integrate” means

  • Localization, taxes, and return period confirmed by the accountant, not by the installer.
  • Legacy account names mapped, types checked, and the three loan accounts posted to by a manual entry.
  • Second currency on, with a rate date that will be stored on the entry.
  • CRM stages written down, and staff who can tell a note from an email.
  • A dispute queue with working hours and a close rule.
  • One successful screen-pop on a test call.

The credit engine is step two. The ledger has to be able to refuse a bad posting before it is asked to accept a thousand of them.

A loan book and an empty chart?

We map the ledger first, then the pipeline, then the phone. The credit engine waits.