62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { restoreFinancialToolsSnapshot } from './financial-calculators.ts';
|
|
|
|
const amount = (value: unknown): string | null => {
|
|
if (typeof value !== 'string') return null;
|
|
const match = /^(\d+)(?:\.(\d+))?$/.exec(value.trim());
|
|
if (!match) return null;
|
|
return (
|
|
match[1].replace(/^0+(?=\d)/, '') +
|
|
'.' +
|
|
(match[2] ?? '').replace(/0+$/, '')
|
|
);
|
|
};
|
|
export const samePlanningAmount = (a: string, b: string) =>
|
|
(!a && !b) || (amount(a) !== null && amount(a) === amount(b));
|
|
|
|
/** Compare named origins without adopting either one or turning unknown into zero. */
|
|
export function fundingDifferences(
|
|
source: { total: string; secured: string },
|
|
calculator: { total: string; secured: string },
|
|
) {
|
|
return (['total', 'secured'] as const).filter(
|
|
(key) => !samePlanningAmount(source[key], calculator[key]),
|
|
);
|
|
}
|
|
|
|
/** Unknown calculator inputs may reuse the canonical source; a known divergent value requires a decision. */
|
|
export function canLinkFundingSource(
|
|
source: { total: string; secured: string } | undefined,
|
|
stored: { total: string; secured: string } | undefined,
|
|
): boolean {
|
|
return Boolean(
|
|
source &&
|
|
(!stored ||
|
|
(['total', 'secured'] as const).every(
|
|
(key) =>
|
|
!stored[key].trim() ||
|
|
samePlanningAmount(source[key], stored[key]),
|
|
)),
|
|
);
|
|
}
|
|
export function draftFundingDifferences(draft: Record<string, unknown>) {
|
|
const snapshot = restoreFinancialToolsSnapshot(
|
|
typeof draft.financial_tools_snapshot === 'string'
|
|
? draft.financial_tools_snapshot
|
|
: undefined,
|
|
);
|
|
if (!snapshot) return [];
|
|
return fundingDifferences(
|
|
{
|
|
total:
|
|
typeof draft.total_investment === 'string'
|
|
? draft.total_investment
|
|
: '',
|
|
secured:
|
|
typeof draft.secured_amount === 'string'
|
|
? draft.secured_amount
|
|
: '',
|
|
},
|
|
snapshot.funding,
|
|
);
|
|
}
|