myfinance 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -2
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +304 -1
  6. data/lib/myfinance.rb +12 -0
  7. data/lib/myfinance/client.rb +16 -0
  8. data/lib/myfinance/entities/bank_statement.rb +16 -0
  9. data/lib/myfinance/entities/credit_card.rb +19 -0
  10. data/lib/myfinance/entities/credit_card_collection.rb +11 -0
  11. data/lib/myfinance/entities/credit_card_transaction.rb +26 -0
  12. data/lib/myfinance/entities/credit_card_transaction_collection.rb +11 -0
  13. data/lib/myfinance/entities/financial_account.rb +1 -1
  14. data/lib/myfinance/entities/payable_account_collection.rb +14 -0
  15. data/lib/myfinance/entities/receivable_account_collection.rb +14 -0
  16. data/lib/myfinance/entities/reconcile_collection.rb +30 -0
  17. data/lib/myfinance/resources/bank_statement.rb +20 -0
  18. data/lib/myfinance/resources/category.rb +16 -0
  19. data/lib/myfinance/resources/classification_center.rb +1 -1
  20. data/lib/myfinance/resources/credit_card.rb +47 -0
  21. data/lib/myfinance/resources/credit_card_transaction.rb +47 -0
  22. data/lib/myfinance/resources/financial_account.rb +48 -7
  23. data/lib/myfinance/resources/financial_transaction.rb +13 -2
  24. data/lib/myfinance/resources/person.rb +1 -1
  25. data/lib/myfinance/resources/reconcile.rb +20 -0
  26. data/lib/myfinance/version.rb +1 -1
  27. data/spec/lib/myfinance/client_spec.rb +21 -0
  28. data/spec/lib/myfinance/entities/credit_card_collection_spec.rb +23 -0
  29. data/spec/lib/myfinance/entities/credit_card_spec.rb +7 -0
  30. data/spec/lib/myfinance/entities/credit_card_transaction_collection_spec.rb +21 -0
  31. data/spec/lib/myfinance/entities/credit_card_transaction_spec.rb +8 -0
  32. data/spec/lib/myfinance/entities/reconcile_collection_spec.rb +20 -0
  33. data/spec/lib/myfinance/resources/bank_statement_spec.rb +53 -0
  34. data/spec/lib/myfinance/resources/category_spec.rb +24 -3
  35. data/spec/lib/myfinance/resources/classification_center_spec.rb +12 -5
  36. data/spec/lib/myfinance/resources/credit_card_spec.rb +142 -0
  37. data/spec/lib/myfinance/resources/credit_card_transaction_spec.rb +162 -0
  38. data/spec/lib/myfinance/resources/financial_transaction_spec.rb +27 -2
  39. data/spec/lib/myfinance/resources/payable_account_spec.rb +131 -15
  40. data/spec/lib/myfinance/resources/person_spec.rb +16 -4
  41. data/spec/lib/myfinance/resources/receivable_account_spec.rb +132 -15
  42. data/spec/lib/myfinance/resources/reconcile_spec.rb +33 -0
  43. data/spec/support/bank_statements/extrato.ofx +207 -0
  44. metadata +35 -2
@@ -0,0 +1,16 @@
1
+ module Myfinance
2
+ module Entities
3
+ class BankStatement < Base
4
+ attribute :id, Integer
5
+ attribute :deposit_account_id, Integer
6
+ attribute :file_file_name, String
7
+ attribute :future_items_ignored_count, Integer
8
+ attribute :amount_zero_items_ignored_count, Integer
9
+ attribute :invalid_date_items_ignored_count, Integer
10
+ attribute :event, Hash
11
+
12
+ attribute :created_at, DateTime
13
+ attribute :updated_at, DateTime
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Myfinance
2
+ module Entities
3
+ class CreditCard < Base
4
+ attribute :id, Integer
5
+ attribute :entity_id, Integer
6
+ attribute :person_id, Integer
7
+ attribute :classification_center_id, Integer
8
+ attribute :category_id, Integer
9
+ attribute :closing_day, Integer
10
+ attribute :expiration_day, Integer
11
+ attribute :name, String
12
+ attribute :flag, String
13
+ attribute :flag_image_url, String
14
+ attribute :observation, String
15
+ attribute :created_at, DateTime
16
+ attribute :updated_at, DateTime
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module Myfinance
2
+ module Entities
3
+ class CreditCardCollection < Collection
4
+ def build_collection
5
+ response.parsed_body.each do |attributes|
6
+ collection.push(Myfinance::Entities::CreditCard.new(attributes["credit_card"]))
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module Myfinance
2
+ module Entities
3
+ class CreditCardTransaction < Base
4
+ attribute :id, Integer
5
+ attribute :credit_card_invoice_id, Integer
6
+ attribute :credit_card_id, Integer
7
+ attribute :classification_center_id, Integer
8
+ attribute :category_id, Integer
9
+ attribute :amount, Decimal
10
+ attribute :description, String
11
+ attribute :occurred_at, Date
12
+ attribute :type, String
13
+ attribute :document, String
14
+ attribute :observation, String
15
+ attribute :created_at, DateTime
16
+ attribute :updated_at, DateTime
17
+ attribute :invoice_payment, Boolean
18
+ attribute :excel_import_id, Integer
19
+ attribute :financial_account_id, Integer
20
+ attribute :person_id, Integer
21
+ attribute :moved, Boolean
22
+ attribute :recurrence_id, Integer
23
+ attribute :indexed_at, DateTime
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module Myfinance
2
+ module Entities
3
+ class CreditCardTransactionCollection < Collection
4
+ def build_collection
5
+ response.parsed_body.each do |attributes|
6
+ collection.push(Myfinance::Entities::CreditCardTransaction.new(attributes["credit_card_transaction"]))
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -10,7 +10,7 @@ module Myfinance
10
10
  :competency_month].each { |k| attribute k, String }
11
11
 
12
12
  [:amount, :interest_amount, :discount_amount, :total_amount, :ticket_amount].each do |k|
13
- attribute k, Float
13
+ attribute k, Decimal
14
14
  end
15
15
 
16
16
  [:remind, :income_tax_relevant, :recurrent, :parcelled, :ticket_amount].each do |k|
@@ -0,0 +1,14 @@
1
+ module Myfinance
2
+ module Entities
3
+ #
4
+ # A wrapper to Myfinance payable accounts collection
5
+ #
6
+ class PayableAccountCollection < Collection
7
+ def build_collection
8
+ response.parsed_body.each do |attributes|
9
+ collection.push(Myfinance::Entities::PayableAccount.new(attributes["payable_account"]))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Myfinance
2
+ module Entities
3
+ #
4
+ # A wrapper to Myfinance receivable accounts collection
5
+ #
6
+ class ReceivableAccountCollection < Collection
7
+ def build_collection
8
+ response.parsed_body.each do |attributes|
9
+ collection.push(Myfinance::Entities::ReceivableAccount.new(attributes["receivable_account"]))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module Myfinance
2
+ module Entities
3
+ class ReconcileCollection < Collection
4
+ def build_collection
5
+ response.parsed_body.each do |attributes|
6
+ type = attributes.first
7
+ if type == "financial_transactions" || type == "financial_accounts"
8
+ create_collection(type, attributes)
9
+ end
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def create_collection(type, attributes)
16
+ klass = klass_name(type)
17
+
18
+ attributes.delete(attributes.first)
19
+ attributes.each do |attribute|
20
+ collection.push(klass.new(attribute.first))
21
+ end
22
+ end
23
+
24
+ def klass_name(type)
25
+ return Myfinance::Entities::FinancialTransaction if type == "financial_transactions"
26
+ Myfinance::Entities::FinancialAccount
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module Myfinance
2
+ module Resources
3
+ class BankStatement < Base
4
+ def import(entity_id, deposit_account_id, file)
5
+ path = "/entities/#{entity_id}/deposit_accounts/#{deposit_account_id}/bank_statements"
6
+ params = { file: file }
7
+ http.post(path, body: { bank_statement: params }, multipart: true) do |response|
8
+ respond_with_object(response, "bank_statement")
9
+ end
10
+ end
11
+
12
+ def status(entity_id, deposit_account_id, id)
13
+ path = "/entities/#{entity_id}/deposit_accounts/#{deposit_account_id}/bank_statements/#{id}"
14
+ http.get(path) do |response|
15
+ respond_with_object(response, "bank_statement")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -35,6 +35,22 @@ module Myfinance
35
35
  end
36
36
  end
37
37
 
38
+ #
39
+ # Find a category by attributes
40
+ #
41
+ # [API]
42
+ # Method: <tt>GET /categories/:id</tt>
43
+ #
44
+ # Documentation: https://sandbox.myfinance.com.br/docs/api/categories#get_show
45
+ #
46
+ def find_by(params = {})
47
+ path = params.map { |k, v| "search[#{k}]=#{v}" }.join("&")
48
+
49
+ http.get(URI.encode("/categories?#{path}"), body: {}) do |response|
50
+ respond_with_collection(response)
51
+ end
52
+ end
53
+
38
54
  #
39
55
  # Creates a category
40
56
  #
@@ -46,7 +46,7 @@ module Myfinance
46
46
  def find_by(params)
47
47
  values = params.map { |k,v| "search[#{k}]=#{v}" }.join("&")
48
48
  http.get(
49
- "/classification_centers?#{values.gsub(%r/\s/, '+')}", body: {}
49
+ URI.encode("/classification_centers?#{values}"), body: {}
50
50
  ) do |response|
51
51
  respond_with_collection(response)
52
52
  end
@@ -0,0 +1,47 @@
1
+ module Myfinance
2
+ module Resources
3
+ class CreditCard < Base
4
+ def find_all(entity_id)
5
+ http.get(path(entity_id), body: {}) do |response|
6
+ respond_with_collection(response)
7
+ end
8
+ end
9
+
10
+ def find(entity_id, id)
11
+ cc_path = path(entity_id) + "/#{id}"
12
+ http.get(cc_path, body: {}) do |response|
13
+ respond_with_object(response, "credit_card")
14
+ end
15
+ end
16
+
17
+ def create(entity_id, params = {})
18
+ body = { credit_card: params }
19
+ http.post(path(entity_id), body: body) do |response|
20
+ respond_with_object(response, "credit_card")
21
+ end
22
+ end
23
+
24
+ def update(entity_id, id, params = {})
25
+ cc_path = path(entity_id) + "/#{id}"
26
+ body = { credit_card: params }
27
+ http.put(cc_path, body: body) do |response|
28
+ respond_with_object(response, "credit_card")
29
+ end
30
+ end
31
+
32
+ def destroy(entity_id, id)
33
+ cc_path = path(entity_id) + "/#{id}"
34
+ http.delete(cc_path, body: {}) do |response|
35
+ response
36
+ end
37
+ end
38
+
39
+
40
+ private
41
+
42
+ def path(entity_id)
43
+ "/entities/#{entity_id}/credit_cards"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ module Myfinance
2
+ module Resources
3
+ class CreditCardTransaction < Base
4
+ def find_all(entity_id, credit_card_id, year, month)
5
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/invoices/#{year}-#{month}"
6
+ http.get(path, body: {}) do |response|
7
+ respond_with_collection(response)
8
+ end
9
+ end
10
+
11
+ def find(entity_id, credit_card_id, credit_card_transaction_id)
12
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/transactions/#{credit_card_transaction_id}"
13
+ http.get(path, body: {}) do |response|
14
+ respond_with_object(response, "credit_card_transaction")
15
+ end
16
+ end
17
+
18
+ def create(entity_id, credit_card_id, params = {})
19
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/transactions"
20
+ http.post(path, body: { credit_card_transaction: params }) do |response|
21
+ respond_with_object(response, "credit_card_transaction")
22
+ end
23
+ end
24
+
25
+ def update(entity_id, credit_card_id, credit_card_transaction_id, params = {})
26
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/transactions/#{credit_card_transaction_id}"
27
+ http.put(path, body: { credit_card_transaction: params }) do |response|
28
+ respond_with_object(response, "credit_card_transaction")
29
+ end
30
+ end
31
+
32
+ def destroy(entity_id, credit_card_id, credit_card_transaction_id, params = {})
33
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/transactions/#{credit_card_transaction_id}"
34
+ http.delete(path, body: { credit_card_transaction: params }) do |response|
35
+ response
36
+ end
37
+ end
38
+
39
+ def destroy_parcelled(entity_id, credit_card_id, credit_card_transaction_id, params = {})
40
+ path = "/entities/#{entity_id}/credit_cards/#{credit_card_id}/transactions/#{credit_card_transaction_id}/recurrence"
41
+ http.delete(path, body: { credit_card_transaction: params }) do |response|
42
+ response
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -7,6 +7,15 @@ module Myfinance
7
7
  set_method_for(pay_or_receive_method)
8
8
  set_method_for(undo_payment_or_receivement)
9
9
  end
10
+
11
+ def find_all(entity_id, page = nil)
12
+ request_and_build_collection_response(:get, index_endpoint(entity_id, page))
13
+ end
14
+
15
+ def find(entity_id, id)
16
+ request_and_build_object_response(:get, endpoint_for(id, entity_id, :show))
17
+ end
18
+
10
19
  #
11
20
  # Creates a payable/receivable account
12
21
  #
@@ -18,7 +27,7 @@ module Myfinance
18
27
  # Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts#post_create
19
28
  #
20
29
  def create(entity_id, params = {})
21
- request_and_build_response(:post, endpoint_for(nil, entity_id, :create), params)
30
+ request_and_build_object_response(:post, endpoint_for(nil, entity_id, :create), params)
22
31
  end
23
32
 
24
33
  #
@@ -31,8 +40,8 @@ module Myfinance
31
40
  # Documentation: https://app.myfinance.com.br/docs/api/payable_accounts#put_update
32
41
  # Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts#put_update
33
42
  #
34
- def update(id, entity_id, params = {})
35
- request_and_build_response(:put, endpoint_for(id, entity_id, :update), params)
43
+ def update(entity_id, id, params = {})
44
+ request_and_build_object_response(:put, endpoint_for(id, entity_id, :update), params)
36
45
  end
37
46
 
38
47
  #
@@ -45,29 +54,57 @@ module Myfinance
45
54
  # Documentation: https://app.myfinance.com.br/docs/api/payable_accounts#delete_destroy
46
55
  # Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts#delete_destroy
47
56
  #
48
- def destroy(id, entity_id)
57
+ def destroy(entity_id, id)
49
58
  http.delete(endpoint_for(id, entity_id, :destroy)) do |_response|
50
59
  true
51
60
  end
52
61
  end
53
62
 
63
+ def destroy_recurrence(entity_id, id)
64
+ http.delete(endpoint_for(id, entity_id, :destroy_recurrence)) do |_response|
65
+ true
66
+ end
67
+ end
68
+
69
+ def destroy_many(entity_id, ids)
70
+ http.delete(destroy_many_endpoint(ids, entity_id)) do |_response|
71
+ true
72
+ end
73
+ end
74
+
54
75
  private
55
76
 
56
- def request_and_build_response(method, endpoint, params={})
77
+ def request_and_build_object_response(method, endpoint, params = {})
57
78
  http.send(method, endpoint, body: { resource_key => params }) do |response|
58
79
  respond_with_object(response, resource_key)
59
80
  end
60
81
  end
61
82
 
83
+ def request_and_build_collection_response(method, endpoint)
84
+ http.send(method, endpoint, body: {}) do |response|
85
+ respond_with_collection(response)
86
+ end
87
+ end
88
+
89
+ def index_endpoint(entity_id, page)
90
+ index_path = parameterize_endpoint(nil, entity_id, :index)
91
+
92
+ return index_path unless page
93
+ index_path + "?page=#{page}"
94
+ end
95
+
62
96
  def endpoint_for(id, entity_id, key)
63
97
  parameterize_endpoint(id, entity_id, key)
64
98
  end
65
99
 
66
100
  def default_endpoints
67
101
  {
102
+ index: "/entities/:entity_id/#{resource_key}s",
103
+ show: "/entities/:entity_id/#{resource_key}s/:id",
68
104
  create: "/entities/:entity_id/#{resource_key}s",
69
105
  update: "/entities/:entity_id/#{resource_key}s/:id",
70
- destroy: "/entities/:entity_id/#{resource_key}s/:id"
106
+ destroy: "/entities/:entity_id/#{resource_key}s/:id",
107
+ destroy_recurrence: "/entities/:entity_id/#{resource_key}s/:id/recurrence"
71
108
  }
72
109
  end
73
110
 
@@ -77,9 +114,13 @@ module Myfinance
77
114
 
78
115
  def set_method_for(action)
79
116
  self.class.send(:define_method, action) do |id, entity_id, params={}|
80
- request_and_build_response(:put, endpoint_for(id, entity_id, action), params)
117
+ request_and_build_object_response(:put, endpoint_for(id, entity_id, action), params)
81
118
  end
82
119
  end
120
+
121
+ def destroy_many_endpoint(ids, entity_id)
122
+ "/entities/#{entity_id}/#{resource_key}s?selected_ids=#{ids.join(',')}"
123
+ end
83
124
  end
84
125
  end
85
126
  end
@@ -7,7 +7,7 @@ module Myfinance
7
7
  # [API]
8
8
  # Documentation: https://app.myfinance.com.br/docs/api/financial_transactions
9
9
  #
10
- def find_all(entity_id, deposit_account_id)
10
+ def find_all(entity_id, deposit_account_id, page = nil)
11
11
  #
12
12
  # List all financial transactions
13
13
  #
@@ -16,7 +16,9 @@ module Myfinance
16
16
  #
17
17
  # Documentation: https://app.myfinance.com.br/docs/api/financial_transactions#get_index
18
18
  #
19
- http.get(path(entity_id, deposit_account_id), body: {}) do |response|
19
+ fts_path = index_path(entity_id, deposit_account_id, page)
20
+
21
+ http.get(fts_path, body: {}) do |response|
20
22
  respond_with_collection(response)
21
23
  end
22
24
  end
@@ -97,10 +99,19 @@ module Myfinance
97
99
 
98
100
  private
99
101
 
102
+ def index_path(entity_id, deposit_account_id, page)
103
+ return paginated_path(entity_id, deposit_account_id, page) if page
104
+ path(entity_id, deposit_account_id)
105
+ end
106
+
100
107
  def path(entity_id, deposit_account_id)
101
108
  "/entities/#{entity_id}/deposit_accounts/#{deposit_account_id}/financial_transactions"
102
109
  end
103
110
 
111
+ def paginated_path(entity_id, deposit_account_id, page)
112
+ "/entities/#{entity_id}/deposit_accounts/#{deposit_account_id}/financial_transactions?page=#{page}"
113
+ end
114
+
104
115
  def destroy_many_path(entity_id, deposit_account_id, ids)
105
116
  path(entity_id, deposit_account_id) + "/destroy_many?selected_ids=#{ids.join(",")}"
106
117
  end