lunchmoney 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publish_gem.yml +1 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/lunchmoney/api.rb +34 -34
  5. data/lib/lunchmoney/calls/assets.rb +98 -0
  6. data/lib/lunchmoney/calls/base.rb +112 -0
  7. data/lib/lunchmoney/calls/budgets.rb +84 -0
  8. data/lib/lunchmoney/calls/categories.rb +196 -0
  9. data/lib/lunchmoney/calls/crypto.rb +50 -0
  10. data/lib/lunchmoney/calls/plaid_accounts.rb +40 -0
  11. data/lib/lunchmoney/calls/recurring_expenses.rb +29 -0
  12. data/lib/lunchmoney/calls/tags.rb +21 -0
  13. data/lib/lunchmoney/calls/transactions.rb +220 -0
  14. data/lib/lunchmoney/calls/users.rb +21 -0
  15. data/lib/lunchmoney/objects/asset.rb +91 -0
  16. data/lib/lunchmoney/objects/budget.rb +76 -0
  17. data/lib/lunchmoney/objects/category.rb +55 -0
  18. data/lib/lunchmoney/objects/child_category.rb +44 -0
  19. data/lib/lunchmoney/objects/child_transaction.rb +35 -0
  20. data/lib/lunchmoney/objects/config.rb +40 -0
  21. data/lib/lunchmoney/objects/crypto.rb +46 -0
  22. data/lib/lunchmoney/objects/crypto_base.rb +67 -0
  23. data/lib/lunchmoney/objects/data.rb +44 -0
  24. data/lib/lunchmoney/objects/object.rb +28 -0
  25. data/lib/lunchmoney/objects/plaid_account.rb +75 -0
  26. data/lib/lunchmoney/objects/recurring_expense.rb +68 -0
  27. data/lib/lunchmoney/objects/recurring_expense_base.rb +31 -0
  28. data/lib/lunchmoney/objects/split.rb +28 -0
  29. data/lib/lunchmoney/objects/tag.rb +24 -0
  30. data/lib/lunchmoney/objects/tag_base.rb +23 -0
  31. data/lib/lunchmoney/objects/transaction.rb +160 -0
  32. data/lib/lunchmoney/objects/transaction_base.rb +54 -0
  33. data/lib/lunchmoney/objects/transaction_modification_base.rb +32 -0
  34. data/lib/lunchmoney/objects/update_transaction.rb +47 -0
  35. data/lib/lunchmoney/objects/user.rb +38 -0
  36. data/lib/lunchmoney/version.rb +1 -1
  37. metadata +32 -32
  38. data/lib/lunchmoney/api_call.rb +0 -109
  39. data/lib/lunchmoney/assets/asset.rb +0 -89
  40. data/lib/lunchmoney/assets/asset_calls.rb +0 -96
  41. data/lib/lunchmoney/budget/budget.rb +0 -74
  42. data/lib/lunchmoney/budget/budget_calls.rb +0 -82
  43. data/lib/lunchmoney/budget/config.rb +0 -38
  44. data/lib/lunchmoney/budget/data.rb +0 -42
  45. data/lib/lunchmoney/categories/category/category.rb +0 -52
  46. data/lib/lunchmoney/categories/category/child_category.rb +0 -42
  47. data/lib/lunchmoney/categories/category_calls.rb +0 -195
  48. data/lib/lunchmoney/crypto/crypto/crypto.rb +0 -43
  49. data/lib/lunchmoney/crypto/crypto/crypto_base.rb +0 -65
  50. data/lib/lunchmoney/crypto/crypto_calls.rb +0 -49
  51. data/lib/lunchmoney/data_object.rb +0 -25
  52. data/lib/lunchmoney/plaid_accounts/plaid_account.rb +0 -73
  53. data/lib/lunchmoney/plaid_accounts/plaid_account_calls.rb +0 -38
  54. data/lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense.rb +0 -65
  55. data/lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense_base.rb +0 -29
  56. data/lib/lunchmoney/recurring_expenses/recurring_expense_calls.rb +0 -28
  57. data/lib/lunchmoney/tags/tag/tag.rb +0 -20
  58. data/lib/lunchmoney/tags/tag/tag_base.rb +0 -21
  59. data/lib/lunchmoney/tags/tag_calls.rb +0 -20
  60. data/lib/lunchmoney/transactions/transaction/child_transaction.rb +0 -31
  61. data/lib/lunchmoney/transactions/transaction/split.rb +0 -24
  62. data/lib/lunchmoney/transactions/transaction/transaction.rb +0 -156
  63. data/lib/lunchmoney/transactions/transaction/transaction_base.rb +0 -52
  64. data/lib/lunchmoney/transactions/transaction/transaction_modification_base.rb +0 -30
  65. data/lib/lunchmoney/transactions/transaction/update_transaction.rb +0 -43
  66. data/lib/lunchmoney/transactions/transaction_calls.rb +0 -218
  67. data/lib/lunchmoney/user/user.rb +0 -36
  68. data/lib/lunchmoney/user/user_calls.rb +0 -19
@@ -0,0 +1,32 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Objects
6
+ # Base object used for transaction objects that are used to update
7
+ # transactions https://lunchmoney.dev/#update-transaction
8
+ class TransactionModificationBase < LunchMoney::Objects::Object
9
+ sig { returns(T.nilable(String)) }
10
+ attr_accessor :payee, :date, :notes
11
+
12
+ sig { returns(T.nilable(Integer)) }
13
+ attr_accessor :category_id
14
+
15
+ sig do
16
+ params(
17
+ payee: T.nilable(String),
18
+ date: T.nilable(String),
19
+ category_id: T.nilable(Integer),
20
+ notes: T.nilable(String),
21
+ ).void
22
+ end
23
+ def initialize(payee: nil, date: nil, category_id: nil, notes: nil)
24
+ super()
25
+ @payee = payee
26
+ @date = date
27
+ @category_id = category_id
28
+ @notes = notes
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,47 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "transaction_modification_base"
5
+
6
+ module LunchMoney
7
+ module Objects
8
+ # object used when updating a transaction https://lunchmoney.dev/#update-transaction
9
+ class UpdateTransaction < TransactionModificationBase
10
+ sig { returns(T.nilable(String)) }
11
+ attr_accessor :amount, :currency, :status, :external_id
12
+
13
+ sig { returns(T.nilable(Integer)) }
14
+ attr_accessor :asset_id, :recurring_id
15
+
16
+ sig { returns(T.nilable(T::Array[T.any(String, Integer)])) }
17
+ attr_accessor :tags
18
+
19
+ sig do
20
+ params(
21
+ tags: T.nilable(T::Array[T.any(String, Integer)]),
22
+ category_id: T.nilable(Integer),
23
+ payee: T.nilable(String),
24
+ amount: T.nilable(String),
25
+ currency: T.nilable(String),
26
+ asset_id: T.nilable(Integer),
27
+ recurring_id: T.nilable(Integer),
28
+ notes: T.nilable(String),
29
+ status: T.nilable(String),
30
+ external_id: T.nilable(String),
31
+ date: T.nilable(String),
32
+ ).void
33
+ end
34
+ def initialize(tags: nil, category_id: nil, payee: nil, amount: nil, currency: nil, asset_id: nil,
35
+ recurring_id: nil, notes: nil, status: nil, external_id: nil, date: nil)
36
+ super(payee:, date:, category_id:, notes:)
37
+ @amount = amount
38
+ @tags = tags
39
+ @currency = currency
40
+ @asset_id = asset_id
41
+ @recurring_id = recurring_id
42
+ @status = status
43
+ @external_id = external_id
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Objects
6
+ # https://lunchmoney.dev/#user-object
7
+ class User < LunchMoney::Objects::Object
8
+ sig { returns(Integer) }
9
+ attr_accessor :user_id, :account_id
10
+
11
+ sig { returns(String) }
12
+ attr_accessor :user_name, :user_email, :budget_name
13
+
14
+ sig { returns(T.nilable(String)) }
15
+ attr_accessor :api_key_label
16
+
17
+ sig do
18
+ params(
19
+ user_id: Integer,
20
+ user_name: String,
21
+ user_email: String,
22
+ account_id: Integer,
23
+ budget_name: String,
24
+ api_key_label: T.nilable(String),
25
+ ).void
26
+ end
27
+ def initialize(user_id:, user_name:, user_email:, account_id:, budget_name:, api_key_label: nil)
28
+ super()
29
+ @user_id = user_id
30
+ @user_name = user_name
31
+ @user_email = user_email
32
+ @account_id = account_id
33
+ @budget_name = budget_name
34
+ @api_key_label = api_key_label
35
+ end
36
+ end
37
+ end
38
+ end
@@ -3,5 +3,5 @@
3
3
 
4
4
  module LunchMoney
5
5
  # Current version of the gem
6
- VERSION = "1.0.0"
6
+ VERSION = "1.1.0"
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lunchmoney
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@halorrr"
@@ -89,40 +89,40 @@ files:
89
89
  - bin/yard
90
90
  - lib/lunchmoney.rb
91
91
  - lib/lunchmoney/api.rb
92
- - lib/lunchmoney/api_call.rb
93
- - lib/lunchmoney/assets/asset.rb
94
- - lib/lunchmoney/assets/asset_calls.rb
95
- - lib/lunchmoney/budget/budget.rb
96
- - lib/lunchmoney/budget/budget_calls.rb
97
- - lib/lunchmoney/budget/config.rb
98
- - lib/lunchmoney/budget/data.rb
99
- - lib/lunchmoney/categories/category/category.rb
100
- - lib/lunchmoney/categories/category/child_category.rb
101
- - lib/lunchmoney/categories/category_calls.rb
92
+ - lib/lunchmoney/calls/assets.rb
93
+ - lib/lunchmoney/calls/base.rb
94
+ - lib/lunchmoney/calls/budgets.rb
95
+ - lib/lunchmoney/calls/categories.rb
96
+ - lib/lunchmoney/calls/crypto.rb
97
+ - lib/lunchmoney/calls/plaid_accounts.rb
98
+ - lib/lunchmoney/calls/recurring_expenses.rb
99
+ - lib/lunchmoney/calls/tags.rb
100
+ - lib/lunchmoney/calls/transactions.rb
101
+ - lib/lunchmoney/calls/users.rb
102
102
  - lib/lunchmoney/configuration.rb
103
- - lib/lunchmoney/crypto/crypto/crypto.rb
104
- - lib/lunchmoney/crypto/crypto/crypto_base.rb
105
- - lib/lunchmoney/crypto/crypto_calls.rb
106
- - lib/lunchmoney/data_object.rb
107
103
  - lib/lunchmoney/errors.rb
108
104
  - lib/lunchmoney/exceptions.rb
109
- - lib/lunchmoney/plaid_accounts/plaid_account.rb
110
- - lib/lunchmoney/plaid_accounts/plaid_account_calls.rb
111
- - lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense.rb
112
- - lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense_base.rb
113
- - lib/lunchmoney/recurring_expenses/recurring_expense_calls.rb
114
- - lib/lunchmoney/tags/tag/tag.rb
115
- - lib/lunchmoney/tags/tag/tag_base.rb
116
- - lib/lunchmoney/tags/tag_calls.rb
117
- - lib/lunchmoney/transactions/transaction/child_transaction.rb
118
- - lib/lunchmoney/transactions/transaction/split.rb
119
- - lib/lunchmoney/transactions/transaction/transaction.rb
120
- - lib/lunchmoney/transactions/transaction/transaction_base.rb
121
- - lib/lunchmoney/transactions/transaction/transaction_modification_base.rb
122
- - lib/lunchmoney/transactions/transaction/update_transaction.rb
123
- - lib/lunchmoney/transactions/transaction_calls.rb
124
- - lib/lunchmoney/user/user.rb
125
- - lib/lunchmoney/user/user_calls.rb
105
+ - lib/lunchmoney/objects/asset.rb
106
+ - lib/lunchmoney/objects/budget.rb
107
+ - lib/lunchmoney/objects/category.rb
108
+ - lib/lunchmoney/objects/child_category.rb
109
+ - lib/lunchmoney/objects/child_transaction.rb
110
+ - lib/lunchmoney/objects/config.rb
111
+ - lib/lunchmoney/objects/crypto.rb
112
+ - lib/lunchmoney/objects/crypto_base.rb
113
+ - lib/lunchmoney/objects/data.rb
114
+ - lib/lunchmoney/objects/object.rb
115
+ - lib/lunchmoney/objects/plaid_account.rb
116
+ - lib/lunchmoney/objects/recurring_expense.rb
117
+ - lib/lunchmoney/objects/recurring_expense_base.rb
118
+ - lib/lunchmoney/objects/split.rb
119
+ - lib/lunchmoney/objects/tag.rb
120
+ - lib/lunchmoney/objects/tag_base.rb
121
+ - lib/lunchmoney/objects/transaction.rb
122
+ - lib/lunchmoney/objects/transaction_base.rb
123
+ - lib/lunchmoney/objects/transaction_modification_base.rb
124
+ - lib/lunchmoney/objects/update_transaction.rb
125
+ - lib/lunchmoney/objects/user.rb
126
126
  - lib/lunchmoney/validators.rb
127
127
  - lib/lunchmoney/version.rb
128
128
  - lunchmoney.gemspec
@@ -1,109 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require_relative "errors"
5
-
6
- module LunchMoney
7
- # Base class for all API call types
8
- class ApiCall
9
- # Base URL used for API calls
10
- BASE_URL = "https://dev.lunchmoney.app/v1/"
11
-
12
- sig { returns(T.nilable(String)) }
13
- attr_reader :api_key
14
-
15
- sig { params(api_key: T.nilable(String)).void }
16
- def initialize(api_key: nil)
17
- @api_key = T.let((api_key || LunchMoney.configuration.api_key), T.nilable(String))
18
- end
19
-
20
- private
21
-
22
- sig { params(endpoint: String, query_params: T.nilable(T::Hash[Symbol, T.untyped])).returns(Faraday::Response) }
23
- def get(endpoint, query_params: nil)
24
- connection = request(flat_params: true)
25
-
26
- if query_params.present?
27
- connection.get(BASE_URL + endpoint, query_params)
28
- else
29
- connection.get(BASE_URL + endpoint)
30
- end
31
- end
32
-
33
- sig { params(endpoint: String, params: T.nilable(T::Hash[Symbol, T.untyped])).returns(Faraday::Response) }
34
- def post(endpoint, params)
35
- request(json_request: true).post(BASE_URL + endpoint, params)
36
- end
37
-
38
- sig { params(endpoint: String, body: T::Hash[Symbol, T.untyped]).returns(Faraday::Response) }
39
- def put(endpoint, body)
40
- request(json_request: true).put(BASE_URL + endpoint) do |req|
41
- req.body = body
42
- end
43
- end
44
-
45
- sig { params(endpoint: String, query_params: T.nilable(T::Hash[Symbol, T.untyped])).returns(Faraday::Response) }
46
- def delete(endpoint, query_params: nil)
47
- connection = request(flat_params: true)
48
-
49
- if query_params.present?
50
- connection.delete(BASE_URL + endpoint, query_params)
51
- else
52
- connection.delete(BASE_URL + endpoint)
53
- end
54
- end
55
-
56
- sig { params(json_request: T::Boolean, flat_params: T::Boolean).returns(Faraday::Connection) }
57
- def request(json_request: false, flat_params: false)
58
- Faraday.new do |conn|
59
- conn.request(:authorization, "Bearer", @api_key)
60
- conn.request(:json) if json_request
61
- # conn.options.params_encoder = Faraday::FlatParamsEncoder if flat_params
62
- conn.response(:json, content_type: /json$/, parser_options: { symbolize_names: true })
63
- end
64
- end
65
-
66
- sig { params(response: Faraday::Response).returns(LunchMoney::Errors) }
67
- def errors(response)
68
- body = response.body
69
-
70
- return parse_errors(body) unless error_hash(body).nil?
71
-
72
- LunchMoney::Errors.new
73
- end
74
-
75
- sig { params(body: T::Hash[Symbol, T.any(String, T::Array[String])]).returns(LunchMoney::Errors) }
76
- def parse_errors(body)
77
- errors = error_hash(body)
78
- api_errors = LunchMoney::Errors.new
79
- return api_errors if errors.blank?
80
-
81
- case errors
82
- when String
83
- api_errors << errors
84
- when Array
85
- errors.each { |error| api_errors << error }
86
- end
87
-
88
- api_errors
89
- end
90
-
91
- sig { params(body: T.untyped).returns(T.untyped) }
92
- def error_hash(body)
93
- return unless body.is_a?(Hash)
94
-
95
- if body[:error]
96
- body[:error]
97
- elsif body[:errors]
98
- body[:errors]
99
- elsif body[:name] == "Error"
100
- body[:message]
101
- end
102
- end
103
-
104
- sig { params(params: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
105
- def clean_params(params)
106
- params.reject! { |_key, value| value.nil? }
107
- end
108
- end
109
- end
@@ -1,89 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module LunchMoney
5
- # https://lunchmoney.dev/#assets-object
6
- class Asset < LunchMoney::DataObject
7
- include LunchMoney::Validators
8
-
9
- sig { returns(Integer) }
10
- attr_accessor :id
11
-
12
- sig { returns(String) }
13
- attr_reader :type_name, :balance_as_of, :created_at
14
-
15
- sig { returns(String) }
16
- attr_accessor :name, :balance, :currency
17
-
18
- sig { returns(T.nilable(String)) }
19
- attr_accessor :display_name, :closed_on, :institution_name, :subtype_name
20
-
21
- sig { returns(T::Boolean) }
22
- attr_accessor :exclude_transactions
23
-
24
- # Valid asset type names
25
- VALID_TYPE_NAMES = T.let(
26
- [
27
- "cash",
28
- "credit",
29
- "investment",
30
- "real estate",
31
- "loan",
32
- "vehicle",
33
- "cryptocurrency",
34
- "employee compensation",
35
- "other liability",
36
- "other asset",
37
- ],
38
- T::Array[String],
39
- )
40
-
41
- sig do
42
- params(
43
- created_at: String,
44
- type_name: String,
45
- name: String,
46
- balance: String,
47
- balance_as_of: String,
48
- currency: String,
49
- exclude_transactions: T::Boolean,
50
- id: Integer,
51
- subtype_name: T.nilable(String),
52
- display_name: T.nilable(String),
53
- closed_on: T.nilable(String),
54
- institution_name: T.nilable(String),
55
- ).void
56
- end
57
- def initialize(created_at:, type_name:, name:, balance:, balance_as_of:, currency:, exclude_transactions:, id:,
58
- subtype_name: nil, display_name: nil, closed_on: nil, institution_name: nil)
59
- super()
60
- @created_at = T.let(validate_iso8601!(created_at), String)
61
- @type_name = T.let(validate_one_of!(type_name, VALID_TYPE_NAMES), String)
62
- @name = name
63
- @balance = balance
64
- @balance_as_of = T.let(validate_iso8601!(balance_as_of), String)
65
- @currency = currency
66
- @exclude_transactions = exclude_transactions
67
- @id = id
68
- @subtype_name = subtype_name
69
- @display_name = display_name
70
- @closed_on = closed_on
71
- @institution_name = institution_name
72
- end
73
-
74
- sig { params(name: String).void }
75
- def type_name=(name)
76
- @type_name = validate_one_of!(name, VALID_TYPE_NAMES)
77
- end
78
-
79
- sig { params(time: String).void }
80
- def balance_as_of=(time)
81
- @balance_as_of = validate_iso8601!(time)
82
- end
83
-
84
- sig { params(time: String).void }
85
- def created_at=(time)
86
- @created_at = validate_iso8601!(time)
87
- end
88
- end
89
- end
@@ -1,96 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require_relative "asset"
5
-
6
- module LunchMoney
7
- # https://lunchmoney.dev/#assets
8
- class AssetCalls < ApiCall
9
- sig { returns(T.any(T::Array[LunchMoney::Asset], LunchMoney::Errors)) }
10
- def assets
11
- response = get("assets")
12
-
13
- api_errors = errors(response)
14
- return api_errors if api_errors.present?
15
-
16
- response.body[:assets].map do |asset|
17
- LunchMoney::Asset.new(**asset)
18
- end
19
- end
20
-
21
- sig do
22
- params(
23
- type_name: String,
24
- name: String,
25
- balance: String,
26
- subtype_name: T.nilable(String),
27
- display_name: T.nilable(String),
28
- balance_as_of: T.nilable(String),
29
- currency: T.nilable(String),
30
- institution_name: T.nilable(String),
31
- closed_on: T.nilable(String),
32
- exclude_transactions: T.nilable(T::Boolean),
33
- ).returns(T.any(LunchMoney::Asset, LunchMoney::Errors))
34
- end
35
- def create_asset(type_name:, name:, balance:, subtype_name: nil, display_name: nil, balance_as_of: nil,
36
- currency: nil, institution_name: nil, closed_on: nil, exclude_transactions: nil)
37
- params = {
38
- type_name:,
39
- name:,
40
- balance:,
41
- subtype_name:,
42
- display_name:,
43
- balance_as_of:,
44
- currency:,
45
- institution_name:,
46
- closed_on:,
47
- exclude_transactions:,
48
- }
49
-
50
- response = post("assets", params)
51
-
52
- api_errors = errors(response)
53
- return api_errors if api_errors.present?
54
-
55
- LunchMoney::Asset.new(**response.body)
56
- end
57
-
58
- sig do
59
- params(
60
- asset_id: Integer,
61
- type_name: T.nilable(String),
62
- name: T.nilable(String),
63
- balance: T.nilable(String),
64
- subtype_name: T.nilable(String),
65
- display_name: T.nilable(String),
66
- balance_as_of: T.nilable(String),
67
- currency: T.nilable(String),
68
- institution_name: T.nilable(String),
69
- closed_on: T.nilable(String),
70
- exclude_transactions: T.nilable(T::Boolean),
71
- ).returns(T.any(LunchMoney::Asset, LunchMoney::Errors))
72
- end
73
- def update_asset(asset_id, type_name: nil, name: nil, balance: nil, subtype_name: nil, display_name: nil,
74
- balance_as_of: nil, currency: nil, institution_name: nil, closed_on: nil, exclude_transactions: nil)
75
- params = {
76
- type_name:,
77
- name:,
78
- balance:,
79
- subtype_name:,
80
- display_name:,
81
- balance_as_of:,
82
- currency:,
83
- institution_name:,
84
- closed_on:,
85
- exclude_transactions:,
86
- }
87
-
88
- response = put("assets/#{asset_id}", params)
89
-
90
- api_errors = errors(response)
91
- return api_errors if api_errors.present?
92
-
93
- LunchMoney::Asset.new(**response.body)
94
- end
95
- end
96
- end
@@ -1,74 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require_relative "data"
5
- require_relative "config"
6
-
7
- module LunchMoney
8
- # https://lunchmoney.dev/#budget-object
9
- class Budget < LunchMoney::DataObject
10
- # API object reference documentation: https://lunchmoney.dev/#budget-object
11
-
12
- sig { returns(String) }
13
- attr_accessor :category_name
14
-
15
- sig { returns(Integer) }
16
- attr_accessor :order
17
-
18
- sig { returns(T.nilable(String)) }
19
- attr_accessor :category_group_name
20
-
21
- sig { returns(T.nilable(Integer)) }
22
- attr_accessor :category_id, :group_id
23
-
24
- sig { returns(T.nilable(T::Boolean)) }
25
- attr_accessor :is_group
26
-
27
- sig { returns(T::Boolean) }
28
- attr_accessor :is_income, :exclude_from_budget, :exclude_from_totals, :archived
29
-
30
- sig { returns(T::Hash[Symbol, LunchMoney::Data]) }
31
- attr_accessor :data
32
-
33
- sig { returns(T.nilable(T::Hash[Symbol, LunchMoney::Config])) }
34
- attr_accessor :config
35
-
36
- sig { returns(T.nilable({ list: T::Array[LunchMoney::RecurringExpense] })) }
37
- attr_accessor :recurring
38
-
39
- sig do
40
- params(
41
- is_income: T::Boolean,
42
- exclude_from_budget: T::Boolean,
43
- exclude_from_totals: T::Boolean,
44
- data: T::Hash[Symbol, LunchMoney::Data],
45
- category_name: String,
46
- order: Integer,
47
- archived: T::Boolean,
48
- category_id: T.nilable(Integer),
49
- category_group_name: T.nilable(String),
50
- group_id: T.nilable(Integer),
51
- is_group: T.nilable(T::Boolean),
52
- config: T.nilable(T::Hash[Symbol, LunchMoney::Config]),
53
- recurring: T.nilable({ list: T::Array[LunchMoney::RecurringExpense] }),
54
- ).void
55
- end
56
- def initialize(is_income:, exclude_from_budget:, exclude_from_totals:, data:, category_name:, order:, archived:,
57
- category_id: nil, category_group_name: nil, group_id: nil, is_group: nil, config: nil, recurring: nil)
58
- super()
59
- @category_id = category_id
60
- @is_income = is_income
61
- @exclude_from_budget = exclude_from_budget
62
- @exclude_from_totals = exclude_from_totals
63
- @data = data
64
- @category_name = category_name
65
- @order = order
66
- @category_group_name = category_group_name
67
- @group_id = group_id
68
- @is_group = is_group
69
- @config = config
70
- @archived = archived
71
- @recurring = recurring
72
- end
73
- end
74
- end
@@ -1,82 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require_relative "budget"
5
-
6
- module LunchMoney
7
- # https://lunchmoney.dev/#budget
8
- class BudgetCalls < ApiCall
9
- sig do
10
- params(
11
- start_date: String,
12
- end_date: String,
13
- currency: T.nilable(String),
14
- ).returns(T.any(T::Array[LunchMoney::Budget], LunchMoney::Errors))
15
- end
16
- def budgets(start_date:, end_date:, currency: nil)
17
- params = clean_params({ start_date:, end_date:, currency: })
18
- response = get("budgets", query_params: params)
19
-
20
- api_errors = errors(response)
21
- return api_errors if api_errors.present?
22
-
23
- response.body.map do |budget|
24
- if budget[:data]
25
- data_keys = budget[:data].keys
26
- data_keys.each do |data_key|
27
- budget[:data][data_key] = LunchMoney::Data.new(**budget[:data][data_key])
28
- end
29
- end
30
-
31
- if budget[:config]
32
- config_keys = budget[:config].keys
33
- config_keys.each do |config_key|
34
- budget[:config][config_key] = LunchMoney::Data.new(**budget[:config][config_key])
35
- end
36
- end
37
-
38
- if budget[:recurring]
39
- budget[:recurring][:list]&.map! { |recurring| LunchMoney::RecurringExpenseBase.new(**recurring) }
40
- end
41
-
42
- LunchMoney::Budget.new(**budget)
43
- end
44
- end
45
-
46
- sig do
47
- params(
48
- start_date: String,
49
- category_id: Integer,
50
- amount: Number,
51
- currency: T.nilable(String),
52
- ).returns(T.any(
53
- T::Hash[Symbol, { category_id: Integer, amount: Number, currency: String, start_date: String }],
54
- LunchMoney::Errors,
55
- ))
56
- end
57
- def upsert_budget(start_date:, category_id:, amount:, currency: nil)
58
- params = clean_params({ start_date:, category_id:, amount:, currency: })
59
- response = put("budgets", params)
60
-
61
- api_errors = errors(response)
62
- return api_errors if api_errors.present?
63
-
64
- response.body
65
- end
66
-
67
- sig { params(start_date: String, category_id: Integer).returns(T.any(T::Boolean, LunchMoney::Errors)) }
68
- def remove_budget(start_date:, category_id:)
69
- params = {
70
- start_date:,
71
- category_id:,
72
- }
73
-
74
- response = delete("budgets", query_params: params)
75
-
76
- api_errors = errors(response)
77
- return api_errors if api_errors.present?
78
-
79
- response.body
80
- end
81
- end
82
- end