gitviola / ynab-bank-importer

💰 Pull transactions from your bank and import them to YNAB automatically.
https://ynab.com/referral/?ref=C-_IP8eD8dWYfEec&utm_source=customer_referral
MIT License
133 stars 20 forks source link

`entry_date': undefined method `month' #52

Closed yuvke closed 5 years ago

yuvke commented 5 years ago

Hi,

I'm trying to run the script locally on Mac (directly in terminal, I have ruby installed). I'm getting the following error:

/Library/Ruby/Gems/2.3.0/gems/cmxl-0.2.2/lib/cmxl/fields/transaction.rb:63:in `entry_date': undefined method `month' for "190229":String (NoMethodError)
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/dumper/fints.rb:34:in `date'
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/dumper.rb:19:in `to_ynab_transaction'
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/dumper/fints.rb:24:in `block in fetch_transactions'
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/dumper/fints.rb:24:in `map'
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/dumper/fints.rb:24:in `fetch_transactions'
        from /Users/yuvalshaked/yuvdev/ynab-bank-importer/lib/account.rb:18:in `fetch_transactions'
        from run.rb:11:in `block in <main>'
        from run.rb:9:in `map'
        from run.rb:9:in `<main>'

My config is:

ynab:
  access_token: "xxxxxxxxxxxxxxxxxxx919237484383ebe0" # Your YNAB access token
  budget_id: "xxxxxxxx-xxxx-xxxxx-xxxxxx-8c90ac86a0e0" # the first hash in the url when you open your budget
  cash_account_id: "xxxxxxxx-xxxxx-xxxxx-xxxxx-57c2e77ecdc9" # if set that it creates transactions
                            # to your cash account if withdrawal is detected
accounts:
  - dumper: :fints
    iban: "DE3210050000xxxxxxxxxxxx" # iban of your account
    ynab_id: "xxxxxxxx-xxxx-xxxx-xxxx-dada1c650246" # last hash in the url when you click on the account in YNAB
    username: "username" # online banking username / alias
    password: "password" # online banking PIN (NOT! the pin of your bank card!)
    fints_blz: "10050000" # Your bank's code / Bankleitzahl
    fints_endpoint: "https://banking-be3.s-fints-pt-be.de/fints30" # more info can be found here: https://github.com/schurig/ynab-bank-importer/wiki/FinTS---HBCI#fints_endpoint
  - dumper: :n26
    iban: # n26 iban
    ynab_id: # last hash in the url when you click on the account in YNAB
    username: # n26 username
    password: # n26 password
    skip_pending_transactions: false # default: false, only imports transactions when they're processed
    set_category: false # default: false, sets the N26 category name as category

Any idea what may be causing this?

gitviola commented 5 years ago

Hey @yuvke, do you mind adding a small line?

Before this line here:

https://github.com/schurig/ynab-bank-importer/blob/3739b4b56c25d255f44431ea9436cfba9922abb3/lib/dumper/fints.rb#L34

it would help if you add a

puts "################"
p transaction.inspect

and post the output here (the one just before it fails). Please make sure that you remove all sensitive information from the output

I suspect that your bank returns some weird value.

yuvke commented 5 years ago

Hey @schurig, thank you for the help. Here's the last output before the script throws:

<Cmxl::Fields::Transaction:0x00007fc0022e9d88
    @tag=\"61\", 
    @modifier=nil, 
    @source=\"SOMEIDXXXX,1902290301DR3\", 
    @data={
        \"date\"=>\"190229\",
        \"entry_date\"=>\"0301\",
        \"storno_flag\"=>\"\",
        \"funds_code\"=>\"D\",
        \"currency_letter\"=>\"R\",
        \"amount\"=>\"3,00\",
        \"swift_code\"=>\"XXXX\",
        \"reference\"=>\"NONREF\",
        \"bank_reference\"=>\"\"
    },
    @match=#<MatchData \"SOMEIDXXXX,1902290301DR3\" 
        date:\"190229\"
        entry_date:\"0301\"
        storno_flag:\"\"
        funds_code:\"D\"
        currency_letter:\"R\"
        amount:\"3,00\"
        swift_code:\"N024\"
        reference:\"NONREF\"
        bank_reference:\"\"
    >,
    @details=#<Cmxl::Fields::StatementDetails:0x00007fc0022e96f8
        @tag=\"86\",
        @modifier=nil,
        @source=\"809?VERYLONGIDWITHTONSOFCHARACTERSANDQUESTIONMARKS\",
        @data={
            \"transaction_code\"=>\"809\",
            \"details\"=>\"?VERYLONGIDWITHTONSOFCHARACTERSANDQUESTIONMARKS\",
            \"seperator\"=>\"?\"
        },
        @match=#<MatchData \"809?VERYLONGIDWITHTONSOFCHARACTERSANDQUESTIONMARKS\"
            transaction_code:\"809\"
            details:\"?VERYLONGIDWITHTONSOFCHARACTERSANDQUESTIONMARKS\"
            seperator:\"?\"
        >
    >
>
yuvke commented 5 years ago

@schurig, could this be related to the fact that I'm running the script directly from the terminal and via the docker container? I'm running on Mac and I have ruby installed, but maybe not the correct version?

gitviola commented 5 years ago

@yuvke I just had some time to check into it and it seems like it's a combination of your bank and the ruby library cmxl that I'm using: https://github.com/railslove/cmxl/blob/master/lib/cmxl/fields/transaction.rb#L63-L67

BluetriX commented 5 years ago

Got the same problem now with my bank. worked one month ago... :-(

I played a bit... it has to do sth with the februrary... he is trying getting the month of "190230" ... the 30th of Februrary 2019 does not exist...

I "fixed" this by modifying fints.rb --> statement = client.get_statement(account, Date.today - 30, Date.today - 9) (getting data from date-30 till date-9 [28.02.19])

yuvke commented 5 years ago

@BluetriX - thanks for the tip! I managed to skip the problematic dates (mine was February 29). And enter the remaining statements manually!

@schurig - Any idea why this happens? Is the faulty date due to the bank's API or the cmxl lib?

gitviola commented 5 years ago

@BluetriX @yuvke what bank is it that fails? I wonder if maybe the problem is that the bank thinks Feb 29th 2019 exists. I could at least build something around it that skips that transaction automatically so it doesn't happen again..

yuvke commented 5 years ago

This happens to me on Sparkasse. I would change the date to 28/2 so that the transaction would be valid. Is it possible?

gitviola commented 5 years ago

I will have a look into it and will try to do it asap. Probably not today but next week

moay commented 5 years ago

Hi there. Updates on this? Just ran into the same issue. Great work btw!

gitviola commented 5 years ago

I just fixed the issue. Sorry, I forgot that this was still open.

Be aware that if you use the latest version you might get some duplicates imported. YNAB will ask you to approve them. So you can simply select all the transactions it asks you to approve and remove them if you think it's a duplicate. Will only effect transactions within the last 35 days. 😊

moay commented 5 years ago

Thanks for acting on the issue. Actually, I think your fix doesn't resolve the issue, as the date in question is "190230". Just pulled the latest changes, the error is thrown again. :-( I can't reopen the issue, but it isn't resolved yet, I guess.

For me, this happens on a transaction from the DKB bank in Germany, so it's not some little bank where you'd expect a general misbehaviour or false date calculation. So I'd expect the issue to not be directly related to february - maybe this can happen in other months too? How about just changing the date to the last possible day in the month in case it's a date like Feb 30 or April 31?

moay commented 5 years ago

Okay, inspected that a bit closer, here is some more information.

First the error I get:

/home/pi/ynab-bank-importer/lib/dumper/fints.rb:98:in `entry_date': undefined method `year' for "190230":String (NoMethodError)

I inspected the failing transaction, it looks like this (removed some parts):

#<Cmxl::Fields::Transaction:0x2858be0 
@tag="61", 
@modifier=nil, 
@source="1902300228DR298,00N010NONREF", 
@data={
    "date"=>"190230", 
    "entry_date"=>"0228", 
    "storno_flag"=>"", 
    "funds_code"=>"D", 
    "currency_letter"=>"R", 
    "amount"=>"298,00", 
    "swift_code"=>"N010", 
    "reference"=>"NONREF", 
    "bank_reference"=>""
}, 
@match=#<MatchData "1902300228DR298,00N010NONREF" date:"190230" entry_date:"0228" storno_flag:"" funds_code:"D" currency_letter:"R" amount:"298,00" swift_code:"N010" reference:"NONREF" bank_reference:"">, 
@details=#<Cmxl::Fields::StatementDetails:0x28587d8 @tag="86", 
@modifier=nil, 
@source="***", 
@data={"transaction_code"=>"601", 
"details"=>"***", 
"seperator"=>"?"}, 
@match=#<MatchData "601***" transaction_code:"601" details:"***" seperator:"?">>>

So the entry_date seems to be correct but getting the year from '190230' fails, probably because ' '190230' could not be parsed to a year and remains a string instead. Maybe one could just get the year from the string in case the date is a string and not a date (which should only happen is those edge cases with invalid dates)?

moay commented 5 years ago

Simpler solution: In fints.rb:95 just don't pass the year into to_date() if date could not be parsed and therefore is a string. It will fallback to today's year (which might be an issue at the end of december, but thats way better than a failing import).

Sorry for not submitting this as a pr, having the relatives on the doorstep so I don't have the time right now. If you don't get to it, I'll submit one later.

gitviola commented 5 years ago

@moay I just pushed a new branch. Could you check if it works with that version? #57 hotfix/fix-not-existing-dates

In this version I don't check for the 28th of February. I always take the last day of the month if the date was invalid. Let's hope this works.

moay commented 5 years ago

Just ran a quick test, seems to work. No error. I'll check the transactions later, but there are some new ones, so this looks good. 👍

Thanks!