myfinance 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +23 -0
- data/.hound.yml +1063 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +94 -0
- data/LICENSE.txt +21 -0
- data/README.md +209 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/myfinance.rb +35 -0
- data/lib/myfinance/client.rb +31 -0
- data/lib/myfinance/configuration.rb +12 -0
- data/lib/myfinance/entities/base.rb +9 -0
- data/lib/myfinance/entities/collection.rb +57 -0
- data/lib/myfinance/entities/entity.rb +16 -0
- data/lib/myfinance/entities/entity_collection.rb +14 -0
- data/lib/myfinance/entities/financial_account.rb +30 -0
- data/lib/myfinance/entities/payable_account.rb +6 -0
- data/lib/myfinance/entities/receivable_account.rb +6 -0
- data/lib/myfinance/exception.rb +11 -0
- data/lib/myfinance/http.rb +33 -0
- data/lib/myfinance/request.rb +53 -0
- data/lib/myfinance/resources/base.rb +28 -0
- data/lib/myfinance/resources/entity.rb +39 -0
- data/lib/myfinance/resources/financial_account.rb +70 -0
- data/lib/myfinance/resources/payable_account.rb +33 -0
- data/lib/myfinance/resources/receivable_account.rb +33 -0
- data/lib/myfinance/response.rb +41 -0
- data/lib/myfinance/version.rb +3 -0
- data/myfinance.gemspec +45 -0
- data/spec/lib/myfinance/client_spec.rb +49 -0
- data/spec/lib/myfinance/configuration_spec.rb +26 -0
- data/spec/lib/myfinance/entities/base_spec.rb +28 -0
- data/spec/lib/myfinance/entities/collection_spec.rb +70 -0
- data/spec/lib/myfinance/entities/entity_collection_spec.rb +20 -0
- data/spec/lib/myfinance/entities/entity_spec.rb +11 -0
- data/spec/lib/myfinance/entities/payable_account_spec.rb +13 -0
- data/spec/lib/myfinance/entities/receivable_account_spec.rb +13 -0
- data/spec/lib/myfinance/http_spec.rb +37 -0
- data/spec/lib/myfinance/request_spec.rb +29 -0
- data/spec/lib/myfinance/resources/entity_spec.rb +63 -0
- data/spec/lib/myfinance/resources/payable_account_spec.rb +146 -0
- data/spec/lib/myfinance/resources/receivable_account_spec.rb +146 -0
- data/spec/lib/myfinance/response_spec.rb +58 -0
- data/spec/myfinance_spec.rb +25 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/client.rb +3 -0
- data/spec/support/matchers/have_attr_accessor.rb +18 -0
- data/spec/support/shared_examples/entity_attributes.rb +9 -0
- data/spec/support/shared_examples/http_request_methods.rb +29 -0
- data/spec/support/vcr.rb +7 -0
- metadata +306 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Entities
|
3
|
+
#
|
4
|
+
# A wrapper to Myfinance collection returns from API. This wrapper represents a collection and it's responsible for processing pagination information as well.
|
5
|
+
#
|
6
|
+
class Collection < Base
|
7
|
+
PAGE_REGEX = /page=(\d+)/
|
8
|
+
|
9
|
+
attr_reader :response, :collection, :headers
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
@response = response
|
13
|
+
@collection = []
|
14
|
+
@headers = response.headers['Link'].split(',') rescue []
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.build(response)
|
18
|
+
self.new(response).build
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
build_collection
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def next_page
|
27
|
+
page_for(:next)
|
28
|
+
end
|
29
|
+
|
30
|
+
def last_page
|
31
|
+
page_for(:last)
|
32
|
+
end
|
33
|
+
|
34
|
+
def previous_page
|
35
|
+
page_for(:prev)
|
36
|
+
end
|
37
|
+
|
38
|
+
def first_page
|
39
|
+
page_for(:first)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def page_for(page_rel)
|
45
|
+
header_link_for(page_rel).match(PAGE_REGEX)[1].to_i rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def header_link_for(rel)
|
49
|
+
headers.select{|n| n =~ /rel=#{rel}/}.first
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_collection
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Entities
|
3
|
+
class Entity < Base
|
4
|
+
attribute :id, Integer
|
5
|
+
attribute :name, String
|
6
|
+
attribute :account_id, Integer
|
7
|
+
attribute :charging_uuid, String
|
8
|
+
attribute :created_at, DateTime
|
9
|
+
attribute :default_in_menu, Boolean
|
10
|
+
attribute :deleted_at, DateTime
|
11
|
+
attribute :federation_subscription_number, String
|
12
|
+
attribute :imported_from_sync_at, DateTime
|
13
|
+
attribute :updated_at, DateTime
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Entities
|
3
|
+
#
|
4
|
+
# A wrapper to Myfinance entities collection
|
5
|
+
#
|
6
|
+
class EntityCollection < Collection
|
7
|
+
def build_collection
|
8
|
+
response.parsed_body.each do |attributes|
|
9
|
+
collection.push(Myfinance::Entities::Entity.new(attributes['entity']))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Entities
|
3
|
+
class FinancialAccount < Base
|
4
|
+
[:id, :entity_id, :status, :category_id, :person_id, :recurrence_id, :number_of_parcels,
|
5
|
+
:current_parcel, :classification_center_id, :expected_deposit_account_id].each do |k|
|
6
|
+
attribute k, Integer
|
7
|
+
end
|
8
|
+
|
9
|
+
[:status_name, :description, :document, :observation, :recurrence_period,
|
10
|
+
:competency_month].each { |k| attribute k, String }
|
11
|
+
|
12
|
+
[:amount, :interest_amount, :discount_amount, :total_amount, :ticket_amount].each do |k|
|
13
|
+
attribute k, Float
|
14
|
+
end
|
15
|
+
|
16
|
+
[:remind, :income_tax_relevant, :recurrent, :parcelled, :ticket_amount].each do |k|
|
17
|
+
attribute k, Boolean
|
18
|
+
end
|
19
|
+
|
20
|
+
[:due_date, :occurred_at, :document_emission_date, :reminded_at].each do |k|
|
21
|
+
attribute k, Date
|
22
|
+
end
|
23
|
+
[:created_at, :updated_at].each { |k| attribute k, DateTime }
|
24
|
+
|
25
|
+
attribute :financial_account_taxes_attributes, Array[Hash]
|
26
|
+
attribute :reconciliations, Hash[String => Array]
|
27
|
+
attribute :links, Array[Hash[String => String]]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "myfinance/request"
|
2
|
+
require "myfinance/response"
|
3
|
+
|
4
|
+
module Myfinance
|
5
|
+
class Http
|
6
|
+
attr_reader :token
|
7
|
+
|
8
|
+
def initialize(token)
|
9
|
+
@token = token
|
10
|
+
end
|
11
|
+
|
12
|
+
%w[get post delete put].each do |m|
|
13
|
+
define_method(m) do |path, options = {}, &block|
|
14
|
+
send_request(m.to_sym, path, options, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def send_request(method, path, options, &block)
|
21
|
+
request = Request.new(options.merge!({
|
22
|
+
method: method,
|
23
|
+
token: token,
|
24
|
+
url: "#{Myfinance.configuration.url}#{path}",
|
25
|
+
user_agent: Myfinance.configuration.user_agent
|
26
|
+
}))
|
27
|
+
|
28
|
+
response = Response.new(request.run)
|
29
|
+
|
30
|
+
response.resolve!(&block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Myfinance
|
2
|
+
class Request
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@args = args
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
request.run
|
10
|
+
request.response
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :args
|
16
|
+
|
17
|
+
def request
|
18
|
+
@request ||= Typhoeus::Request.new(args[:url], options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def options
|
22
|
+
{
|
23
|
+
method: args[:method],
|
24
|
+
params: args[:params],
|
25
|
+
body: body,
|
26
|
+
headers: headers,
|
27
|
+
accept_encoding: "gzip"
|
28
|
+
}.reject {|k,v| v.nil?}
|
29
|
+
end
|
30
|
+
|
31
|
+
def headers
|
32
|
+
headers = args.fetch(:headers) { {} }
|
33
|
+
|
34
|
+
{
|
35
|
+
"Accept" => "application/json",
|
36
|
+
"Content-Type" => "application/json",
|
37
|
+
"User-Agent" => args[:user_agent],
|
38
|
+
"Authorization" => "Basic #{authorization_hash}"
|
39
|
+
}.merge(headers)
|
40
|
+
end
|
41
|
+
|
42
|
+
def body
|
43
|
+
body = args[:body]
|
44
|
+
body = MultiJson.dump(body) if body.is_a?(Hash)
|
45
|
+
body
|
46
|
+
end
|
47
|
+
|
48
|
+
def authorization_hash
|
49
|
+
::Base64.strict_encode64("#{args[:token]}:X")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Resources
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_accessor :http
|
6
|
+
|
7
|
+
def initialize(http)
|
8
|
+
@http = http
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def respond_with_collection(response)
|
14
|
+
collection_klass = Myfinance::Entities.const_get("#{entity_klass_name}Collection")
|
15
|
+
collection_klass.build(response)
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_with_object(response, key)
|
19
|
+
entity_klass = Myfinance::Entities.const_get(entity_klass_name)
|
20
|
+
entity_klass.new(response.parsed_body(key))
|
21
|
+
end
|
22
|
+
|
23
|
+
def entity_klass_name
|
24
|
+
self.class.to_s.gsub('Resources', 'Entities')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Resources
|
3
|
+
#
|
4
|
+
# A wrapper to Myfinance entities API
|
5
|
+
#
|
6
|
+
# [API]
|
7
|
+
# Documentation: https://app.myfinance.com.br/docs/api/entities
|
8
|
+
#
|
9
|
+
class Entity < Base
|
10
|
+
#
|
11
|
+
# List all entities of the user
|
12
|
+
#
|
13
|
+
# [API]
|
14
|
+
# Method: <tt>GET /entities</tt>
|
15
|
+
#
|
16
|
+
# Documentation: https://app.myfinance.com.br/docs/api/entities#get_index
|
17
|
+
#
|
18
|
+
def find_all
|
19
|
+
http.get('/entities', body: {}) do |response|
|
20
|
+
respond_with_collection(response)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Find a specific entity
|
26
|
+
#
|
27
|
+
# [API]
|
28
|
+
# Method: <tt>GET /entities/:id</tt>
|
29
|
+
#
|
30
|
+
# Documentation: https://app.myfinance.com.br/docs/api/entities#get_show
|
31
|
+
#
|
32
|
+
def find(entity_id)
|
33
|
+
http.get("/entities/#{entity_id}", body: {}) do |response|
|
34
|
+
respond_with_object(response, 'entity')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Resources
|
3
|
+
class FinancialAccount < Base
|
4
|
+
|
5
|
+
def initialize(http)
|
6
|
+
@http = http
|
7
|
+
set_method_for(pay_or_receive_method)
|
8
|
+
set_method_for(undo_payment_or_receivement)
|
9
|
+
end
|
10
|
+
#
|
11
|
+
# Creates a payable/receivable account
|
12
|
+
#
|
13
|
+
# [API]
|
14
|
+
# Method: <tt>POST /entities/:entity_id/payable_accounts</tt>
|
15
|
+
# Method: <tt>POST /entities/:entity_id/receivable_accounts</tt>
|
16
|
+
#
|
17
|
+
# Documentation: https://app.myfinance.com.br/docs/api/payable_accounts#post_create
|
18
|
+
# Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts#post_create
|
19
|
+
#
|
20
|
+
def create(entity_id, params = {})
|
21
|
+
request_and_build_response(:post, endpoint_for(nil, entity_id, :create), params)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Destroys a payable/receivable account
|
26
|
+
#
|
27
|
+
# [API]
|
28
|
+
# Method: <tt>DELETE /entities/:entity_id/payable_accounts/:id</tt>
|
29
|
+
# Method: <tt>DELETE /entities/:entity_id/receivable_accounts/:id</tt>
|
30
|
+
#
|
31
|
+
# Documentation: https://app.myfinance.com.br/docs/api/payable_accounts#delete_destroy
|
32
|
+
# Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts#delete_destroy
|
33
|
+
#
|
34
|
+
def destroy(id, entity_id)
|
35
|
+
http.delete(endpoint_for(id, entity_id, :destroy)) do |response|
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def request_and_build_response(method, endpoint, params={})
|
43
|
+
http.send(method, endpoint, body: { resource_key => params }) do |response|
|
44
|
+
respond_with_object(response, resource_key)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def endpoint_for(id, entity_id, key)
|
49
|
+
parameterize_endoint(id, entity_id, key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_endpoints
|
53
|
+
{
|
54
|
+
create: "/entities/:entity_id/#{resource_key}s",
|
55
|
+
destroy: "/entities/:entity_id/#{resource_key}s/:id"
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def parameterize_endoint(id, entity_id, key)
|
60
|
+
endpoints[key.to_sym].gsub(':entity_id', entity_id.to_s).gsub(':id', id.to_s)
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_method_for(action)
|
64
|
+
self.class.send(:define_method, action) do |id, entity_id, params={}|
|
65
|
+
request_and_build_response(:put, endpoint_for(id, entity_id, action), params)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Resources
|
3
|
+
#
|
4
|
+
# A wrapper to Myfinance payable accounts API
|
5
|
+
#
|
6
|
+
# [API]
|
7
|
+
# Documentation: https://app.myfinance.com.br/docs/api/payable_accounts
|
8
|
+
#
|
9
|
+
class PayableAccount < FinancialAccount
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def endpoints
|
14
|
+
default_endpoints.merge({
|
15
|
+
pay: '/entities/:entity_id/payable_accounts/:id/pay',
|
16
|
+
undo_payment: '/entities/:entity_id/payable_accounts/:id/undo_payment'
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
def pay_or_receive_method
|
21
|
+
'pay'
|
22
|
+
end
|
23
|
+
|
24
|
+
def undo_payment_or_receivement
|
25
|
+
'undo_payment'
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_key
|
29
|
+
'payable_account'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Myfinance
|
2
|
+
module Resources
|
3
|
+
#
|
4
|
+
# A wrapper to Myfinance receivable accounts API
|
5
|
+
#
|
6
|
+
# [API]
|
7
|
+
# Documentation: https://app.myfinance.com.br/docs/api/receivable_accounts
|
8
|
+
#
|
9
|
+
class ReceivableAccount < FinancialAccount
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def endpoints
|
14
|
+
default_endpoints.merge({
|
15
|
+
receive: '/entities/:entity_id/receivable_accounts/:id/receive',
|
16
|
+
undo_receivement: '/entities/:entity_id/receivable_accounts/:id/undo_receivement',
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
def pay_or_receive_method
|
21
|
+
'receive'
|
22
|
+
end
|
23
|
+
|
24
|
+
def undo_payment_or_receivement
|
25
|
+
'undo_receivement'
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_key
|
29
|
+
'receivable_account'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|