feat(clients, alm): add CIN/MCA verification & authorized signatories tab; refactor ALM report print and export
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Casing for client names: the name is stored exactly as the officer typed it, except that a word
|
||||
* starting with a lower-case letter has that first letter raised. Nothing else is touched.
|
||||
*
|
||||
* 'keshav Singh sisodiya' → 'Keshav Singh Sisodiya'
|
||||
* 'lincpay lTD' → 'Lincpay LTD'
|
||||
* 'Technoludium Solutions Private Limited' → unchanged
|
||||
* 'TECHNOLUDIUM SOLUTIONS' → unchanged
|
||||
*
|
||||
* Deliberately NOT full title-casing. Lower-casing the rest of each word would rewrite an entity
|
||||
* name the officer entered as it appears on the certificate — 'TECHNOLUDIUM' becoming
|
||||
* 'Technoludium', 'Ltd' becoming a forced 'LTD'. That name is matched character-for-character
|
||||
* against the PAN holder's registered name during KYC verification, so the typed spelling is the
|
||||
* thing to preserve; only an unintended lower-case first letter is corrected.
|
||||
*/
|
||||
|
||||
/** Characters after which a new word starts: 'jean-marie' → 'Jean-Marie'. */
|
||||
const SEGMENT_STARTERS = new Set([
|
||||
'-',
|
||||
"'",
|
||||
'’'
|
||||
]);
|
||||
|
||||
/**
|
||||
* Raises the first letter of each word in a single space-delimited token, leaving every other
|
||||
* character as typed.
|
||||
*/
|
||||
function capitalizeWord(word: string): string {
|
||||
let result = '';
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
const previous = i === 0 ? '' : word[i - 1];
|
||||
let startsWord = i === 0 || SEGMENT_STARTERS.has(previous);
|
||||
if (previous === "'" || previous === '’') {
|
||||
// 'o'brien' / 'd'souza' capitalise after the apostrophe, but a possessive
|
||||
// ('lincpay's') must not — only a single leading letter marks the name prefix.
|
||||
startsWord = i === 2;
|
||||
}
|
||||
result += startsWord ? word[i].toUpperCase() : word[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the casing rule above to a person or entity name.
|
||||
* Trims and collapses runs of whitespace; non-string input yields ''.
|
||||
*/
|
||||
export function toProperNameCase(value: string | null | undefined): string {
|
||||
if (typeof value !== 'string') {
|
||||
return '';
|
||||
}
|
||||
const collapsed = value.trim().replace(/\s+/g, ' ');
|
||||
if (!collapsed) {
|
||||
return '';
|
||||
}
|
||||
return collapsed.split(' ').map(capitalizeWord).join(' ');
|
||||
}
|
||||
Reference in New Issue
Block a user