From d2185909c37c26026f2621125adf40e3bfe832fc Mon Sep 17 00:00:00 2001
From: Jed Fox <git@jedfox.com>
Date: Tue, 2 May 2023 17:48:01 -0400
Subject: [PATCH] Add support for credit card OFX files (#987)

---
 .../loot-core/src/mocks/files/credit-card.ofx | 11 +++++++
 .../__snapshots__/parse-file.test.ts.snap     | 29 +++++++++++++++++++
 .../src/server/accounts/parse-file.test.ts    | 12 ++++++++
 .../src/server/accounts/parse-file.ts         |  5 +++-
 upcoming-release-notes/987.md                 |  6 ++++
 5 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 packages/loot-core/src/mocks/files/credit-card.ofx
 create mode 100644 upcoming-release-notes/987.md

diff --git a/packages/loot-core/src/mocks/files/credit-card.ofx b/packages/loot-core/src/mocks/files/credit-card.ofx
new file mode 100644
index 000000000..60a820b5b
--- /dev/null
+++ b/packages/loot-core/src/mocks/files/credit-card.ofx
@@ -0,0 +1,11 @@
+OFXHEADER:100
+DATA:OFXSGML
+VERSION:102
+SECURITY:NONE
+ENCODING:USASCII
+CHARSET:1252
+COMPRESSION:NONE
+OLDFILEUID:NONE
+NEWFILEUID:NONE
+
+<OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0<SEVERITY>INFO</STATUS><DTSERVER>20230407120000[0:GMT]<LANGUAGE>ENG<FI><ORG>Apple Card<FID>12345</FI></SONRS></SIGNONMSGSRSV1><CREDITCARDMSGSRSV1><CCSTMTTRNRS><TRNUID>0<STATUS><CODE>0<SEVERITY>INFO</STATUS><CCSTMTRS><CURDEF>USD<CCACCTFROM><ACCTID>7dc6a2fd-2124-457a-a14</CCACCTFROM><BANKTRANLIST><DTSTART>20230301120000[0:GMT]<DTEND>20230331120000[0:GMT]<STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20230330120000[0:GMT]<TRNAMT>-6.00<FITID>57f91dca-0460-4692-be90-84165b7002<NAME>LOUISIANA STATE MUSEUM751 PLACE JOHN PAUL NEW ORLEANS 70116-3205LA USA</STMTTRN></BANKTRANLIST><LEDGERBAL><BALAMT>-9654.01<DTASOF>20230331120000[0:GMT]</LEDGERBAL><AVAILBAL><BALAMT>1173.02<DTASOF>20230331120000[0:GMT]</AVAILBAL></CCSTMTRS></CCSTMTTRNRS></CREDITCARDMSGSRSV1></OFX>
diff --git a/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap b/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
index 5ada01f60..308b06b94 100644
--- a/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
+++ b/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
@@ -29,6 +29,35 @@ Array [
 ]
 `;
 
+exports[`File import ofx import works (credit card) 1`] = `
+Array [
+  Object {
+    "acct": "one",
+    "amount": -600,
+    "category": null,
+    "cleared": 1,
+    "date": 20230330,
+    "description": "id2",
+    "error": null,
+    "financial_id": "57f91dca-0460-4692-be90-84165b7002",
+    "id": "id3",
+    "imported_description": "LOUISIANA STATE MUSEUM751 PLACE JOHN PAUL NEW ORLEANS 70116-3205LA USA",
+    "isChild": 0,
+    "isParent": 0,
+    "location": null,
+    "notes": null,
+    "parent_id": null,
+    "pending": 0,
+    "schedule": null,
+    "sort_order": 123456789,
+    "starting_balance_flag": 0,
+    "tombstone": 0,
+    "transferred_id": null,
+    "type": null,
+  },
+]
+`;
+
 exports[`File import ofx import works 1`] = `
 Array [
   Object {
diff --git a/packages/loot-core/src/server/accounts/parse-file.test.ts b/packages/loot-core/src/server/accounts/parse-file.test.ts
index a44754a16..b42076213 100644
--- a/packages/loot-core/src/server/accounts/parse-file.test.ts
+++ b/packages/loot-core/src/server/accounts/parse-file.test.ts
@@ -81,6 +81,18 @@ describe('File import', () => {
     expect(await getTransactions('one')).toMatchSnapshot();
   }, 45000);
 
+  test('ofx import works (credit card)', async () => {
+    prefs.loadPrefs();
+    await db.insertAccount({ id: 'one', name: 'one' });
+
+    let { errors } = await importFileWithRealTime(
+      'one',
+      __dirname + '/../../mocks/files/credit-card.ofx',
+    );
+    expect(errors.length).toBe(0);
+    expect(await getTransactions('one')).toMatchSnapshot();
+  }, 45000);
+
   test('qfx import works', async () => {
     prefs.loadPrefs();
     await db.insertAccount({ id: 'one', name: 'one' });
diff --git a/packages/loot-core/src/server/accounts/parse-file.ts b/packages/loot-core/src/server/accounts/parse-file.ts
index 87500ccec..9d037d40f 100644
--- a/packages/loot-core/src/server/accounts/parse-file.ts
+++ b/packages/loot-core/src/server/accounts/parse-file.ts
@@ -215,7 +215,10 @@ async function parseOfxJavascript(filepath) {
   }
   // .STMTTRN may be a list or a single object.
   const transactions = [
-    data.body.OFX.BANKMSGSRSV1.STMTTRNRS.STMTRS.BANKTRANLIST.STMTTRN,
+    (
+      data.body.OFX.BANKMSGSRSV1?.STMTTRNRS.STMTRS ||
+      data.body.OFX.CREDITCARDMSGSRSV1?.CCSTMTTRNRS.CCSTMTRS
+    ).BANKTRANLIST.STMTTRN,
   ].flat();
   return {
     errors,
diff --git a/upcoming-release-notes/987.md b/upcoming-release-notes/987.md
new file mode 100644
index 000000000..d262331d4
--- /dev/null
+++ b/upcoming-release-notes/987.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [j-f1]
+---
+
+Add support for credit card OFX files
-- 
GitLab