Cosmic Module

O

Qubits of DPK

March 22, 2026

Core Open Source

fineract-branch — Full Codebase Explanation

What is Apache Fineract? It's open-source core banking software used by microfinance institutions and digital lenders. Think of it as the backend engine that keeps customer accounts, branches, loans, and savings systems organized.

What This Module Is (Big Picture)

The branch layer is the part of Fineract that models the bank's real-world office structure.
Layman: Imagine a bank with one head office, a few regional offices, and many local branches. fineract-branch is the part of the system that keeps that org chart correct, and uses it to decide who can see or manage what.
If fineract-portfolio is the customer folder system, fineract-branch is the map of the bank itself.

Where the Code Lives

Unlike the name suggests, there is not just one place where all branch logic lives.
Layman: fineract-branch is the labeled department. fineract-core contains the rulebook and data shapes. fineract-provider contains the staff actually doing the work.

Key Package 1: org.apache.fineract.organisation.office

This is the main package for office and branch management.

The Main Entity: Office.java

Path: fineract-core/src/main/java/org/apache/fineract/organisation/office/domain/Office.java
This is the main JPA entity for an office.
Layman — JPA entity: Think of this like one row in the bank's "branch list" table. Each Office object represents one real branch or head office.
Key fields on an Office:
Key methods on Office.java:
java
QUBITS OF DPK
1headOffice(String, LocalDate, ExternalId)   // Create the root office
2fromJson(Office, JsonCommand)               // Build an office from API input
3update(JsonCommand)                         // Apply changed fields
4update(Office newParent)                    // Move office under a different parent
5generateHierarchy()                         // Recompute hierarchy string
6identifiedBy(Long id)                       // Check identity
Layman: These methods are like actions in an admin dashboard: create a branch, rename it, move it under another branch, and refresh its place in the tree.

The Most Important Idea: hierarchy

The key design idea here is the hierarchy field.
It stores the office tree path as a string so Fineract can quickly answer questions like:
  • Is this office under the current user's branch?
  • Which branches can this user see?
  • Can this user update that office?
plain text
QUBITS OF DPK
1Head Office        -> .
2Regional Office    -> .1.
3Local Branch       -> .1.4.
4Sub Branch         -> .1.4.9.
Layman: It works like a folder path on your laptop. If /Head/RegionA/Branch4 starts with /Head/RegionA, then you know it lives under that region.

DTO Layer: OfficeData.java

Path: fineract-core/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
This is the main data transfer object returned to APIs and UI layers.
Layman — DTO: Instead of sending the full database object, Fineract creates a cleaner "summary packet" with just the fields needed by the frontend or API caller.
Key fields:
java
QUBITS OF DPK
1id
2name
3nameDecorated
4externalId
5openingDate
6hierarchy
7parentId
8parentName
9allowedParents
nameDecorated is especially useful because it visually reflects the office depth.
Layman: If the UI shows indentation in the office dropdown, that decorated name is what makes the org tree readable.

Key Package 2: API Layer

OfficesApiResource.java

Path: fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
This is the REST controller for office operations.
Layman — REST controller: When an admin panel or app asks the backend for branch data, this class is the front desk that receives the request.
Key endpoints:
plain text
QUBITS OF DPK
1GET    /v1/offices                     -> List offices
2GET    /v1/offices/template            -> Get template data for office creation
3GET    /v1/offices/{officeId}          -> Get one office
4GET    /v1/offices/external-id/{id}    -> Find an office by external ID
5POST   /v1/offices                     -> Create a new office
6PUT    /v1/offices/{officeId}          -> Update an office
7PUT    /v1/offices/external-id/{id}    -> Update using external ID
8GET    /v1/offices/downloadtemplate    -> Download bulk import Excel template
9POST   /v1/offices/uploadtemplate      -> Upload bulk office import file
Layman: This is what lets a branch-management screen load all branches, open a branch profile, create a new branch, or upload an Excel sheet to create many branches at once.
A notable detail in retrieveOffices() is the includeAllOffices behavior plus ordering parameters. That is where Fineract decides how wide the office list should be and how to sort it.

OfficeTransactionsApiResource.java

Path: fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficeTransactionsApiResource.java
This handles money transfers between offices.
Key endpoints:
plain text
QUBITS OF DPK
1GET    /v1/officetransactions          -> List office-to-office transfers
2GET    /v1/officetransactions/template -> Get transaction template data
3POST   /v1/officetransactions          -> Create a transfer
4DELETE /v1/officetransactions/{id}     -> Delete a transfer
Layman: If one branch sends funds to another, this API is the system record for that transfer.

Key Package 3: Read Services

OfficeReadPlatformService.java + OfficeReadPlatformServiceImpl.java

Paths:
  • fineract-core/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformService.java
  • fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
This is the read side of the office system.
Layman: The interface is the menu. The implementation is the kitchen.
Key read operations:
java
QUBITS OF DPK
1retrieveAllOffices(boolean, SearchParameters)
2retrieveAllOfficesForDropdown()
3retrieveOffice(Long officeId)
4retrieveOfficeWithExternalId(ExternalId)
5retrieveNewOfficeTemplate()
6retrieveAllowedParents(Long officeId)
7retrieveAllOfficeTransactions()

Important behavior inside the implementation

OfficeReadPlatformServiceImpl uses the current logged-in user's office hierarchy to filter what they can see.
java
QUBITS OF DPK
1final String hierarchy = currentUser.getOffice().getHierarchy();
2final String hierarchySearchString = hierarchy + "%";
Layman: A branch manager usually should not see data for totally unrelated branches. The code uses the user's own branch path to limit visibility.
It also builds nameDecorated using hierarchy depth, which helps dropdowns look like a tree instead of a flat list.
Another important point: the implementation mixes JDBC for queries with cache annotations like @Cacheable.
Layman: Read-heavy branch lookups are optimized because office trees are queried often and do not change every second.

Key Package 4: Write Services

OfficeWritePlatformService.java + OfficeWritePlatformServiceJpaRepositoryImpl.java

Paths:
  • fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformService.java
  • fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java
This is the write side: create, update, and office transactions.
Key write operations:
java
QUBITS OF DPK
1createOffice(JsonCommand)
2updateOffice(Long officeId, JsonCommand)
3officeTransaction(JsonCommand)
4deleteOfficeTransaction(Long transactionId, JsonCommand)

Important behavior inside the write service

Before creating or updating an office, it validates permissions using the current user's office hierarchy.
Layman: A manager at Branch A should not be able to reorganize Branch Z on the other side of the country.
The method validateUserPriviledgeOnOfficeAndRetrieve(...) is one of the most important security checks in this module.
When a new office is created:
  1. #
    Input is validated.
  2. #
    Parent office is resolved.
  3. #
    The office is saved once to get an ID.
  4. #
    The hierarchy string is generated.
  5. #
    It is saved again with the final hierarchy.
Layman: It first creates the branch record, then fills in its exact position in the org chart after the database gives it an ID.
The service also evicts office caches after writes.
Layman: If the branch tree changes, cached old branch lists must be cleared so users see the new structure immediately.

Command Handlers

Path: fineract-provider/src/main/java/org/apache/fineract/organisation/office/handler/
Key handler classes:
plain text
QUBITS OF DPK
1CreateOfficeCommandHandler.java
2UpdateOfficeCommandHandler.java
3CreateOfficeTransactionCommandHandler.java
4DeleteOfficeTransactionCommandHandler.java
Layman — Command pattern: Instead of one huge class doing everything, each action gets its own handler. That keeps code smaller, clearer, and easier to audit.
This also fits Fineract's broader command-processing architecture, where API calls are wrapped as commands and routed through the command framework.

Validators / Deserializers

OfficeCommandFromApiJsonDeserializer.java

Path: fineract-provider/src/main/java/org/apache/fineract/organisation/office/serialization/OfficeCommandFromApiJsonDeserializer.java
This validates office create and update payloads.
Important fields it checks:
java
QUBITS OF DPK
1name
2parentId
3openingDate
4externalId
5locale
6dateFormat
It enforces rules like:
  • name must not be blank
  • name max length is 100
  • openingDate is required for create
  • parentId must be positive when provided
  • externalId max length is 100
Layman: Before the system creates a branch, it checks that the form is complete and reasonable.

OfficeTransactionCommandFromApiJsonDeserializer.java

This validates office-to-office transfer input.
Layman: Same idea, but for money moving between branches.

Supporting Domain Object: OfficeTransaction.java

Path: fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeTransaction.java
This entity models money movement between offices.
Key fields:
Layman: This is the branch-to-branch ledger entry.

Repository and Data Access Layer

Key supporting classes:

Exceptions

Office-related errors are split across fineract-core and fineract-provider.
There are also data-integrity errors raised for duplicate office name or duplicate externalId.
Layman: The system prevents nonsense structures like duplicate branch identities or a branch reporting to itself.

How It All Connects (Full Flow)

Here is the typical flow when an admin creates a new branch:
plain text
QUBITS OF DPK
1Admin UI
2    │  POST /v1/offices { "name": "Chennai Branch", "parentId": 1, "openingDate": "2026-03-22" }
34OfficesApiResource.java
5    │  ← REST controller receives request
67CommandProcessingService
8    │  ← Routes request to the office command handler
910CreateOfficeCommandHandler.java
111213OfficeWritePlatformServiceJpaRepositoryImpl.java
14    │  → OfficeCommandFromApiJsonDeserializer validates input
15    │  → validateUserPriviledgeOnOfficeAndRetrieve() checks authorization
16    │  → Office.fromJson(...) creates domain object
17    │  → saveAndFlush() gets database ID
18    │  → generateHierarchy() computes tree path
19    │  → save() persists final office
2021Database (`m_office`)
222324CommandProcessingResult
252627Admin UI receives new office ID
Layman — full flow: It is like adding a new branch to the company org chart software. The system checks the form, checks whether you are allowed to do it, creates the branch, places it in the right spot in the tree, saves it, and sends back confirmation.

Why This Module Matters to the Rest of Fineract

Many other modules depend on office structure even if they are not inside the branch package.
Examples:
  • Users belong to offices
  • Clients belong to offices
  • Loan officers operate within office scopes
  • Reporting often filters by office hierarchy
  • Security rules often depend on office ancestry
Layman: Branch logic is not just "admin metadata." It decides who owns customers, who can access data, and how work is divided across the institution.

Connection to Your PRs

Your PR #5658 (InstanceModeIntegrationTest) touches this module through the office API behavior.
The test checks GET /offices, especially the case where the head office should not be retrievable in batch-only mode.
That directly relates to:
  • OfficesApiResource.java handling the request
  • office visibility rules in the read layer
  • the broader branch hierarchy model used by the platform
Layman: Your test is basically asking: "When the system runs in this restricted mode, does the branch-list API still behave correctly?"

One-Sentence Layman Summary

fineract-branch is the part of Fineract that keeps the bank's branch tree organized and uses that structure to control visibility, permissions, ownership, and branch-to-branch operations.
If you want, I can next create the same style pages for fineract-core and fineract-provider too, so the whole architecture section stays visually consistent.