actualbudget / import-ynab5

A tool for importing YNAB5 (nYNAB) data into Actual
26 stars 14 forks source link

Failing to import transactions that were created via YNAB API #8

Closed bzupnick closed 2 years ago

bzupnick commented 2 years ago

I'm getting the following error:

$ node index.js YourBudget.json
Importing Accounts...
Importing Categories...
Importing Payees...
Importing Transactions...
Error: [API Error] Can't convert to integer: -3506.9
    at /Users/bzupnick/Desktop/import-ynab5/node_modules/@actual-app/api/connection.js:26:13
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async /Users/bzupnick/Desktop/import-ynab5/importer.js:242:7
    at async Promise.all (index 3)
    at async importTransactions (/Users/bzupnick/Desktop/import-ynab5/importer.js:186:3)
    at async doImport (/Users/bzupnick/Desktop/import-ynab5/importer.js:306:3)
    at async /Users/bzupnick/Desktop/import-ynab5/node_modules/@actual-app/api/connection.js:113:5
    at async _run (/Users/bzupnick/Desktop/import-ynab5/node_modules/@actual-app/api/connection.js:91:11)
    at async run (/Users/bzupnick/Desktop/import-ynab5/index.js:6:3)

When I open up YourBudget.json, though, I'm not seeing -3506.9. I am seeing:

 {"id":"cef8382e-c42d-4241-af37-f1909175fb7b","date":"2021-11-05","amount":-35069,"memo":"Market Close","cleared":"cleared","approved":true,"flag_color":null,"account_id":"58543bed-6c70-4074-97ab-1a1c35b17a7d","payee_id":"4c48f4b2-b423-4aac-a898-5a84b3fd94b4","category_id":null,"transfer_account_id":null,"transfer_transaction_id":null,"matched_transaction_id":null,"import_id":null,"deleted":false},

which is the closest I can see to being the "culprit" transaction.

The weird thing is that if, in YNAB, I go to that account on that day I only see a transaction for $35.07 🤔

image

So I tried changing 35069 to 35070 in YourBudget.json and reran it. I got a similar error but a different number:

Error: [API Error] Can't convert to integer: 184.8

and that's just from the next transaction, as you can see in the screenshot above, that in the GUI says $1.85.

So obviously I fixed that one number again, ran it to confirm, and the third number tripped up. We've found the pattern.

Note that this account is populated twice daily automatically by a Google script I wrote up that creates a YNAB transaction via it's API. Unfortunately I don't have access to that script anymore since Google decided to not open that page:

image

But I wonder if the issue is that maybe my script is sending numbers like $5.345 or something? That's getting rounded in the GUI, not in the backend, and is screwing with the script here? Since I don't have access to my spreadsheet macros it's hard to debug and give it exactly what's being sent. Sorry!

bzupnick commented 2 years ago

update: After deleting all the transactions for this account (g/.*58543bed-6c70-4074-97ab-1a1c35b17a7d.*/d) and running the script again, it worked!

RDslva commented 2 years ago

I'm seeing a similar error, but I have not created transactions via the YNAB API ever.

@bzupnick , was your solution to delete all transactions from the offending account in the YNAB JSON file, and re-import?

bzupnick commented 2 years ago

Weird. I wonder why it happens, though. What's your offending error and corresponding line in the json file?

And yeah, I deleted all the transactions from the account and re-imported. It was a "tracking" account so it didn't effect my budget at all

RDslva commented 2 years ago

That's strange, that happened with a tracking account for me as well, an investment account to be precise. I ended up actually having 2 accounts that were causing issues, both needed to be deleted for the import to go smoothly.

Ended up downloading VS code and manually deleting the offending account lines from the JSON via regex. ^.account-guid-here., for those curious.

skrobul commented 2 years ago

So I bumped onto the same bug while trying to import my transactions. The example offending transaction is:

  {"id":"790438ac-0d28-4031-9ba9-b3e349475356","date":"2021-08-03","amount":-4059,"memo":"Groceries PLN 21.58","cleared":"reconciled","approved":true,"flag_color":"green","account_id":"3e4e34a2-82d1-4f34-aa44-a10d75a188c1","payee_id":"ada7a8b8-e47b-4143-a9fb-9a407d5eec92","category_id":"29ae8dc4-2534-4a9a-b1cd-25aa07fd70b9","transfer_account_id":null,"transfer_transaction_id":null,"matched_transaction_id":null,"import_id":"YNAB:-4059:2021-08-03:1","deleted":false} 

This is what I have tried so far with no results:

So I looked into the code and it's this function throwing the error:

function ct(e, t) {
    if (void 0 === e) throw new Error("Query value cannot be undefined");
    if (null === e) return "boolean" === t ? 0 : null;
    switch (t) {
        case "date":
            if (e instanceof Date) return V($e(e));
            if (null == e.match(/^\d{4}-\d{2}-\d{2}$/) || e.date < "2000-01-01") throw new Error("Invalid date: " + e);
            return V(e);
        case "date-month":
            return V(e.slice(0, 7));
        case "date-year":
            return V(e.slice(0, 4));
        case "boolean":
            return e ? 1 : 0;
        case "id":
            if ("string" != typeof e && null !== e) throw new Error("Invalid id, must be string: " + e);
            return e;
        case "integer":
            if ("number" == typeof e && (0 | e) === e) return e;
            throw new Error("Can't convert to integer: " + JSON.stringify(e));
        case "json":
            return JSON.stringify(e)
    }
    return e
}

specifically, it's the (0 | e) === e) condition that is not matched because -1405.9 | 0 gives -1405. So it looks like those are just amounts that have not been rounded properly. In my case, these have also been created by a script (like in @bzupnick's case). I will figure out some script to fix those to be round numbers.

rienafairefr commented 2 years ago

Same bug here. All my transactions are written through the YNAB API :-)

bzupnick commented 2 years ago

here's a PR that fixes this problem

bzupnick commented 2 years ago

fix got merged