/** * 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 { Observable, forkJoin, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { ClientsService } from 'app/clients/clients.service'; /** * Finds clients by name whatever case the officer types it in. * * The platform's name filter matches anywhere in the name but only in the exact case typed, so * "sneha" finds nobody while "Sneha" finds Ms. Sneha Iyer. Names are stored capitalised, so the term * is tried as typed, capitalised word by word, and in upper and lower case, and the results merged. * Done here rather than by changing the platform's search, which every other screen relies on. */ export function searchClientsAnyCase(clientsService: ClientsService, term: string, officeId?: any): Observable { const variants = Array.from( new Set([ term, term.toLowerCase().replace(/(^|[\s.])(\p{L})/gu, (_match, lead, letter) => lead + letter.toUpperCase()), term.toUpperCase(), term.toLowerCase() ]) ); return forkJoin( variants.map((variant) => clientsService.getFilteredClients('displayName', 'ASC', false, variant, officeId).pipe( map((response: any) => { const found = response?.pageItems || response || []; return Array.isArray(found) ? found : []; }), catchError(() => of([])) ) ) ).pipe( map((lists: any[][]) => { const byId = new Map(); for (const client of lists.flat()) { byId.set(client.id, client); } return Array.from(byId.values()).sort((a, b) => String(a.displayName).localeCompare(String(b.displayName))); }) ); }