# OMNL Fineract scripts
Scripts for the **OMNL** tenancy ([omnl.hybxfinance.io](https://omnl.hybxfinance.io/)). Load env from `omnl-fineract/.env` or repo root `.env` (see [OMNL_FINERACT_CONFIGURATION.md](../../docs/04-configuration/OMNL_FINERACT_CONFIGURATION.md)).
| Script | Purpose |
|--------|---------|
| **omnl-gl-accounts-create.sh** | Create the five migration GL accounts (1000, 1050, 2000, 2100, 3000) via `POST /glaccounts`. Idempotent (skips if exists). Run **before** ledger post. See [OMNL_GL_ACCOUNTS_REQUIRED.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_GL_ACCOUNTS_REQUIRED.md). |
| **omnl-gl-accounts-fx-gru-create.sh** | Create FX and GRU (M00) GL accounts from Chart of Accounts (12xxx/13xxx, 21xxx, 42xxx/52xxx). See [OMNL_GL_ACCOUNTS_FX_GRU.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_GL_ACCOUNTS_FX_GRU.md). |
| **omnl-discovery.sh** | GET offices, clients, savings/FD/RD products and accounts; output JSON. Set `OUT_DIR=
` to write files. |
| **omnl-ledger-post.sh** | Post ledger allocation entries T-001–T-008 per [LEDGER_ALLOCATION_POSTING_RUNBOOK.md](../../docs/04-configuration/mifos-omnl-central-bank/LEDGER_ALLOCATION_POSTING_RUNBOOK.md). Resolves GL from `GET /glaccounts`. `DRY_RUN=1`, `TRANSACTION_DATE`, `OFFICE_ID=1` optional. |
| **omnl-ledger-post-from-matrix.sh** | Post journal entries from [omnl-journal-matrix.json](../../docs/04-configuration/mifos-omnl-central-bank/omnl-journal-matrix.json) (matrix + full GL + IPSAS). Resolves glCode→id; posts to OMNL Hybx. `JOURNAL_MATRIX=`, `DRY_RUN=1`, `TRANSACTION_DATE` optional. See [OMNL_JOURNAL_LEDGER_MATRIX.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_JOURNAL_LEDGER_MATRIX.md). |
| **omnl-deposit-one.sh** | Post a single deposit to an existing savings account. `ACCOUNT_ID= AMOUNT= [DATE=yyyy-MM-dd]`. Use discovery output for account IDs; for bulk, loop over a CSV or discovery JSON. |
| **omnl-client-names-fix.sh** | Set client `firstname`/`lastname` to canonical entity names when blank. `DRY_RUN=1` to print only. See [OMNL_CLIENT_NAMES_FIX.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_CLIENT_NAMES_FIX.md). |
| **omnl-entity-data-apply.sh** | Apply entity master data to **Fineract clients** (name, LEI identifier, address, contacts). Skip if you use **offices-only**; LEI for the package comes from [OMNL_ENTITY_MASTER_DATA.json](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json) + snapshot enrich. `ENTITY_DATA`, `DRY_RUN=1`. |
| **omnl-clients-create-9-15.sh** | Create clients 9–15 in Fineract (FIDIS, Alpha Omega Holdings, …). Idempotent. `DRY_RUN=1` to print only. *(Deprecated if using entities as offices instead.)* |
| **omnl-offices-populate-15.sh** | Populate the 15 entities as **Offices** (Organization / Manage Offices): update office 1 name, create offices 2–15 as children. Uses [OMNL_ENTITY_MASTER_DATA.json](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json). `DRY_RUN=1` to print only; `OPENING_DATE=yyyy-MM-dd` optional. |
| **omnl-clients-remove-15.sh** | Remove the 15 clients (ids 1–15). Run after populating entities as offices. Requires `CONFIRM_REMOVE=1`; `DRY_RUN=1` to preview. |
| **omnl-user-shamrayan-office-create.sh** | Create Staff for office 2 (Shamrayan) and User `shamrayan.admin` with full admin access to that office only. Requires `OMNL_SHAMRAYAN_ADMIN_PASSWORD`. See [OMNL_OFFICE_LOGINS_AND_CREDENTIALS.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_OFFICE_LOGINS_AND_CREDENTIALS.md). |
| **omnl-office2-access-security-test.sh** | Security test: office-2 user must not see other offices’ data or achieve path traversal/command injection. Set office-2 user and password (e.g. `OMNL_OFFICE2_TEST_USER`, `OMNL_OFFICE2_TEST_PASSWORD`). See [OMNL_OFFICE_2_ACCESS_SECURITY_TEST.md](../../docs/04-configuration/mifos-omnl-central-bank/OMNL_OFFICE_2_ACCESS_SECURITY_TEST.md). |
| **omnl-office-create-samama.sh** | Create Office for Samama Group LLC (Azerbaijan) and post 5B USD M1 from Head Office (Phase C pattern: HO Dr 2100 Cr 2410; office Dr 1410 Cr 2100). Idempotent by externalId. `SKIP_TRANSFER=1` to create office only. See [SAMAMA_OFFICE_AND_5B_M1_TRANSFER.md](../../docs/04-configuration/mifos-omnl-central-bank/SAMAMA_OFFICE_AND_5B_M1_TRANSFER.md). |
| **omnl-office-create-pelican.sh** | Create Office for Pelican Motors And Finance LLC (Chalmette, LA). Idempotent by externalId `PEL-MOTORS-CHALMETTE-LA`. Use with omnl.hybx.global by setting `OMNL_FINERACT_BASE_URL`. See [PELICAN_MOTORS_OFFICE_RUNBOOK.md](../../docs/04-configuration/mifos-omnl-central-bank/PELICAN_MOTORS_OFFICE_RUNBOOK.md). |
| **omnl-office-create-adf-singapore.sh** | Create Office for ADF ASIAN PACIFIC HOLDING SINGAPORE PTE LTD (child of OMNL Head Office). Idempotent by externalId `202328126M`. See [ADF_ASIAN_PACIFIC_SINGAPORE_OFFICE_RUNBOOK.md](../../docs/04-configuration/mifos-omnl-central-bank/ADF_ASIAN_PACIFIC_SINGAPORE_OFFICE_RUNBOOK.md). |
| **omnl-transaction-package-snapshot.sh** | **Regulator Section 2:** `GET /offices` + `GET /glaccounts` → `omnl_transaction_package_snapshot.json`, then **enrich** offices with LEI/entity names from `OMNL_ENTITY_MASTER_DATA.json` (`scripts/omnl/jq/enrich-snapshot-entity-master.jq`). `OUT_DIR` / `OUT_FILE` / `ENTITY_DATA` optional. |
| **omnl-office-create-bank-kanaya.sh** | Create **Bank Kanaya** office (`externalId=BANK-KANAYA-ID`, parent HO). Idempotent. `DRY_RUN=1` first. See [BANK_KANAYA_OFFICE_RUNBOOK.md](../../docs/04-configuration/mifos-omnl-central-bank/BANK_KANAYA_OFFICE_RUNBOOK.md). |
| **build-transaction-package-zip.sh** | **Zip:** `transaction-package-HYBX-BATCH-001.zip` — binder + 215k ledger + Merkle + Appendix. Stages snapshot, **enrich** from `OMNL_ENTITY_MASTER_DATA.json`, copies that JSON (+ `.md`) into `Volume_A/Section_2/`. Needs root `omnl_transaction_package_snapshot.json` or `ALLOW_MISSING_OMNL_SNAPSHOT=1`. |
| **generate-transaction-package-evidence.py** | Ledger, exhibits, e-sign policy, `GENERATED_EVIDENCE_ESIGN_MANIFEST.json`. |
| **apply-qes-tsa-to-staging.sh** | Optional RFC 3161 TSA + CMS on anchor (`TSA_URL`, `QES_SIGN_*`). |
| **verify-transaction-package-commitment.py** | Verify `contentCommitmentSha256` vs unzipped tree. |
| **patch-attestation-subreg-pdf-hashes.sh** | Set `COUNSEL_PDF` + `AUDIT_PDF` → updates `INSTITUTIONAL_PACKAGE_SCORE_ATTESTATION_4_995.json` PDF SHA-256 fields; then rebuild zip. |
| **check-transaction-package-4995-readiness.sh** | **4.995 gate:** structural checks; `--strict` requires live OMNL snapshot, finalized ISO vault hashes, completed regulatory annex, signed attestation JSON. See `INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md`. |
| **run-transaction-package-ci-smoke.sh** | **CI / dev:** fast package build (10-row fixture ledger, no snapshot), `verify-transaction-package-commitment.py` + structural `check-transaction-package-4995-readiness.sh`. Unsets `TSA_URL`. |
| **omnl-pvp-post-clearing-bank-kanaya.sh** | **PvP clearing JEs** (HO Dr2410/Cr2100; Kanaya Dr2100/Cr1410). `DRY_RUN=1` default; `OFFICE_ID_HO` / `OFFICE_ID_KANAYA` / `AMOUNT_MINOR_UNITS`. See [PvP_MULTILATERAL_NET_SETTLEMENT_BANK_KANAYA.md](../../docs/04-configuration/mifos-omnl-central-bank/PvP_MULTILATERAL_NET_SETTLEMENT_BANK_KANAYA.md). |
| **resolve_ids.sh** | Resolve GL IDs (1410, 2100, 2410) and payment type; write `ids.env`. Run before closures/reconciliation/templates. See [OPERATING_RAILS.md](../../docs/04-configuration/mifos-omnl-central-bank/OPERATING_RAILS.md). |
| **omnl-gl-closures-post.sh** | Post GL closures for Office 20 and HO (idempotent). `CLOSING_DATE=yyyy-MM-dd`, `DRY_RUN=1`. See [OPERATING_RAILS.md](../../docs/04-configuration/mifos-omnl-central-bank/OPERATING_RAILS.md). |
| **omnl-reconciliation-office20.sh** | Snapshot Office 20 (offices + GL + trial balance), timestamp, sha256. `OUT_DIR=./reconciliation`. See [OPERATING_RAILS.md](../../docs/04-configuration/mifos-omnl-central-bank/OPERATING_RAILS.md). |
| **omnl-operator-rail.sh** | One-command rail: resolve IDs, closures, verify, reconciliation, A/B/C readiness, print templates. `SKIP_CLOSURES=1` / `SKIP_RECON=1` optional. See [OPERATING_RAILS.md](../../docs/04-configuration/mifos-omnl-central-bank/OPERATING_RAILS.md). |
| **omnl-audit-packet-office20.sh** | Audit packet: snapshot.json, snapshot.meta, computed_balances.json, recent_journal_entries.json, manifest.json. See [OFFICE_20_AUDIT_PACKET.md](../../docs/04-configuration/mifos-omnl-central-bank/OFFICE_20_AUDIT_PACKET.md). |
| **omnl-je-reverse-by-reference.sh** | Reverse JE by referenceNumber. `REFERENCE_NUMBER=...` See [OFFICE_20_DR_RUNBOOK.md](../../docs/04-configuration/mifos-omnl-central-bank/OFFICE_20_DR_RUNBOOK.md). |
| **omnl-je-maker.sh** / **omnl-je-checker.sh** | Maker-checker: maker writes payload + sha256; checker validates and posts. |
| **omnl-monitor-office20-movement.sh** | Exit 2 if Office 20 movement in last N days (alert payload). |
| **omnl-config-hash.sh** | Output hashes of payment types, GL, office 20 (drift detection). |
| **validate-rail.sh** | CI: .gitignore (ids.env, reconciliation), resolve_ids pattern, shellcheck. |
**Populate 15 entities as Offices (remove as Clients)**
From repo root with `omnl-fineract/.env` set:
```bash
# 1. Populate entities as offices (update office 1, create offices 2–15)
DRY_RUN=1 bash scripts/omnl/omnl-offices-populate-15.sh
bash scripts/omnl/omnl-offices-populate-15.sh
# 2. Remove the 15 clients (requires confirmation)
DRY_RUN=1 bash scripts/omnl/omnl-clients-remove-15.sh
CONFIRM_REMOVE=1 bash scripts/omnl/omnl-clients-remove-15.sh
```
**Complete all clients (1–15) in one go** *(only if keeping entities as clients)*
From repo root with `omnl-fineract/.env` set (OMNL_FINERACT_BASE_URL, OMNL_FINERACT_PASSWORD):
```bash
# 1. Create clients 9–15 in Fineract (no-op if they already exist)
bash scripts/omnl/omnl-clients-create-9-15.sh
# 2. Set names for all 15 + apply LEI/address/contacts from OMNL_ENTITY_MASTER_DATA.json
bash scripts/omnl/omnl-entity-data-apply.sh
```
Optional: run `DRY_RUN=1` before each step to preview. To only fix names (no LEI/address/contact), run `bash scripts/omnl/omnl-client-names-fix.sh` after step 1.
**Run from repo root:**
```bash
# 1. Create GL accounts (run first; idempotent)
bash scripts/omnl/omnl-gl-accounts-create.sh
# 2. Post ledger entries (T-001–T-008) — from runbook or from matrix JSON
bash scripts/omnl/omnl-ledger-post.sh
# Or from matrix (full GL + IPSAS): omnl-ledger-post-from-matrix.sh
DRY_RUN=1 bash scripts/omnl/omnl-ledger-post-from-matrix.sh
bash scripts/omnl/omnl-ledger-post-from-matrix.sh
# Discovery (list products, clients, accounts)
bash scripts/omnl/omnl-discovery.sh
OUT_DIR=./output/omnl-discovery bash scripts/omnl/omnl-discovery.sh
# Ledger dry run (print payloads only)
DRY_RUN=1 bash scripts/omnl/omnl-ledger-post.sh
# Single deposit (ACCOUNT_ID from discovery)
ACCOUNT_ID=1 AMOUNT=100 DATE=2026-02-10 bash scripts/omnl/omnl-deposit-one.sh
# Fix blank client names (set canonical entity names)
DRY_RUN=1 bash scripts/omnl/omnl-client-names-fix.sh
bash scripts/omnl/omnl-client-names-fix.sh
# Apply full entity data (names + LEI + address + contacts from OMNL_ENTITY_MASTER_DATA.json)
ENTITY_DATA=docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json DRY_RUN=1 bash scripts/omnl/omnl-entity-data-apply.sh
bash scripts/omnl/omnl-entity-data-apply.sh
# Create clients 9–15 (idempotent)
DRY_RUN=1 bash scripts/omnl/omnl-clients-create-9-15.sh
bash scripts/omnl/omnl-clients-create-9-15.sh
# Populate 15 entities as offices (Organization / Manage Offices)
DRY_RUN=1 bash scripts/omnl/omnl-offices-populate-15.sh
bash scripts/omnl/omnl-offices-populate-15.sh
# Remove the 15 clients (after populating as offices)
CONFIRM_REMOVE=1 bash scripts/omnl/omnl-clients-remove-15.sh
# Samama Group LLC — create office and 5B USD M1 transfer (Phase C interoffice)
DRY_RUN=1 bash scripts/omnl/omnl-office-create-samama.sh
bash scripts/omnl/omnl-office-create-samama.sh
# Office only (no transfer): SKIP_TRANSFER=1 bash scripts/omnl/omnl-office-create-samama.sh
# Pelican Motors And Finance LLC — create office (omnl.hybx.global or omnl.hybxfinance.io)
DRY_RUN=1 bash scripts/omnl/omnl-office-create-pelican.sh
bash scripts/omnl/omnl-office-create-pelican.sh
# ADF Asian Pacific Holding Singapore Pte Ltd — create office (child of OMNL Head Office, externalId 202328126M)
DRY_RUN=1 bash scripts/omnl/omnl-office-create-adf-singapore.sh
bash scripts/omnl/omnl-office-create-adf-singapore.sh
```
**Transaction package — env vars**
| Variable | Purpose |
|----------|---------|
| `OUT_ZIP` | Output zip path |
| `ALLOW_MISSING_OMNL_SNAPSHOT` | `1` = build without Section 2 snapshot (non-submission) |
| `HYBX_LEDGER_FILE` | Replace generated CSV |
| `EVIDENCE_GENERATED_AT_UTC` | Fixed ISO UTC for reproducible generator timestamps |
| `TSA_URL` / `QES_SIGN_CERT` / `QES_SIGN_KEY` | Optional crypto (see `apply-qes-tsa-to-staging.sh`) |
| `APPLY_REAL_QES_TSA` | `1` = require TSA or QES env |
**Requirements:** `curl`, `jq` (for ledger posting and pretty-print in discovery).