Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- Config, docs, scripts, and backup manifests - Submodule refs unchanged (m = modified content in submodules) Made-with: Cursor
70 lines
3.1 KiB
Bash
Executable File
70 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# OMNL Fineract — Minimum viable reconciliation snapshot for Office 20 (Samama): offices, GL balances, and optional trial balance.
|
|
# Writes a timestamped file with hash and metadata. Run daily (or after material postings).
|
|
# Usage: from repo root. OUT_DIR=./reconciliation (default). See OPERATING_RAILS.md.
|
|
|
|
set -euo pipefail
|
|
REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
OUT_DIR="${OUT_DIR:-${REPO_ROOT}/reconciliation}"
|
|
OFFICE_ID="${OFFICE_ID:-20}"
|
|
TIMESTAMP="${TIMESTAMP:-$(date -u +%Y%m%d-%H%M%S)}"
|
|
|
|
if [ -f "${REPO_ROOT}/omnl-fineract/.env" ]; then
|
|
set +u
|
|
source "${REPO_ROOT}/omnl-fineract/.env" 2>/dev/null || true
|
|
set -u
|
|
elif [ -f "${REPO_ROOT}/.env" ]; then
|
|
set +u
|
|
source "${REPO_ROOT}/.env" 2>/dev/null || true
|
|
set -u
|
|
fi
|
|
|
|
BASE_URL="${OMNL_FINERACT_BASE_URL:-}"
|
|
TENANT="${OMNL_FINERACT_TENANT:-omnl}"
|
|
USER="${OMNL_FINERACT_USER:-app.omnl}"
|
|
PASS="${OMNL_FINERACT_PASSWORD:-}"
|
|
|
|
if [ -z "$BASE_URL" ] || [ -z "$PASS" ]; then
|
|
echo "Set OMNL_FINERACT_BASE_URL and OMNL_FINERACT_PASSWORD" >&2
|
|
exit 1
|
|
fi
|
|
|
|
CURL_OPTS=(-s -S -H "Fineract-Platform-TenantId: ${TENANT}" -H "Content-Type: application/json" -u "${USER}:${PASS}")
|
|
mkdir -p "$OUT_DIR"
|
|
|
|
REPORT_FILE="${OUT_DIR}/office${OFFICE_ID}-${TIMESTAMP}.json"
|
|
META_FILE="${OUT_DIR}/office${OFFICE_ID}-${TIMESTAMP}.meta"
|
|
|
|
# 1) Office 20 (and HO) summary
|
|
offices=$(curl "${CURL_OPTS[@]}" "${BASE_URL}/offices" 2>/dev/null)
|
|
echo "$offices" | jq --argjson o "$OFFICE_ID" '[.[] | select(.id == $o or .id == 1)]' > "${REPORT_FILE}.offices" 2>/dev/null || echo "$offices" > "${REPORT_FILE}.offices"
|
|
|
|
# 2) GL accounts (1410, 2100, 2410) — balances if API returns them; otherwise list
|
|
glaccounts=$(curl "${CURL_OPTS[@]}" "${BASE_URL}/glaccounts" 2>/dev/null)
|
|
echo "$glaccounts" | jq '[.[] | select(.glCode == "1410" or .glCode == "2100" or .glCode == "2410") | {glCode, id, name, organizationRunningBalance: (.organizationRunningBalance // "n/a")}]' > "${REPORT_FILE}.gl" 2>/dev/null || echo "$glaccounts" > "${REPORT_FILE}.gl"
|
|
|
|
# 3) Trial balance for office (parameter names vary by deployment)
|
|
tb_params="R_officeId=${OFFICE_ID}"
|
|
curl "${CURL_OPTS[@]}" "${BASE_URL}/runreports/Trial%20Balance?${tb_params}&output-type=json" 2>/dev/null > "${REPORT_FILE}.trialbalance" || true
|
|
|
|
# 4) Combined snapshot (for hash and audit)
|
|
jq -n \
|
|
--arg ts "$(date -u -Iseconds)" \
|
|
--argjson oid "$OFFICE_ID" \
|
|
--arg op "${OPERATOR_ID:-manual}" \
|
|
--slurpfile ofc "${REPORT_FILE}.offices" \
|
|
--slurpfile gl "${REPORT_FILE}.gl" \
|
|
'{ timestamp: $ts, officeId: $oid, operator: $op, offices: ($ofc[0] // []), glRelevant: ($gl[0] // []) }' \
|
|
> "$REPORT_FILE" 2>/dev/null || echo "{\"timestamp\": \"$(date -u -Iseconds)\", \"officeId\": $OFFICE_ID}" > "$REPORT_FILE"
|
|
|
|
# 5) Hash and metadata
|
|
HASH=$(sha256sum "$REPORT_FILE" 2>/dev/null | awk '{print $1}')
|
|
echo "timestamp=$TIMESTAMP
|
|
file=$REPORT_FILE
|
|
sha256=$HASH
|
|
officeId=$OFFICE_ID" > "$META_FILE"
|
|
|
|
echo "Snapshot: $REPORT_FILE (sha256=$HASH)" >&2
|
|
echo "Meta: $META_FILE" >&2
|
|
echo "Office 20 acceptance: 1410 net Dr 5,000,000,000; 2100 net Cr 5,000,000,000 (verify in UI or trial balance)." >&2
|