/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { Injectable, inject } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; export interface RbiFeedItem { id: number; title: string; link: string; description: string; pubDate: any; // Fineract returns [year,month,day,hour,min,sec] array category: string; fetchedOn?: any; openProjectWpId?: number; // OpenProject work package ID openProjectWpStatus?: string; openProjectWpProgress?: number; } @Injectable({ providedIn: 'root' }) export class RbiCircularsService { private http = inject(HttpClient); getAll(category?: string): Observable { let params = new HttpParams(); if (category) { params = params.set('category', category); } return this.http.get('/rbi-feeds', { params }); } getById(id: number): Observable { return this.http.get(`/rbi-feeds/${id}`); } triggerFetch(): Observable { return this.http.post('/rbi-feeds/fetch', {}); } /** * Members and share capital per share type for one financial year, with the year before alongside. * * @param financialYear the year the FY opens in — 2025 means FY 2025-26. */ getShareCapitalReturn(financialYear: number): Observable { return this.http.get('/shareproducts/capital-return', { params: new HttpParams().set('financialYear', String(financialYear)) }); } /** Financial years that actually have share activity, newest first, for the year picker. */ getShareCapitalReturnYears(): Observable { return this.http.get('/shareproducts/capital-return/financial-years'); } /** * Form 1 — CRR, computed live from the ledger for the fortnight the reporting date falls in. * * The DTL base and the balances maintained are read as at different dates: the base lags by 45 * days (snapped back to a reporting Friday), the holdings are as at the reporting date itself. * The response's `basis` block states both, so the lag is auditable rather than implied. * * @param reportingDate yyyy-MM-dd. Defaults to the current business date on the backend. * @param officeId Optional — scopes every figure to one office. */ getForm1(reportingDate?: string, baseDate?: string, officeId?: number): Observable { let params = new HttpParams(); if (reportingDate) { params = params.set('reportingDate', reportingDate); } // The base date can be given outright. The 45-day lag lands where it lands, and a bank reading // an earlier fortnight — or correcting a filing — needs to name the date the base is struck at // rather than work backwards from it. Left blank it is derived from the lag as before. if (baseDate) { params = params.set('baseDate', baseDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return this.http.get('/rbireservereturn/form1', { params }); } /** * Form 9 — SLR, computed live on the month-end position. Any date within a month resolves to that * month's end, since the return reports the position at close. */ getForm9(reportingDate?: string, officeId?: number): Observable { let params = new HttpParams(); if (reportingDate) { params = params.set('reportingDate', reportingDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return this.http.get('/rbireservereturn/form9', { params }); } /** * Form 9 in the shape it is filed — the statutory statement of compliance with section 24. * * A different statement from `getForm9`, not a reformatting: three dated columns rather than one, * and the ratio charged on the last Friday of the second preceding fortnight rather than on the * month end itself. */ getForm9Statutory(reportingDate?: string, officeId?: number): Observable { let params = new HttpParams(); if (reportingDate) { params = params.set('reportingDate', reportingDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return this.http.get('/rbireservereturn/form9-statutory', { params }); } /** * Form IX — the Return on Assets and Liabilities a co-operative bank files monthly, code R408. * * A different return from `getForm9` despite the name: that one reports the SLR ratio, this one * reports the whole balance sheet. Every figure comes back in rupees thousands, with the rupee * figure alongside it so a line can still be reconciled against the ledger. * * @param reportingDate yyyy-MM-dd — any date in the month; the return reports that month's end. */ getForm9Return(reportingDate?: string, officeId?: number): Observable { let params = new HttpParams(); if (reportingDate) { params = params.set('reportingDate', reportingDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return this.http.get('/rbireservereturn/form9-return', { params }); } /** * OSS 1 — Return on Assets and Liabilities, computed live from the ledger. * * Every figure is a closing balance as at the quarter end; the bank's own particulars come from * the institution profile. Any date inside a quarter resolves to that quarter, so a caller never * has to know which day a quarter ends on. * * @param quarterEndDate yyyy-MM-dd — any date in the quarter. Defaults to the business date. * @param officeId Optional — scopes every figure to one office. */ getOss1(quarterEndDate?: string, officeId?: number): Observable { return this.http.get('/ossreturn/oss1', { params: this.ossParams(quarterEndDate, officeId) }); } /** * OSS 2 — Return on Earnings, computed live from the ledger. * * Earnings lines report the movement over the quarter rather than a closing balance, so the same * accounts read as balances would carry forward every earlier quarter's income as well. */ getOss2(quarterEndDate?: string, officeId?: number): Observable { return this.http.get('/ossreturn/oss2', { params: this.ossParams(quarterEndDate, officeId) }); } /** * Form 1 as a co-operative bank files it — Banking Regulation (Co-operative Societies) Rules * 1966, Rule 5, sections 18(1) and 24(3). * * A different statement from `getForm1`, not a reformatting: three columns rather than one, both * ratios settled on the same liabilities, and those liabilities taken from the last Friday of the * second preceding fortnight rather than a 45-day lag. */ getForm1Statutory( reportingDate?: string, firstColumnDate?: string, secondColumnDate?: string, officeId?: number ): Observable { let params = new HttpParams(); if (reportingDate) { params = params.set('reportingDate', reportingDate); } // Both fortnight closes can be given outright. A bank filing August wants 15/08 and 31/08 on // the face of the form whatever today is, and one date cannot produce a pair that spans a month // boundary or skips a fortnight — which a late or corrected filing needs. if (firstColumnDate) { params = params.set('firstColumnDate', firstColumnDate); } if (secondColumnDate) { params = params.set('secondColumnDate', secondColumnDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return this.http.get('/rbireservereturn/form1-statutory', { params }); } // ── Saved returns ── /** * Returns saved earlier, newest first. A saved return is served from the snapshot taken when it * was saved, never recomputed — a backdated entry or a changed mapping would otherwise produce a * different statement from the one that was reviewed. */ getSavedReturns(formCode?: string): Observable { let params = new HttpParams(); if (formCode) { params = params.set('formCode', formCode); } return this.http.get('/rbiformafiling', { params }); } /** One saved return, with the stored snapshot, so the screen renders what was saved. */ getSavedReturn(filingId: number): Observable { return this.http.get(`/rbiformafiling/${filingId}`); } /** Keeps the return currently on screen. Re-saving the same form and date replaces it. */ saveReturn(formCode: string, reportingDate: string, report: any, remarks?: string): Observable { return this.http.post('/rbiformafiling', { formCode, reportingDate, report, remarks, locale: 'en', dateFormat: 'yyyy-MM-dd' }); } /** Moves a saved return along its filing lifecycle; the snapshot itself is untouched. */ updateSavedReturnStatus(filingId: number, status: string, remarks?: string): Observable { return this.http.post(`/rbiformafiling/${filingId}/status`, { status, remarks }); } deleteSavedReturn(filingId: number): Observable { return this.http.delete(`/rbiformafiling/${filingId}`); } private ossParams(quarterEndDate?: string, officeId?: number): HttpParams { let params = new HttpParams(); if (quarterEndDate) { params = params.set('quarterEndDate', quarterEndDate); } if (officeId != null) { params = params.set('officeId', String(officeId)); } return params; } }