lunchmoney 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check_pipeline.yml +24 -0
  3. data/.github/workflows/ci.yml +1 -4
  4. data/.github/workflows/dependabot-rbi-updater.yml +3 -6
  5. data/.github/workflows/publish_gem.yml +14 -16
  6. data/.github/workflows/release_pipeline.yml +36 -0
  7. data/.rubocop.yml +5 -2
  8. data/Gemfile +1 -1
  9. data/Gemfile.lock +19 -18
  10. data/LICENSE +1 -1
  11. data/README.md +1 -1
  12. data/Rakefile +27 -0
  13. data/lib/lunchmoney/api.rb +160 -35
  14. data/lib/lunchmoney/calls/assets.rb +98 -0
  15. data/lib/lunchmoney/calls/base.rb +118 -0
  16. data/lib/lunchmoney/calls/budgets.rb +84 -0
  17. data/lib/lunchmoney/calls/categories.rb +196 -0
  18. data/lib/lunchmoney/calls/crypto.rb +50 -0
  19. data/lib/lunchmoney/calls/plaid_accounts.rb +40 -0
  20. data/lib/lunchmoney/calls/recurring_expenses.rb +29 -0
  21. data/lib/lunchmoney/calls/tags.rb +21 -0
  22. data/lib/lunchmoney/calls/transactions.rb +220 -0
  23. data/lib/lunchmoney/calls/users.rb +21 -0
  24. data/lib/lunchmoney/errors.rb +17 -1
  25. data/lib/lunchmoney/objects/asset.rb +92 -0
  26. data/lib/lunchmoney/objects/budget.rb +76 -0
  27. data/lib/lunchmoney/objects/category.rb +55 -0
  28. data/lib/lunchmoney/objects/child_category.rb +44 -0
  29. data/lib/lunchmoney/objects/child_transaction.rb +35 -0
  30. data/lib/lunchmoney/objects/config.rb +40 -0
  31. data/lib/lunchmoney/objects/crypto.rb +46 -0
  32. data/lib/lunchmoney/objects/crypto_base.rb +67 -0
  33. data/lib/lunchmoney/objects/data.rb +44 -0
  34. data/lib/lunchmoney/objects/object.rb +28 -0
  35. data/lib/lunchmoney/objects/plaid_account.rb +75 -0
  36. data/lib/lunchmoney/objects/recurring_expense.rb +68 -0
  37. data/lib/lunchmoney/objects/recurring_expense_base.rb +31 -0
  38. data/lib/lunchmoney/objects/split.rb +28 -0
  39. data/lib/lunchmoney/objects/tag.rb +24 -0
  40. data/lib/lunchmoney/objects/tag_base.rb +23 -0
  41. data/lib/lunchmoney/objects/transaction.rb +160 -0
  42. data/lib/lunchmoney/objects/transaction_base.rb +54 -0
  43. data/lib/lunchmoney/objects/transaction_modification_base.rb +32 -0
  44. data/lib/lunchmoney/objects/update_transaction.rb +47 -0
  45. data/lib/lunchmoney/objects/user.rb +38 -0
  46. data/lib/lunchmoney/version.rb +1 -1
  47. data/lunchmoney.gemspec +3 -4
  48. data/sorbet/rbi/gems/{minitest@5.21.2.rbi → minitest@5.22.2.rbi} +147 -144
  49. data/sorbet/rbi/gems/{rubocop-sorbet@0.7.6.rbi → rubocop-sorbet@0.7.7.rbi} +53 -6
  50. data/sorbet/rbi/gems/{rubocop@1.60.1.rbi → rubocop@1.60.2.rbi} +51 -30
  51. data/sorbet/rbi/gems/{toys@0.15.4.rbi → toys@0.15.5.rbi} +3 -3
  52. data/sorbet/rbi/gems/{webmock@3.19.1.rbi → webmock@3.20.0.rbi} +10 -10
  53. metadata +50 -47
  54. data/lib/lunchmoney/api_call.rb +0 -109
  55. data/lib/lunchmoney/assets/asset.rb +0 -89
  56. data/lib/lunchmoney/assets/asset_calls.rb +0 -96
  57. data/lib/lunchmoney/budget/budget.rb +0 -74
  58. data/lib/lunchmoney/budget/budget_calls.rb +0 -82
  59. data/lib/lunchmoney/budget/config.rb +0 -38
  60. data/lib/lunchmoney/budget/data.rb +0 -42
  61. data/lib/lunchmoney/categories/category/category.rb +0 -52
  62. data/lib/lunchmoney/categories/category/child_category.rb +0 -42
  63. data/lib/lunchmoney/categories/category_calls.rb +0 -195
  64. data/lib/lunchmoney/crypto/crypto/crypto.rb +0 -43
  65. data/lib/lunchmoney/crypto/crypto/crypto_base.rb +0 -65
  66. data/lib/lunchmoney/crypto/crypto_calls.rb +0 -49
  67. data/lib/lunchmoney/data_object.rb +0 -25
  68. data/lib/lunchmoney/plaid_accounts/plaid_account.rb +0 -73
  69. data/lib/lunchmoney/plaid_accounts/plaid_account_calls.rb +0 -38
  70. data/lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense.rb +0 -65
  71. data/lib/lunchmoney/recurring_expenses/recurring_expense/recurring_expense_base.rb +0 -29
  72. data/lib/lunchmoney/recurring_expenses/recurring_expense_calls.rb +0 -28
  73. data/lib/lunchmoney/tags/tag/tag.rb +0 -20
  74. data/lib/lunchmoney/tags/tag/tag_base.rb +0 -21
  75. data/lib/lunchmoney/tags/tag_calls.rb +0 -20
  76. data/lib/lunchmoney/transactions/transaction/child_transaction.rb +0 -31
  77. data/lib/lunchmoney/transactions/transaction/split.rb +0 -24
  78. data/lib/lunchmoney/transactions/transaction/transaction.rb +0 -156
  79. data/lib/lunchmoney/transactions/transaction/transaction_base.rb +0 -52
  80. data/lib/lunchmoney/transactions/transaction/transaction_modification_base.rb +0 -30
  81. data/lib/lunchmoney/transactions/transaction/update_transaction.rb +0 -43
  82. data/lib/lunchmoney/transactions/transaction_calls.rb +0 -218
  83. data/lib/lunchmoney/user/user.rb +0 -36
  84. data/lib/lunchmoney/user/user_calls.rb +0 -19
  85. /data/sorbet/rbi/gems/{crack@0.4.5.rbi → crack@1.0.0.rbi} +0 -0
  86. /data/sorbet/rbi/gems/{toys-core@0.15.4.rbi → toys-core@0.15.5.rbi} +0 -0
@@ -0,0 +1,220 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../objects/child_transaction"
5
+ require_relative "../objects/transaction"
6
+ require_relative "../objects/split"
7
+ require_relative "../objects/update_transaction"
8
+
9
+ module LunchMoney
10
+ module Calls
11
+ # https://lunchmoney.dev/#transactions
12
+ class Transactions < LunchMoney::Calls::Base
13
+ sig do
14
+ params(
15
+ tag_id: T.nilable(Integer),
16
+ recurring_id: T.nilable(Integer),
17
+ plaid_account_id: T.nilable(Integer),
18
+ category_id: T.nilable(Integer),
19
+ asset_id: T.nilable(Integer),
20
+ is_group: T.nilable(T::Boolean),
21
+ status: T.nilable(String),
22
+ start_date: T.nilable(String),
23
+ end_date: T.nilable(String),
24
+ debit_as_negative: T.nilable(T::Boolean),
25
+ pending: T.nilable(T::Boolean),
26
+ offset: T.nilable(Integer),
27
+ limit: T.nilable(Integer),
28
+ ).returns(T.any(T::Array[LunchMoney::Objects::Transaction], LunchMoney::Errors))
29
+ end
30
+ def transactions(
31
+ tag_id: nil,
32
+ recurring_id: nil,
33
+ plaid_account_id: nil,
34
+ category_id: nil,
35
+ asset_id: nil,
36
+ is_group: nil,
37
+ status: nil,
38
+ start_date: nil,
39
+ end_date: nil,
40
+ debit_as_negative: nil,
41
+ pending: nil,
42
+ offset: nil,
43
+ limit: nil
44
+ )
45
+
46
+ params = clean_params({
47
+ tag_id:,
48
+ recurring_id:,
49
+ plaid_account_id:,
50
+ category_id:,
51
+ asset_id:,
52
+ is_group:,
53
+ status:,
54
+ start_date:,
55
+ end_date:,
56
+ debit_as_negative:,
57
+ pending:,
58
+ offset:,
59
+ limit:,
60
+ })
61
+ response = get("transactions", query_params: params)
62
+
63
+ api_errors = errors(response)
64
+ return api_errors if api_errors.present?
65
+
66
+ response.body[:transactions].map do |transaction|
67
+ transaction[:tags].map! { |tag| LunchMoney::Objects::TagBase.new(**tag) }
68
+
69
+ transaction[:children]&.map! do |child_transaction|
70
+ LunchMoney::Objects::ChildTransaction.new(**child_transaction)
71
+ end
72
+
73
+ LunchMoney::Objects::Transaction.new(**transaction)
74
+ end
75
+ end
76
+
77
+ sig do
78
+ params(
79
+ transaction_id: Integer,
80
+ debit_as_negative: T.nilable(T::Boolean),
81
+ ).returns(T.any(LunchMoney::Objects::Transaction, LunchMoney::Errors))
82
+ end
83
+ def transaction(transaction_id, debit_as_negative: nil)
84
+ params = clean_params({ debit_as_negative: })
85
+ response = get("transactions/#{transaction_id}", query_params: params)
86
+
87
+ api_errors = errors(response)
88
+ return api_errors if api_errors.present?
89
+
90
+ LunchMoney::Objects::Transaction.new(**response.body)
91
+ end
92
+
93
+ sig do
94
+ params(
95
+ transactions: T::Array[LunchMoney::Objects::UpdateTransaction],
96
+ apply_rules: T.nilable(T::Boolean),
97
+ skip_duplicates: T.nilable(T::Boolean),
98
+ check_for_recurring: T.nilable(T::Boolean),
99
+ debit_as_negative: T.nilable(T::Boolean),
100
+ skip_balance_update: T.nilable(T::Boolean),
101
+ ).returns(T.any(T::Hash[Symbol, T::Array[Integer]], LunchMoney::Errors))
102
+ end
103
+ def insert_transactions(transactions, apply_rules: nil, skip_duplicates: nil,
104
+ check_for_recurring: nil, debit_as_negative: nil, skip_balance_update: nil)
105
+ params = clean_params({
106
+ transactions: transactions.map(&:serialize),
107
+ apply_rules:,
108
+ skip_duplicates:,
109
+ check_for_recurring:,
110
+ debit_as_negative:,
111
+ skip_balance_update:,
112
+ })
113
+ response = post("transactions", params)
114
+
115
+ api_errors = errors(response)
116
+ return api_errors if api_errors.present?
117
+
118
+ response.body
119
+ end
120
+
121
+ sig do
122
+ params(
123
+ transaction_id: Integer,
124
+ transaction: T.nilable(LunchMoney::Objects::UpdateTransaction),
125
+ split: T.nilable(T::Array[LunchMoney::Objects::Split]),
126
+ debit_as_negative: T.nilable(T::Boolean),
127
+ skip_balance_update: T.nilable(T::Boolean),
128
+ ).returns(T.any({ updated: T::Boolean, split: T.nilable(T::Array[Integer]) }, LunchMoney::Errors))
129
+ end
130
+ def update_transaction(transaction_id, transaction: nil, split: nil,
131
+ debit_as_negative: nil, skip_balance_update: nil)
132
+ raise(
133
+ LunchMoney::MissingArgument,
134
+ "Either a transaction or split must be provided",
135
+ ) if transaction.nil? && split.nil?
136
+
137
+ params = clean_params({
138
+ transaction: transaction&.serialize,
139
+ split: split&.map!(&:serialize),
140
+ debit_as_negative:,
141
+ skip_balance_update:,
142
+ })
143
+ response = put("transactions/#{transaction_id}", params)
144
+
145
+ api_errors = errors(response)
146
+ return api_errors if api_errors.present?
147
+
148
+ response.body
149
+ end
150
+
151
+ sig do
152
+ params(
153
+ parent_ids: T::Array[Integer],
154
+ remove_parents: T.nilable(T::Boolean),
155
+ ).returns(T.any(T::Array[Integer], LunchMoney::Errors))
156
+ end
157
+ def unsplit_transaction(parent_ids, remove_parents: false)
158
+ params = { parent_ids:, remove_parents: }
159
+ response = post("transactions/unsplit", params)
160
+
161
+ api_errors = errors(response)
162
+ return api_errors if api_errors.present?
163
+
164
+ response.body
165
+ end
166
+
167
+ sig { params(transaction_id: Integer).returns(T.any(LunchMoney::Objects::Transaction, LunchMoney::Errors)) }
168
+ def transaction_group(transaction_id)
169
+ response = get("transactions/group", query_params: { transaction_id: })
170
+
171
+ api_errors = errors(response)
172
+ return api_errors if api_errors.present?
173
+
174
+ LunchMoney::Objects::Transaction.new(**response.body)
175
+ end
176
+
177
+ sig do
178
+ params(
179
+ date: String,
180
+ payee: String,
181
+ transactions: T::Array[T.any(Integer, String)],
182
+ category_id: T.nilable(Integer),
183
+ notes: T.nilable(String),
184
+ tags: T.nilable(T::Array[T.any(Integer, String)]),
185
+ ).returns(T.any(Integer, LunchMoney::Errors))
186
+ end
187
+ def create_transaction_group(date:, payee:, transactions:, category_id: nil, notes: nil, tags: nil)
188
+ params = clean_params({
189
+ date:,
190
+ payee:,
191
+ transactions:,
192
+ category_id:,
193
+ notes:,
194
+ tags:,
195
+ })
196
+ response = post("transactions/group", params)
197
+
198
+ api_errors = errors(response)
199
+ return api_errors if api_errors.present?
200
+
201
+ response.body
202
+ end
203
+
204
+ sig do
205
+ params(transaction_id: T.any(
206
+ String,
207
+ Integer,
208
+ )).returns(T.any(T::Hash[Symbol, T::Array[Integer]], LunchMoney::Errors))
209
+ end
210
+ def delete_transaction_group(transaction_id)
211
+ response = delete("transactions/group/#{transaction_id}")
212
+
213
+ api_errors = errors(response)
214
+ return api_errors if api_errors.present?
215
+
216
+ response.body
217
+ end
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,21 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../objects/user"
5
+
6
+ module LunchMoney
7
+ module Calls
8
+ # https://lunchmoney.dev/#user
9
+ class Users < LunchMoney::Calls::Base
10
+ sig { returns(T.any(LunchMoney::Objects::User, LunchMoney::Errors)) }
11
+ def me
12
+ response = get("me")
13
+
14
+ api_errors = errors(response)
15
+ return api_errors if api_errors.present?
16
+
17
+ LunchMoney::Objects::User.new(**response.body)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,7 +2,23 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module LunchMoney
5
- # This class is used to represent errors returned directly from the LunchMoney API
5
+ # This class is used to represent errors returned directly from the LunchMoney API. This class has been set up to act
6
+ # like an array, delegating a lot of common array getter methods directly to messages for you.
7
+ # @example
8
+ # api = LunchMoney::Api.new
9
+ # response = api.categories
10
+ #
11
+ # response.class
12
+ # => LunchMoney::Errors
13
+ #
14
+ # response.first
15
+ # => "Some error returned by the API"
16
+ #
17
+ # response.empty?
18
+ # => false
19
+ #
20
+ # response[0]
21
+ # => "Some error returned by the API"
6
22
  class Errors
7
23
  sig { returns(T::Array[String]) }
8
24
  attr_accessor :messages
@@ -0,0 +1,92 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Objects
6
+ # https://lunchmoney.dev/#assets-object
7
+ class Asset < LunchMoney::Objects::Object
8
+ include LunchMoney::Validators
9
+
10
+ sig { returns(Integer) }
11
+ attr_accessor :id
12
+
13
+ sig { returns(String) }
14
+ attr_reader :type_name, :balance_as_of, :created_at
15
+
16
+ sig { returns(String) }
17
+ attr_accessor :name, :balance, :currency
18
+
19
+ sig { returns(T.nilable(String)) }
20
+ attr_accessor :display_name, :closed_on, :institution_name, :subtype_name
21
+
22
+ sig { returns(T::Boolean) }
23
+ attr_accessor :exclude_transactions
24
+
25
+ # Valid asset type names
26
+ VALID_TYPE_NAMES = T.let(
27
+ [
28
+ "cash",
29
+ "credit",
30
+ "investment",
31
+ "real estate",
32
+ "loan",
33
+ "vehicle",
34
+ "cryptocurrency",
35
+ "employee compensation",
36
+ "other liability",
37
+ "other asset",
38
+ "depository",
39
+ ],
40
+ T::Array[String],
41
+ )
42
+
43
+ sig do
44
+ params(
45
+ created_at: String,
46
+ type_name: String,
47
+ name: String,
48
+ balance: String,
49
+ balance_as_of: String,
50
+ currency: String,
51
+ exclude_transactions: T::Boolean,
52
+ id: Integer,
53
+ subtype_name: T.nilable(String),
54
+ display_name: T.nilable(String),
55
+ closed_on: T.nilable(String),
56
+ institution_name: T.nilable(String),
57
+ ).void
58
+ end
59
+ def initialize(created_at:, type_name:, name:, balance:, balance_as_of:, currency:, exclude_transactions:, id:,
60
+ subtype_name: nil, display_name: nil, closed_on: nil, institution_name: nil)
61
+ super()
62
+ @created_at = T.let(validate_iso8601!(created_at), String)
63
+ @type_name = T.let(validate_one_of!(type_name, VALID_TYPE_NAMES), String)
64
+ @name = name
65
+ @balance = balance
66
+ @balance_as_of = T.let(validate_iso8601!(balance_as_of), String)
67
+ @currency = currency
68
+ @exclude_transactions = exclude_transactions
69
+ @id = id
70
+ @subtype_name = subtype_name
71
+ @display_name = display_name
72
+ @closed_on = closed_on
73
+ @institution_name = institution_name
74
+ end
75
+
76
+ sig { params(name: String).void }
77
+ def type_name=(name)
78
+ @type_name = validate_one_of!(name, VALID_TYPE_NAMES)
79
+ end
80
+
81
+ sig { params(time: String).void }
82
+ def balance_as_of=(time)
83
+ @balance_as_of = validate_iso8601!(time)
84
+ end
85
+
86
+ sig { params(time: String).void }
87
+ def created_at=(time)
88
+ @created_at = validate_iso8601!(time)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,76 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "data"
5
+ require_relative "config"
6
+
7
+ module LunchMoney
8
+ module Objects
9
+ # https://lunchmoney.dev/#budget-object
10
+ class Budget < LunchMoney::Objects::Object
11
+ # API object reference documentation: https://lunchmoney.dev/#budget-object
12
+
13
+ sig { returns(String) }
14
+ attr_accessor :category_name
15
+
16
+ sig { returns(Integer) }
17
+ attr_accessor :order
18
+
19
+ sig { returns(T.nilable(String)) }
20
+ attr_accessor :category_group_name
21
+
22
+ sig { returns(T.nilable(Integer)) }
23
+ attr_accessor :category_id, :group_id
24
+
25
+ sig { returns(T.nilable(T::Boolean)) }
26
+ attr_accessor :is_group
27
+
28
+ sig { returns(T::Boolean) }
29
+ attr_accessor :is_income, :exclude_from_budget, :exclude_from_totals, :archived
30
+
31
+ sig { returns(T::Hash[Symbol, LunchMoney::Objects::Data]) }
32
+ attr_accessor :data
33
+
34
+ sig { returns(T.nilable(T::Hash[Symbol, LunchMoney::Objects::Config])) }
35
+ attr_accessor :config
36
+
37
+ sig { returns(T.nilable({ list: T::Array[LunchMoney::Objects::RecurringExpense] })) }
38
+ attr_accessor :recurring
39
+
40
+ sig do
41
+ params(
42
+ is_income: T::Boolean,
43
+ exclude_from_budget: T::Boolean,
44
+ exclude_from_totals: T::Boolean,
45
+ data: T::Hash[Symbol, LunchMoney::Objects::Data],
46
+ category_name: String,
47
+ order: Integer,
48
+ archived: T::Boolean,
49
+ category_id: T.nilable(Integer),
50
+ category_group_name: T.nilable(String),
51
+ group_id: T.nilable(Integer),
52
+ is_group: T.nilable(T::Boolean),
53
+ config: T.nilable(T::Hash[Symbol, LunchMoney::Objects::Config]),
54
+ recurring: T.nilable({ list: T::Array[LunchMoney::Objects::RecurringExpense] }),
55
+ ).void
56
+ end
57
+ def initialize(is_income:, exclude_from_budget:, exclude_from_totals:, data:, category_name:, order:, archived:,
58
+ category_id: nil, category_group_name: nil, group_id: nil, is_group: nil, config: nil, recurring: nil)
59
+ super()
60
+ @category_id = category_id
61
+ @is_income = is_income
62
+ @exclude_from_budget = exclude_from_budget
63
+ @exclude_from_totals = exclude_from_totals
64
+ @data = data
65
+ @category_name = category_name
66
+ @order = order
67
+ @category_group_name = category_group_name
68
+ @group_id = group_id
69
+ @is_group = is_group
70
+ @config = config
71
+ @archived = archived
72
+ @recurring = recurring
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,55 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "child_category"
5
+ module LunchMoney
6
+ module Objects
7
+ # https://lunchmoney.dev/#categories-object
8
+ class Category < ChildCategory
9
+ sig { returns(T.nilable(String)) }
10
+ attr_accessor :group_category_name
11
+
12
+ sig { returns(T::Boolean) }
13
+ attr_accessor :is_income, :exclude_from_budget, :exclude_from_totals, :is_group
14
+
15
+ sig { returns(T.nilable(Integer)) }
16
+ attr_accessor :group_id, :order
17
+
18
+ sig { returns(T.nilable(T::Array[T.any(LunchMoney::Objects::Category, LunchMoney::Objects::ChildCategory)])) }
19
+ attr_accessor :children
20
+
21
+ sig do
22
+ params(
23
+ id: Integer,
24
+ name: String,
25
+ is_income: T::Boolean,
26
+ exclude_from_budget: T::Boolean,
27
+ exclude_from_totals: T::Boolean,
28
+ is_group: T::Boolean,
29
+ archived: T.nilable(T::Boolean),
30
+ archived_on: T.nilable(String),
31
+ updated_at: T.nilable(String),
32
+ created_at: T.nilable(String),
33
+ group_id: T.nilable(Integer),
34
+ order: T.nilable(Integer),
35
+ description: T.nilable(String),
36
+ children: T.nilable(T::Array[T.any(LunchMoney::Objects::Category, LunchMoney::Objects::ChildCategory)]),
37
+ group_category_name: T.nilable(String),
38
+ ).void
39
+ end
40
+ def initialize(id:, name:, is_income:, exclude_from_budget:, exclude_from_totals:, is_group:, archived: nil,
41
+ archived_on: nil, updated_at: nil, created_at: nil, group_id: nil, order: nil, description: nil, children: nil,
42
+ group_category_name: nil)
43
+ super(id:, name:, archived:, archived_on:, updated_at:, created_at:, description:)
44
+ @is_income = is_income
45
+ @exclude_from_budget = exclude_from_budget
46
+ @exclude_from_totals = exclude_from_totals
47
+ @is_group = is_group
48
+ @group_id = group_id
49
+ @order = order
50
+ @children = children
51
+ @group_category_name = group_category_name
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,44 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Objects
6
+ # A slimmed down version of https://lunchmoney.dev/#categories-object used in the
7
+ # `children` field of some category calls
8
+ class ChildCategory < LunchMoney::Objects::Object
9
+ sig { returns(Integer) }
10
+ attr_accessor :id
11
+
12
+ sig { returns(String) }
13
+ attr_accessor :name
14
+
15
+ sig { returns(T.nilable(String)) }
16
+ attr_accessor :description, :archived_on, :updated_at, :created_at
17
+
18
+ sig { returns(T.nilable(T::Boolean)) }
19
+ attr_accessor :archived
20
+
21
+ sig do
22
+ params(
23
+ id: Integer,
24
+ name: String,
25
+ archived: T.nilable(T::Boolean),
26
+ archived_on: T.nilable(String),
27
+ updated_at: T.nilable(String),
28
+ created_at: T.nilable(String),
29
+ description: T.nilable(String),
30
+ ).void
31
+ end
32
+ def initialize(id:, name:, archived: nil, archived_on: nil, updated_at: nil, created_at: nil, description: nil)
33
+ super()
34
+ @id = id
35
+ @name = name
36
+ @archived = archived
37
+ @archived_on = archived_on
38
+ @updated_at = updated_at
39
+ @created_at = created_at
40
+ @description = description
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "transaction_base"
5
+
6
+ module LunchMoney
7
+ module Objects
8
+ # Slimmed down version of https://lunchmoney.dev/#transaction-object used in the
9
+ # `children` field of a transaction object with an additional `formatted_date`` field
10
+ class ChildTransaction < TransactionBase
11
+ sig { returns(String) }
12
+ attr_accessor :formatted_date
13
+
14
+ sig do
15
+ params(
16
+ id: Integer,
17
+ date: String,
18
+ amount: String,
19
+ currency: String,
20
+ to_base: Number,
21
+ payee: String,
22
+ formatted_date: String,
23
+ notes: T.nilable(String),
24
+ asset_id: T.nilable(Integer),
25
+ plaid_account_id: T.nilable(Integer),
26
+ ).void
27
+ end
28
+ def initialize(id:, date:, amount:, currency:, to_base:, payee:, formatted_date:, notes: nil, asset_id: nil,
29
+ plaid_account_id: nil)
30
+ super(id:, date:, amount:, currency:, to_base:, payee:, notes:, asset_id:, plaid_account_id:)
31
+ @formatted_date = formatted_date
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Objects
6
+ # https://lunchmoney.dev/#config-object
7
+ class Config < LunchMoney::Objects::Object
8
+ # API object reference documentation: https://lunchmoney.dev/#config-object
9
+
10
+ sig { returns(Integer) }
11
+ attr_accessor :config_id
12
+
13
+ sig { returns(Number) }
14
+ attr_accessor :amount, :to_base
15
+
16
+ sig { returns(String) }
17
+ attr_accessor :cadence, :currency, :auto_suggest
18
+
19
+ sig do
20
+ params(
21
+ config_id: Integer,
22
+ cadence: String,
23
+ amount: Number,
24
+ currency: String,
25
+ to_base: Number,
26
+ auto_suggest: String,
27
+ ).void
28
+ end
29
+ def initialize(config_id:, cadence:, amount:, currency:, to_base:, auto_suggest:)
30
+ super()
31
+ @config_id = config_id
32
+ @cadence = cadence
33
+ @amount = amount
34
+ @currency = currency
35
+ @to_base = to_base
36
+ @auto_suggest = auto_suggest
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "crypto_base"
5
+ module LunchMoney
6
+ module Objects
7
+ # https://lunchmoney.dev/#crypto-object
8
+ class Crypto < CryptoBase
9
+ include LunchMoney::Validators
10
+
11
+ sig { returns(String) }
12
+ attr_reader :balance_as_of
13
+
14
+ sig { returns(String) }
15
+ attr_accessor :currency, :status
16
+
17
+ sig do
18
+ params(
19
+ created_at: String,
20
+ source: String,
21
+ name: String,
22
+ balance: String,
23
+ balance_as_of: String,
24
+ currency: String,
25
+ status: String,
26
+ institution_name: T.nilable(String),
27
+ id: T.nilable(Integer),
28
+ zabo_account_id: T.nilable(Integer),
29
+ display_name: T.nilable(String),
30
+ ).void
31
+ end
32
+ def initialize(created_at:, source:, name:, balance:, balance_as_of:, currency:,
33
+ status:, institution_name: nil, id: nil, zabo_account_id: nil, display_name: nil)
34
+ super(created_at:, source:, name:, balance:, institution_name:, id:, zabo_account_id:, display_name:)
35
+ @balance_as_of = T.let(validate_iso8601!(balance_as_of), String)
36
+ @currency = currency
37
+ @status = status
38
+ end
39
+
40
+ sig { params(time: String).void }
41
+ def balance_as_of=(time)
42
+ @balance_as_of = validate_iso8601!(time)
43
+ end
44
+ end
45
+ end
46
+ end