lunchmoney 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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