2026-03-02 11:37:34 -08:00
#!/usr/bin/env bash
# OMNL Fineract — Apply entity master data (name, LEI, address, contacts) to clients.
# Reads OMNL_ENTITY_MASTER_DATA.json; maps by accountNo to clientId; updates names, identifiers (LEI), addresses, contacts.
# Usage: run from repo root; sources omnl-fineract/.env or .env.
# ENTITY_DATA=<path> JSON entity data (default: docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json)
# DRY_RUN=1 print only, do not PUT/POST.
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
# OMNL_CLIENTS_PAGE_LIMIT=200 page size when listing clients (default 200).
# OMNL_CLIENT_ID_OVERRIDES='{"1":"123"}' map entity clientNumber -> Fineract client id when accountNo/externalId miss.
# OMNL_LEI_CLIENT_ID_OVERRIDE=123 legacy: same as overrides for clientNumber 1 only.
2026-03-02 11:37:34 -08:00
# Requires: curl, jq.
set -euo pipefail
REPO_ROOT = " ${ REPO_ROOT :- $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) /../.. " && pwd ) } "
DRY_RUN = " ${ DRY_RUN :- 0 } "
ENTITY_DATA = " ${ ENTITY_DATA :- ${ REPO_ROOT } /docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json } "
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
# shellcheck source=lib/omnl-fineract-common.sh
source " ${ REPO_ROOT } /scripts/omnl/lib/omnl-fineract-common.sh "
2026-03-02 11:37:34 -08:00
if [ ! -f " $ENTITY_DATA " ] ; then
echo " Entity data file not found: $ENTITY_DATA " >& 2
exit 1
fi
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
omnl_fineract_load_env
omnl_fineract_init_curl || exit 1
2026-03-02 11:37:34 -08:00
# Resolve clientId by accountNo (000000001 -> id)
get_client_id_by_account( ) {
local account_no = " $1 "
local clients_json = " $2 "
if echo " $clients_json " | jq -e '.pageItems' >/dev/null 2>& 1; then
echo " $clients_json " | jq -r --arg an " $account_no " '.pageItems[] | select(.accountNo == $an) | .id'
else
echo " $clients_json " | jq -r --arg an " $account_no " '.[] | select(.accountNo == $an) | .id'
fi
}
# Resolve clientId by externalId (e.g. OMNL-9) when accountNo not found
get_client_id_by_external_id( ) {
local ext_id = " $1 "
local clients_json = " $2 "
if echo " $clients_json " | jq -e '.pageItems' >/dev/null 2>& 1; then
echo " $clients_json " | jq -r --arg e " $ext_id " '.pageItems[] | select(.externalId == $e) | .id'
else
echo " $clients_json " | jq -r --arg e " $ext_id " '.[] | select(.externalId == $e) | .id'
fi
}
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
clients_json = $( omnl_fineract_fetch_all_clients_pageitems)
if ! echo " $clients_json " | jq -e '.pageItems' >/dev/null 2>& 1; then
echo "Unexpected clients response (no pageItems)." >& 2
2026-03-02 11:37:34 -08:00
exit 1
fi
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
_client_total = $( echo " $clients_json " | jq '.pageItems | length' )
if [ " $_client_total " -eq 0 ] 2>/dev/null; then
echo "Note: Fineract returned 0 clients. Use ./scripts/omnl/omnl-list-clients.sh to confirm; set OMNL_CLIENT_ID_OVERRIDES or recreate clients." >& 2
fi
2026-03-02 11:37:34 -08:00
entity_count = $( jq -r '.entities | length' " $ENTITY_DATA " )
updated_names = 0
updated_lei = 0
updated_address = 0
updated_contact = 0
for i in $( seq 0 $(( entity_count - 1 )) ) ; do
entity = $( jq -c " .entities[ $i ] " " $ENTITY_DATA " )
client_num = $( echo " $entity " | jq -r '.clientNumber' )
account_no = $( echo " $entity " | jq -r '.accountNo' )
entity_name = $( echo " $entity " | jq -r '.entityName' )
lei = $( echo " $entity " | jq -r '.lei // ""' )
mobile = $( echo " $entity " | jq -r '.contact.mobileNo // ""' )
email = $( echo " $entity " | jq -r '.contact.emailAddress // ""' )
client_id = $( get_client_id_by_account " $account_no " " $clients_json " )
if [ -z " $client_id " ] || [ " $client_id " = "null" ] ; then
client_id = $( get_client_id_by_external_id " OMNL- ${ client_num } " " $clients_json " )
fi
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
if { [ -z " $client_id " ] || [ " $client_id " = "null" ] ; } && [ -n " ${ OMNL_CLIENT_ID_OVERRIDES :- } " ] ; then
client_id = $( echo " $OMNL_CLIENT_ID_OVERRIDES " | jq -r --arg n " $client_num " '.[$n] // empty' 2>/dev/null || true )
if [ " $client_id " = "null" ] ; then client_id = "" ; fi
fi
if { [ -z " $client_id " ] || [ " $client_id " = "null" ] ; } && [ " $client_num " = "1" ] && [ -n " ${ OMNL_LEI_CLIENT_ID_OVERRIDE :- } " ] ; then
client_id = " ${ OMNL_LEI_CLIENT_ID_OVERRIDE } "
fi
2026-03-02 11:37:34 -08:00
if [ -z " $client_id " ] || [ " $client_id " = "null" ] ; then
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
echo " Skip: no client with accountNo= $account_no or externalId=OMNL- $client_num (try OMNL_CLIENT_ID_OVERRIDES or ./scripts/omnl/omnl-list-clients.sh) " >& 2
2026-03-02 11:37:34 -08:00
continue
fi
echo " === Client $client_num (id= $client_id ) $entity_name === " >& 2
# 1. Name (lastname non-blank required by tenant validation)
payload_name = $( jq -n --arg f " $entity_name " --arg l "." '{ firstname: $f, lastname: $l }' )
if [ " $DRY_RUN " = "1" ] ; then
echo " [DRY RUN] PUT clients/ ${ client_id } name= $entity_name " >& 2
else
res = $( curl " ${ CURL_OPTS [@] } " -X PUT -d " $payload_name " " ${ BASE_URL } /clients/ ${ client_id } " 2>/dev/null) || true
if echo " $res " | jq -e '.resourceId // .clientId' >/dev/null 2>& 1; then
( ( updated_names++) ) || true
fi
fi
# 2. LEI identifier (if lei non-empty)
if [ -n " $lei " ] && [ " $lei " != "null" ] ; then
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
if [ " $DRY_RUN " != "1" ] && omnl_fineract_client_has_document_key " $client_id " " $lei " ; then
echo " LEI already on client: $lei (skip POST) " >& 2
else
lei_type_id = $( omnl_fineract_get_lei_document_type_id " $client_id " )
if [ -n " $lei_type_id " ] && [ " $lei_type_id " != "null" ] ; then
payload_lei = $( jq -n --arg key " $lei " --argjson typeId " $lei_type_id " '{ documentKey: $key, documentTypeId: $typeId, description: "LEI", status: "Active" }' )
if [ " $DRY_RUN " = "1" ] ; then
echo " [DRY RUN] POST clients/ ${ client_id } /identifiers LEI= $lei " >& 2
else
res = $( curl " ${ CURL_OPTS [@] } " -X POST -d " $payload_lei " " ${ BASE_URL } /clients/ ${ client_id } /identifiers " 2>/dev/null) || true
if echo " $res " | jq -e '.resourceId // .clientId' >/dev/null 2>& 1; then
( ( updated_lei++) ) || true
fi
2026-03-02 11:37:34 -08:00
fi
feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)
Made-with: Cursor
2026-03-24 18:11:36 -07:00
else
echo " Skip LEI: no LEI document type in tenant (add via Admin or codes)" >& 2
2026-03-02 11:37:34 -08:00
fi
fi
fi
# 3. Address (if any address field set and countryId present)
country_id = $( echo " $entity " | jq -r '.address.countryId // empty' )
street = $( echo " $entity " | jq -r '.address.street // ""' )
line1 = $( echo " $entity " | jq -r '.address.addressLine1 // ""' )
city = $( echo " $entity " | jq -r '.address.city // ""' )
if [ -n " $country_id " ] && [ " $country_id " != "null" ] && { [ -n " $street " ] || [ -n " $line1 " ] || [ -n " $city " ] ; } ; then
payload_addr = $( echo " $entity " | jq -c '
.address | {
street: ( .street // "" ) ,
addressLine1: ( .addressLine1 // "" ) ,
addressLine2: ( .addressLine2 // "" ) ,
addressLine3: ( .addressLine3 // "" ) ,
city: ( .city // "" ) ,
postalCode: ( if .postalCode != null and .postalCode != "" then .postalCode else "" end) ,
countryId: .countryId,
isActive: true
} + ( if .stateProvinceId != null and .stateProvinceId != "" then { stateProvinceId: .stateProvinceId } else { } end)
' )
if [ " $DRY_RUN " = "1" ] ; then
echo " [DRY RUN] POST client/ ${ client_id } /addresses " >& 2
else
res = $( curl " ${ CURL_OPTS [@] } " -X POST -d " $payload_addr " " ${ BASE_URL } /client/ ${ client_id } /addresses " 2>/dev/null) || true
if echo " $res " | jq -e '.resourceId // .addressId' >/dev/null 2>& 1; then
( ( updated_address++) ) || true
fi
fi
fi
# 4. Contact (mobileNo, emailAddress) via PUT client
if [ -n " $mobile " ] || [ -n " $email " ] ; then
payload_contact = $( jq -n --arg m " $mobile " --arg e " $email " '{ mobileNo: $m, emailAddress: $e }' )
if [ " $DRY_RUN " = "1" ] ; then
echo " [DRY RUN] PUT clients/ ${ client_id } contact mobile= $mobile email= $email " >& 2
else
res = $( curl " ${ CURL_OPTS [@] } " -X PUT -d " $payload_contact " " ${ BASE_URL } /clients/ ${ client_id } " 2>/dev/null) || true
if echo " $res " | jq -e '.resourceId // .clientId' >/dev/null 2>& 1; then
( ( updated_contact++) ) || true
fi
fi
fi
done
echo " Done: names= $updated_names , LEI= $updated_lei , addresses= $updated_address , contacts= $updated_contact " >& 2