diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4931e03..7a75bb6 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Simpl Résultat", - "version": "0.1.1", + "version": "0.1.2", "identifier": "com.simpl.resultat", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/hooks/useImportWizard.ts b/src/hooks/useImportWizard.ts index 06da0a5..33c5e3a 100644 --- a/src/hooks/useImportWizard.ts +++ b/src/hooks/useImportWizard.ts @@ -338,7 +338,8 @@ export function useImportWizard() { encoding, maxLines: skipLines + 5, }); - const parsed = Papa.parse(preview, { delimiter, skipEmptyLines: true }); + const preprocessed = preprocessQuotedCSV(preview); + const parsed = Papa.parse(preprocessed, { delimiter, skipEmptyLines: true }); const data = parsed.data as string[][]; const headerRow = hasHeader && data.length > skipLines ? skipLines : -1; if (headerRow >= 0 && data[headerRow]) { @@ -445,6 +446,9 @@ export function useImportWizard() { if (config.hasHeader && data.length > config.skipLines) { headers = data[config.skipLines].map((h) => h.trim()); + } else if (!config.hasHeader && headers.length === 0 && data.length > config.skipLines) { + const firstDataRow = data[config.skipLines]; + headers = firstDataRow.map((_, i) => `Col ${i}`); } for (let i = startIdx; i < data.length; i++) { diff --git a/src/services/dashboardService.ts b/src/services/dashboardService.ts index b6eb9a0..0bbc863 100644 --- a/src/services/dashboardService.ts +++ b/src/services/dashboardService.ts @@ -56,7 +56,7 @@ export async function getExpensesByCategory( ): Promise { const db = await getDb(); - const whereClauses: string[] = ["t.amount < 0"]; + const whereClauses: string[] = ["COALESCE(c.type, 'expense') = 'expense'"]; const params: unknown[] = []; let paramIndex = 1; @@ -99,7 +99,7 @@ export async function getRecentTransactions( c.name AS category_name, c.color AS category_color FROM transactions t LEFT JOIN categories c ON t.category_id = c.id - WHERE t.amount < 0 + WHERE COALESCE(c.type, 'expense') = 'expense' ORDER BY t.date DESC, t.id DESC LIMIT $1`, [limit] diff --git a/src/utils/csvAutoDetect.ts b/src/utils/csvAutoDetect.ts index d0a8896..c52761d 100644 --- a/src/utils/csvAutoDetect.ts +++ b/src/utils/csvAutoDetect.ts @@ -220,17 +220,22 @@ function detectNumericColumns(rows: string[][], colCount: number): number[] { for (let col = 0; col < colCount; col++) { let numericCount = 0; let nonEmpty = 0; + const distinctValues = new Set(); for (const row of rows) { const cell = row[col]?.trim(); if (!cell) continue; nonEmpty++; - if (!isNaN(parseFrenchAmount(cell))) { + const val = parseFrenchAmount(cell); + if (!isNaN(val)) { numericCount++; + distinctValues.add(val); } } if (nonEmpty > 0 && numericCount / nonEmpty >= 0.5) { + // Exclude constant-value columns (e.g., account numbers, transit numbers) + if (distinctValues.size <= 1 && nonEmpty > 2) continue; result.push(col); } } @@ -444,8 +449,10 @@ function isSparseComplementary( for (const row of rows) { const cellA = row[colA]?.trim(); const cellB = row[colB]?.trim(); - const hasA = cellA !== "" && cellA != null && !isNaN(parseFrenchAmount(cellA)); - const hasB = cellB !== "" && cellB != null && !isNaN(parseFrenchAmount(cellB)); + const valA = cellA ? parseFrenchAmount(cellA) : NaN; + const valB = cellB ? parseFrenchAmount(cellB) : NaN; + const hasA = !isNaN(valA) && valA !== 0; + const hasB = !isNaN(valB) && valB !== 0; if (!hasA && !hasB) continue; total++;