#!/usr/bin/env bash # OMNL Fineract — Post GL closures for Office 20 (Samama) and Head Office (1) to lock period through a given date. # Idempotent: skips if a closure already exists for that office. Use after funding to prevent backdating. # Usage: from repo root. CLOSING_DATE=yyyy-MM-dd (default: 2026-02-24). DRY_RUN=1 to print only. # See docs/04-configuration/mifos-omnl-central-bank/OPERATING_RAILS.md set -euo pipefail REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}" DRY_RUN="${DRY_RUN:-0}" CLOSING_DATE="${CLOSING_DATE:-2026-02-24}" 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 (e.g. omnl-fineract/.env)" >&2 exit 1 fi CURL_OPTS=(-s -S -H "Fineract-Platform-TenantId: ${TENANT}" -H "Content-Type: application/json" -u "${USER}:${PASS}") # GET glclosures (response may be array or object with pageItems) closures_json=$(curl "${CURL_OPTS[@]}" "${BASE_URL}/glclosures" 2>/dev/null) has_closure_for_office() { local oid="$1" echo "$closures_json" | jq -e --argjson o "$oid" ' (if type == "array" then . else (.pageItems // .) end) | map(select(.officeId == $o or .office.id == $o)) | length > 0 ' >/dev/null 2>&1 } post_closure() { local office_id="$1" local comments="$2" local body body=$(jq -n \ --argjson officeId "$office_id" \ --arg closingDate "$CLOSING_DATE" \ --arg comments "$comments" \ --arg dateFormat "yyyy-MM-dd" \ --arg locale "en" \ '{ officeId: $officeId, closingDate: $closingDate, comments: $comments, dateFormat: $dateFormat, locale: $locale }') if [ "$DRY_RUN" = "1" ]; then echo "DRY_RUN: would POST /glclosures officeId=$office_id closingDate=$CLOSING_DATE" >&2 return 0 fi local out out=$(curl "${CURL_OPTS[@]}" -X POST -d "$body" "${BASE_URL}/glclosures" 2>/dev/null) if echo "$out" | jq -e '.resourceId // .officeId' >/dev/null 2>&1; then echo "Posted GL closure for office $office_id (date=$CLOSING_DATE)" >&2 return 0 else echo "POST /glclosures failed for office $office_id: $out" >&2 return 1 fi } for office_id in 20 1; do if has_closure_for_office "$office_id"; then echo "Skip office $office_id: closure already exists" >&2 else case "$office_id" in 20) comments="Samama Office funded; lock period through funding date" ;; 1) comments="HO closure through Samama funding date" ;; *) comments="GL closure $CLOSING_DATE" ;; esac post_closure "$office_id" "$comments" || true fi done echo "Verify: GET /glclosures?officeId=20 and GET /glclosures?officeId=1" >&2