50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
/**
|
|
* 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<any[]> {
|
|
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<number, any>();
|
|
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)));
|
|
})
|
|
);
|
|
}
|