Full import pipeline: Rust backend (6 Tauri commands for folder scanning, file reading, encoding detection, hashing, folder picker), TypeScript services (DB, import sources, transactions, auto-categorization, user preferences), utility parsers (French amounts, multi-format dates), 12 React components forming a 7-step wizard (source list, config, column mapping, preview, duplicate detection, import, report), and i18n support (FR/EN, ~60 keys each). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
26 lines
920 B
TypeScript
26 lines
920 B
TypeScript
/**
|
|
* Parse a French-formatted amount string to a number.
|
|
* Handles formats like: 1.234,56 / 1234,56 / -1 234.56 / 1 234,56
|
|
*/
|
|
export function parseFrenchAmount(raw: string): number {
|
|
if (!raw || typeof raw !== "string") return NaN;
|
|
|
|
let cleaned = raw.trim();
|
|
|
|
// Remove currency symbols and whitespace
|
|
cleaned = cleaned.replace(/[€$£\s\u00A0]/g, "");
|
|
|
|
// Detect if comma is decimal separator (French style)
|
|
// Pattern: digits followed by comma followed by exactly 1-2 digits at end
|
|
const frenchPattern = /,\d{1,2}$/;
|
|
if (frenchPattern.test(cleaned)) {
|
|
// French format: remove dots (thousand sep), replace comma with dot (decimal)
|
|
cleaned = cleaned.replace(/\./g, "").replace(",", ".");
|
|
} else {
|
|
// English format or no decimal: remove commas (thousand sep)
|
|
cleaned = cleaned.replace(/,/g, "");
|
|
}
|
|
|
|
const result = parseFloat(cleaned);
|
|
return isNaN(result) ? NaN : result;
|
|
}
|