-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathlunch_money.rb
More file actions
78 lines (58 loc) · 2.29 KB
/
lunch_money.rb
File metadata and controls
78 lines (58 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module Plugins
class LunchMoney < Base
BASE_URL = 'https://dev.lunchmoney.app/v1'.freeze
def locals
{ items: }
end
private
def items
case item_type
when 'budgets' then budgets
when 'accounts' then accounts
end
end
def budgets
resp = fetch(budgets_url, headers:)
budget_data = JSON.parse(resp.body)
raise AccessTokenExpired if budget_data.is_a?(Hash) && budget_data['message'] == 'Access token does not exist.'
budget_data.map do |budget|
next if budget['is_income'] # show only expenses by default
[CGI.unescapeHTML(budget['category_name']), budget.dig('data', beginning_of_month, 'spending_to_base') || 0]
end.compact
rescue AccessTokenExpired => e
handle_erroring_state(e.message)
[]
end
# user probably expects all items from "Accounts Overview" widget, which actually lives in 2 places (accounts, assets)
def accounts
resp = fetch(accounts_url, headers:)
account_data = JSON.parse(resp.body)
raise AccessTokenExpired if account_data.is_a?(Hash) && account_data['message'] == 'Access token does not exist.'
resp = fetch(assets_url, headers:)
asset_data = JSON.parse(resp.body)
raise AccessTokenExpired if asset_data.is_a?(Hash) && asset_data['message'] == 'Access token does not exist.'
accounts_map = account_data['plaid_accounts'].map do |account|
[CGI.unescapeHTML(account['display_name'] || account['name']), account['balance']]
end
assets_map = asset_data['assets'].map do |asset|
[CGI.unescapeHTML(asset['display_name'] || asset['name']), asset['balance']]
end
accounts_map + assets_map
rescue AccessTokenExpired => e
handle_erroring_state(e.message)
[]
end
def headers
{ "Authorization" => "Bearer #{settings['access_token']}" }
end
def item_type
return 'budgets' unless settings['item_type'].present?
settings['item_type']
end
def beginning_of_month = Date.today.beginning_of_month.to_s
def end_of_month = Date.today.end_of_month.to_s
def budgets_url = "#{BASE_URL}/budgets?start_date=#{beginning_of_month}&end_date=#{end_of_month}"
def accounts_url = "#{BASE_URL}/plaid_accounts"
def assets_url = "#{BASE_URL}/assets"
end
end