From dd7a7fa796e47af70082a03896787da8928e30c3 Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins <matiss@mja.lv> Date: Sat, 2 Sep 2023 18:03:38 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20(imports)=20ability=20to=20toggl?= =?UTF-8?q?e=20on/off=20OFX=20import=20fallback=20payee=20(#1631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/modals/ImportTransactions.js | 38 ++++++++++++++++++- .../src/server/accounts/parse-file.ts | 23 +++++++---- packages/loot-core/src/types/prefs.d.ts | 1 + upcoming-release-notes/1631.md | 6 +++ 4 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 upcoming-release-notes/1631.md diff --git a/packages/desktop-client/src/components/modals/ImportTransactions.js b/packages/desktop-client/src/components/modals/ImportTransactions.js index 760650c10..e301c4503 100644 --- a/packages/desktop-client/src/components/modals/ImportTransactions.js +++ b/packages/desktop-client/src/components/modals/ImportTransactions.js @@ -577,6 +577,9 @@ export default function ImportTransactions({ modalProps, options }) { let [hasHeaderRow, setHasHeaderRow] = useState( prefs[`csv-has-header-${accountId}`] ?? true, ); + let [fallbackMissingPayeeToMemo, setFallbackMissingPayeeToMemo] = useState( + prefs[`ofx-fallback-missing-payee-${accountId}`] ?? true, + ); let [parseDateFormat, setParseDateFormat] = useState(null); @@ -645,10 +648,14 @@ export default function ImportTransactions({ modalProps, options }) { } useEffect(() => { + const fileType = getFileType(options.filename); + parse( options.filename, - getFileType(options.filename) === 'csv' + fileType === 'csv' ? { delimiter: csvDelimiter, hasHeaderRow } + : fileType === 'ofx' + ? { fallbackMissingPayeeToMemo } : null, ); }, [parseTransactions, options.filename]); @@ -693,9 +700,15 @@ export default function ImportTransactions({ modalProps, options }) { ], }); + const fileType = getFileType(res[0]); + parse( res[0], - getFileType(res[0]) === 'csv' ? { delimiter: csvDelimiter } : null, + fileType === 'csv' + ? { delimiter: csvDelimiter } + : fileType === 'ofx' + ? { fallbackMissingPayeeToMemo } + : null, ); } @@ -754,6 +767,12 @@ export default function ImportTransactions({ modalProps, options }) { savePrefs({ [key]: parseDateFormat }); } + if (filetype === 'ofx') { + savePrefs({ + [`ofx-fallback-missing-payee-${accountId}`]: fallbackMissingPayeeToMemo, + }); + } + if (filetype === 'csv') { savePrefs({ [`csv-mappings-${accountId}`]: JSON.stringify(fieldMappings), @@ -881,6 +900,21 @@ export default function ImportTransactions({ modalProps, options }) { </View> )} + {filetype === 'ofx' && ( + <CheckboxOption + id="form_fallback_missing_payee" + checked={fallbackMissingPayeeToMemo} + onChange={() => { + setFallbackMissingPayeeToMemo(state => !state); + parse(filename, { + fallbackMissingPayeeToMemo: !fallbackMissingPayeeToMemo, + }); + }} + > + Use Memo as a fallback for empty Payees + </CheckboxOption> + )} + {/*Import Options */} {(filetype === 'qif' || filetype === 'csv') && ( <View style={{ marginTop: 25 }}> diff --git a/packages/loot-core/src/server/accounts/parse-file.ts b/packages/loot-core/src/server/accounts/parse-file.ts index 16434a8a2..4a3a2d1bc 100644 --- a/packages/loot-core/src/server/accounts/parse-file.ts +++ b/packages/loot-core/src/server/accounts/parse-file.ts @@ -14,7 +14,11 @@ export type ParseFileResult = { export async function parseFile( filepath, - options?: { delimiter?: string; hasHeaderRow: boolean }, + options?: { + delimiter?: string; + hasHeaderRow: boolean; + fallbackMissingPayeeToMemo?: boolean; + }, ): Promise<ParseFileResult> { let errors = Array<ParseError>(); let m = filepath.match(/\.[^.]*$/); @@ -30,7 +34,7 @@ export async function parseFile( return parseCSV(filepath, options); case '.ofx': case '.qfx': - return parseOFX(filepath); + return parseOFX(filepath, options); default: } } @@ -101,7 +105,12 @@ async function parseQIF(filepath): Promise<ParseFileResult> { }; } -async function parseOFX(filepath): Promise<ParseFileResult> { +async function parseOFX( + filepath, + options: { fallbackMissingPayeeToMemo?: boolean } = { + fallbackMissingPayeeToMemo: true, + }, +): Promise<ParseFileResult> { let { getOFXTransactions, initModule } = await import( /* webpackChunkName: 'xfo' */ 'node-libofx' ); @@ -123,7 +132,7 @@ async function parseOFX(filepath): Promise<ParseFileResult> { // Banks don't always implement the OFX standard properly // If no payee is available try and fallback to memo - let useName = data.some(trans => trans.name != null && trans.name !== ''); + let useMemoFallback = options.fallbackMissingPayeeToMemo; return { errors, @@ -131,9 +140,9 @@ async function parseOFX(filepath): Promise<ParseFileResult> { amount: trans.amount, imported_id: trans.fi_id, date: trans.date ? dayFromDate(new Date(trans.date * 1000)) : null, - payee_name: useName ? trans.name : trans.memo, - imported_payee: useName ? trans.name : trans.memo, - notes: useName ? trans.memo || null : null, //memo used for payee + payee_name: trans.name || (useMemoFallback ? trans.memo : null), + imported_payee: trans.name || (useMemoFallback ? trans.memo : null), + notes: !!trans.name || !useMemoFallback ? trans.memo || null : null, //memo used for payee })), }; } diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts index ece250533..18c8f52d1 100644 --- a/packages/loot-core/src/types/prefs.d.ts +++ b/packages/loot-core/src/types/prefs.d.ts @@ -34,6 +34,7 @@ export type LocalPrefs = Partial< [key: `csv-mappings-${string}`]: string; [key: `csv-delimiter-${string}`]: ',' | ';' | '\t'; [key: `csv-has-header-${string}`]: boolean; + [key: `ofx-fallback-missing-payee-${string}`]: boolean; [key: `flip-amount-${string}-${'csv' | 'qif'}`]: boolean; 'flags.updateNotificationShownForVersion': string; id: string; diff --git a/upcoming-release-notes/1631.md b/upcoming-release-notes/1631.md new file mode 100644 index 000000000..3de4609c9 --- /dev/null +++ b/upcoming-release-notes/1631.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [MatissJanis] +--- + +Imports: ability to toggle on/off the fallback logic for payee field (OFX imports) -- GitLab