ynab / ynab-sdk-ruby

YNAB API Client for Ruby
https://api.ynab.com
Apache License 2.0
65 stars 12 forks source link

balancedAdjustment vs. balanceAdjustment causing ArgumentError #70

Closed jordancrawfordnz closed 1 year ago

jordancrawfordnz commented 1 year ago

Background

I've got an app which syncs my bank transactions (via browser automation) to my YNAB budget. This morning I upgraded to SDK version 2.0.

I tested the upgrade locally and it worked fine syncing to my test YNAB budget. However on my server, while syncing to my real YNAB budget, I got the following error:

/Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:326:in `debt_transaction_type=': invalid value for "debt_transaction_type", must be one of ["payment", "refund", "fee", "interest", "escrow", "balancedAdjustment", "credit", "charge", "null"]. (ArgumentError)
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:391:in `block in build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:381:in `each_pair'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:381:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:372:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:354:in `_deserialize'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `block (2 levels) in build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `map'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `block in build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:298:in `each_pair'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:298:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:289:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:187:in `_deserialize'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:141:in `block in build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:131:in `each_pair'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:131:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:122:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:172:in `_deserialize'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:126:in `block in build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:116:in `each_pair'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:116:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:107:in `build_from_hash'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:285:in `convert_to_type'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:245:in `deserialize'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:76:in `call_api'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api/budgets_api.rb:81:in `get_budget_by_id_with_http_info'
    from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api/budgets_api.rb:29:in `get_budget_by_id'
    from bin/fetch_budget:12:in `<main>'

The contents of fetch_budget is a simple script to output the result of budgets.get_budget_by_id.

#!/usr/bin/env ruby

require 'ynab'

api_key = ARGV.shift
budget_id = ARGV.shift

api = YNAB::API.new(api_key)

puts "Fetching budget..."
budget = api.budgets.get_budget_by_id(budget_id).data.budget
puts budget

Issue

Digging a bit further, I see that the transaction it's trying to present is:

{:id=>"the id", :date=>"date", :amount=>-11111, :memo=>"Entered automatically by YNAB", :cleared=>"reconciled", :approved=>true, :flag_color=>nil, :account_id=>"the acc id", :payee_id=>"the payee id", :category_id=>nil, :transfer_account_id=>nil, :transfer_transaction_id=>nil, :matched_transaction_id=>nil, :import_id=>nil, :import_payee_name=>nil, :import_payee_name_original=>nil, :debt_transaction_type=>"balanceAdjustment", :deleted=>false}

It appears that there's a typo- the API returns balanceAdjustment but the validations expect balancedAdjustment.

Fix

I replaced all references to balancedAdjustment in the gem with balanceAdjustment and it worked fine. This appears to have been a typo.

I don't know how the API client generation stuff works so I haven't created a PR.

jordancrawfordnz commented 1 year ago

Hmm - I noticed that this also says balancedAdjustment in the online API docs - https://api.ynab.com/v1#/

Potentially this is an API issue instead?

bradymholt commented 1 year ago

Thanks for the report. I'll fix in the server spec and I also have https://github.com/ynab/ynab-sdk-ruby/pull/71 to remove the automatic field validation from the client; the previous versions of this client did not have this validation.