/** * 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, of } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; /** HTTP service for the Cashier menu features. */ @Injectable({ providedIn: 'root' }) export class CashierService { private http = inject(HttpClient); // ── Active denominations ── getActiveDenominations(): Observable { return this.http.get('/denominationmaster/active'); } // ── Cash Exchange ── createCashExchange(data: any): Observable { return this.http.post('/cashexchange', data); } getCashExchanges(offset = 0, limit = 20): Observable { const params = new HttpParams().set('offset', offset).set('limit', limit); return this.http.get('/cashexchange', { params }); } getCashExchange(id: number): Observable { return this.http.get(`/cashexchange/${id}`); } reverseCashExchange(id: number, reason: string): Observable { return this.http.post(`/cashexchange/${id}/reverse`, { reason }); } // ── Tellers / Cashiers ── getTellers(): Observable { return this.http.get('/tellers'); } getAllCashiers(): Observable { return this.http.get('/cashiers'); } getCashiersForTeller(tellerId: number): Observable { return this.http.get(`/tellers/${tellerId}/cashiers`); } // ── Cash Transfer ── createCashTransfer(data: any): Observable { return this.http.post('/cashtransfer', data); } getCashTransfers(offset = 0, limit = 20): Observable { const params = new HttpParams().set('offset', offset).set('limit', limit); return this.http.get('/cashtransfer', { params }); } getCashTransferById(id: number): Observable { return this.http.get(`/cashtransfer/${id}`); } reverseCashTransfer(id: number, reason: string): Observable { return this.http.post(`/cashtransfer/${id}/reverse`, { reason }); } // ── Cash Settlement ── createCashSettlement(data: any): Observable { return this.http.post('/cashsettlement', data); } getCashSettlements(offset = 0, limit = 20): Observable { const params = new HttpParams().set('offset', offset).set('limit', limit); return this.http.get('/cashsettlement', { params }); } getCashSettlementById(id: number): Observable { return this.http.get(`/cashsettlement/${id}`); } reverseCashSettlement(id: number, reason: string): Observable { return this.http.post(`/cashsettlement/${id}/reverse`, { reason }); } // ── Inter-cashier Transfer ── createInterCashierTransfer(data: any): Observable { return this.http.post('/cashintercashier', data); } getInterCashierTransfers(offset = 0, limit = 20): Observable { const params = new HttpParams().set('offset', offset).set('limit', limit); return this.http.get('/cashintercashier', { params }); } getInterCashierById(id: number): Observable { return this.http.get(`/cashintercashier/${id}`); } reverseInterCashierTransfer(id: number, reason: string): Observable { return this.http.post(`/cashintercashier/${id}/reverse`, { reason }); } // ── Reconciliation ── createReconciliation(data: any): Observable { return this.http.post('/cashreconciliation', data); } getReconciliations(): Observable { return this.http.get('/cashreconciliation'); } getReconciliationById(id: number): Observable { return this.http.get(`/cashreconciliation/${id}`); } getExpectedBalance(cashierId: number, asOfDate?: string): Observable { let params = new HttpParams().set('cashierId', String(cashierId)); if (asOfDate) params = params.set('asOfDate', asOfDate); return this.http.get('/cashreconciliation/expected', { params }); } // ── Reports ── closingCashReport(date: string): Observable { const params = new HttpParams().set('date', date); return this.http.get('/cashreports/closing', { params }); } excessTransactionReport(threshold: number, fromDate?: string, toDate?: string): Observable { let params = new HttpParams().set('threshold', String(threshold)); if (fromDate) params = params.set('fromDate', fromDate); if (toDate) params = params.set('toDate', toDate); return this.http.get('/cashreports/excess', { params }); } cashierPositionReport(cashierId?: number, asOfDate?: string): Observable { let params = new HttpParams(); if (cashierId) params = params.set('cashierId', String(cashierId)); if (asOfDate) params = params.set('asOfDate', asOfDate); return this.http.get('/cashreports/cashier-position', { params }); } getCashierPositionForMe(asOfDate?: string): Observable { let params = new HttpParams(); if (asOfDate) params = params.set('asOfDate', asOfDate); return this.http.get('/cashreports/cashier-position/me', { params }); } getCashierDayStatus(): Observable { return this.http.get('/cashreports/cashier-day-status'); } getGlEntries(date: string, cashierId?: number, tellerId?: number, offset = 0, limit = 20): Observable { let params = new HttpParams().set('date', date).set('offset', String(offset)).set('limit', String(limit)); if (cashierId) params = params.set('cashierId', String(cashierId)); if (tellerId) params = params.set('tellerId', String(tellerId)); return this.http.get('/cashreports/gl-entries', { params }); } checkSettlement(cashierId: number, date: string): Observable { const params = new HttpParams().set('cashierId', String(cashierId)).set('date', date); return this.http.get('/cashsettlement/check', { params }); } checkReconciliation(cashierId: number, date: string): Observable { const params = new HttpParams().set('cashierId', String(cashierId)).set('date', date); return this.http.get('/cashreconciliation/check', { params }); } getCashierMorningBalance(cashierId: number, date: string): Observable { const params = new HttpParams().set('cashierId', String(cashierId)).set('date', date); return this.http.get('/cashreports/cashier-morning', { params }); } getExpectedBalanceForMe(asOfDate?: string): Observable { let params = new HttpParams(); if (asOfDate) params = params.set('asOfDate', asOfDate); return this.http.get('/cashreconciliation/expected/me', { params }); } // ── Current cashier identity ── // Returns cashierId + cashierName for the logged-in user, or null if not a cashier. getCurrentCashierInfo(): Observable<{ cashierId: number; cashierName: string } | null> { return this.getCashierPositionForMe().pipe( map((pos: any) => (pos?.cashierId ? { cashierId: pos.cashierId, cashierName: pos.cashierName ?? '' } : null)), catchError(() => of(null)) ); } // ── Payment Types ── getPaymentTypes(): Observable { return this.http.get('/paymenttypes'); } // ── Share Collection ── getShareAccountForCollection(accountId: string): Observable { return this.http.get(`/accounts/share/${accountId}`); } collectSharePayment(data: any): Observable { return this.http.post('/cashier/sharecollection', data); } getShareCollectionStatus(shareAccountId: number): Observable { return this.http.get(`/cashier/sharecollection/${shareAccountId}`); } }