bridge_bankin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ module API
5
+ class Error < StandardError
6
+ def initialize(code, response_body = {})
7
+ @payload = response_body
8
+ @code = code
9
+ @type = payload[:type]
10
+ @documentation_url = payload[:documentation_url]
11
+
12
+ super(payload[:message])
13
+ end
14
+
15
+ attr_reader :payload, :code, :type, :documentation_url
16
+ end
17
+
18
+ class BadRequestError < Error; end
19
+
20
+ class UnauthorizedError < Error; end
21
+
22
+ class ForbiddenError < Error; end
23
+
24
+ class NotFoundError < Error; end
25
+
26
+ class ConflictError < Error; end
27
+
28
+ class UnsupportedMediaTypeError < Error; end
29
+
30
+ class UnprocessableEntityError < Error; end
31
+
32
+ class TooManyRequestsError < Error; end
33
+
34
+ class InternalServerError < Error; end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ module API
5
+ module Resource
6
+ def protected_resource(access_token)
7
+ api_client.access_token = access_token
8
+ yield
9
+ end
10
+
11
+ private
12
+
13
+ def api_client
14
+ @api_client ||= API::Client.new
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ module BridgeBankin
6
+ class Authorization
7
+ attr_reader :access_token, :expires_at
8
+
9
+ def initialize(access_token, expires_at)
10
+ @access_token = access_token
11
+ @expires_at = Time.parse(expires_at)
12
+ end
13
+
14
+ class << self
15
+ include API::Resource
16
+
17
+ def generate_token(email:, password:)
18
+ response = api_client.post("/v2/authenticate", email: email, password: password)
19
+ new(response[:access_token], response[:expires_at])
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Bank < BridgeObject
5
+ RESOURCE_TYPE = "bank"
6
+
7
+ class << self
8
+ include API::Resource
9
+
10
+ def list(**params)
11
+ data = api_client.get("/v2/banks", params)
12
+ convert_to_bridge_object(data)
13
+ end
14
+
15
+ def find(id:, **params)
16
+ data = api_client.get("/v2/banks/#{id}", params)
17
+ convert_to_bridge_object(data)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class BridgeObject
5
+ HIDDEN_ATTRIBUTES = %i[resource_type resource_uri].freeze
6
+
7
+ def initialize(**attrs)
8
+ define_instance_variables(attrs)
9
+ end
10
+
11
+ class << self
12
+ def convert_to_bridge_object(**data)
13
+ if data[:resources]
14
+ data[:resources].map { |resource| convert_to_bridge_object(resource) }
15
+ elsif data.is_a?(Array)
16
+ data.map { |val| convert_to_bridge_object(val) }
17
+ else
18
+ object_from_resource_type(data)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def object_classes
25
+ @object_classes ||= ObjectTypes.resource_types_to_classes
26
+ end
27
+
28
+ def object_from_resource_type(data)
29
+ object_classes.fetch(data[:resource_type], BridgeObject).new(data)
30
+ end
31
+ end
32
+
33
+ def to_hash
34
+ instance_variables.each_with_object({}) do |var, hash|
35
+ hash[var.to_s.delete("@")] =
36
+ case instance_variable_get(var)
37
+ when BridgeObject
38
+ instance_variable_get(var).to_hash
39
+ when Array
40
+ instance_variable_get(var).map { |val| val.is_a?(BridgeObject) ? val.to_hash : val }
41
+ else
42
+ instance_variable_get(var)
43
+ end
44
+ end.transform_keys!(&:to_sym)
45
+ end
46
+
47
+ def to_json(*_args)
48
+ to_hash.to_json
49
+ end
50
+
51
+ def ==(other)
52
+ other.is_a?(BridgeObject) && to_hash == other.to_hash
53
+ end
54
+
55
+ private
56
+
57
+ def define_instance_variables(attrs)
58
+ attrs.each do |key, value|
59
+ next if HIDDEN_ATTRIBUTES.include?(key)
60
+
61
+ handle_values_types(key, value) do |parsed_value|
62
+ instance_variable_set("@#{key}".to_sym, parsed_value)
63
+ self.class.class_eval { attr_reader key }
64
+ end
65
+ end
66
+ end
67
+
68
+ def handle_values_types(key, value)
69
+ yield(
70
+ case value
71
+ when Array
72
+ handle_array_values(value)
73
+ when Hash
74
+ handle_hash_values(value)
75
+ when String
76
+ handle_time_values(key, value)
77
+ else
78
+ value
79
+ end
80
+ )
81
+ end
82
+
83
+ def handle_array_values(array)
84
+ array.map do |value|
85
+ next value unless value.is_a?(Hash)
86
+
87
+ handle_hash_values(value)
88
+ end
89
+ end
90
+
91
+ def handle_hash_values(hash)
92
+ self.class.convert_to_bridge_object(hash)
93
+ end
94
+
95
+ def handle_time_values(key, value)
96
+ if key == :date
97
+ Date.parse(value)
98
+ elsif key.to_s.match?(/_at$/)
99
+ Time.parse(value)
100
+ else
101
+ value
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Category < BridgeObject
5
+ RESOURCE_TYPE = "category"
6
+
7
+ class << self
8
+ include API::Resource
9
+
10
+ def list(**params)
11
+ data = api_client.get("/v2/categories", params)
12
+ convert_to_bridge_object(data)
13
+ end
14
+
15
+ def find(id:, **params)
16
+ data = api_client.get("/v2/categories/#{id}", params)
17
+ convert_to_bridge_object(data)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ def self.configuration
5
+ @configuration ||= Configuration.new
6
+ end
7
+
8
+ def self.configuration=(config)
9
+ @configuration = config
10
+ end
11
+
12
+ def self.configure
13
+ yield configuration
14
+ end
15
+
16
+ class Configuration
17
+ attr_reader :api_base_url, :api_version
18
+ attr_accessor :api_client_id, :api_client_secret
19
+
20
+ def initialize
21
+ @api_base_url = "https://sync.bankin.com"
22
+ @api_version = "2019-02-18"
23
+ @api_client_id = "d16099aec29e445dbb31cf3966b3821e"
24
+ @api_client_secret = "HEb73vHEGB4Hunv5OMXFUDNIgNonYJ89YaHHRSyidVgCPbCtFWqtED5fZYObA0lm"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Connect < BridgeObject
5
+ class << self
6
+ include API::Resource
7
+
8
+ def connect_item(access_token:, **params)
9
+ protected_resource(access_token) do
10
+ data = api_client.get("/v2/connect/items/add/url", params)
11
+ convert_to_bridge_object(data)
12
+ end
13
+ end
14
+
15
+ def connect_item_with_iban(access_token:, **params)
16
+ protected_resource(access_token) do
17
+ data = api_client.post("/v2/connect/items/add/url", params)
18
+ convert_to_bridge_object(data)
19
+ end
20
+ end
21
+
22
+ def edit_item(access_token:, **params)
23
+ protected_resource(access_token) do
24
+ data = api_client.get("/v2/connect/items/edit/url", params)
25
+ convert_to_bridge_object(data)
26
+ end
27
+ end
28
+
29
+ def item_sync(access_token:, **params)
30
+ protected_resource(access_token) do
31
+ data = api_client.get("/v2/connect/items/sync", params)
32
+ convert_to_bridge_object(data)
33
+ end
34
+ end
35
+
36
+ def validate_email(access_token:, **params)
37
+ protected_resource(access_token) do
38
+ data = api_client.get("/v2/connect/users/email/confirmation/url", params)
39
+ convert_to_bridge_object(data)
40
+ end
41
+ end
42
+
43
+ def validate_pro_items(access_token:, **params)
44
+ protected_resource(access_token) do
45
+ data = api_client.get("/v2/connect/items/pro/confirmation/url", params)
46
+ convert_to_bridge_object(data)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Insight < BridgeObject
5
+ class << self
6
+ include API::Resource
7
+
8
+ def categories_insights(access_token:, **params)
9
+ protected_resource(access_token) do
10
+ data = api_client.get("/v2/insights/category", params)
11
+ convert_to_bridge_object(data)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Item < BridgeObject
5
+ RESOURCE_TYPE = "item"
6
+
7
+ # TODO: Add support of item statuses
8
+
9
+ class << self
10
+ include API::Resource
11
+
12
+ def list(access_token:, **params)
13
+ protected_resource(access_token) do
14
+ data = api_client.get("/v2/items", params)
15
+ convert_to_bridge_object(data)
16
+ end
17
+ end
18
+
19
+ def find(id:, access_token:, **params)
20
+ protected_resource(access_token) do
21
+ data = api_client.get("/v2/items/#{id}", params)
22
+ convert_to_bridge_object(data)
23
+ end
24
+ end
25
+
26
+ def refresh(id:, access_token:, **params)
27
+ protected_resource(access_token) do
28
+ data = api_client.post("/v2/items/#{id}/refresh", params)
29
+ convert_to_bridge_object(data)
30
+ end
31
+ end
32
+
33
+ def refresh_status(id:, access_token:, **params)
34
+ protected_resource(access_token) do
35
+ data = api_client.get("/v2/items/#{id}/refresh/status", params)
36
+ convert_to_bridge_object(data)
37
+ end
38
+ end
39
+
40
+ def delete(id:, access_token:, **params)
41
+ protected_resource(access_token) do
42
+ data = api_client.delete("/v2/items/#{id}", params)
43
+ convert_to_bridge_object(data)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ module ObjectTypes
5
+ def self.resource_types_to_classes
6
+ {
7
+ Account::RESOURCE_TYPE => Account,
8
+ Bank::RESOURCE_TYPE => Bank,
9
+ Category::RESOURCE_TYPE => Category,
10
+ Item::RESOURCE_TYPE => Item,
11
+ Stock::RESOURCE_TYPE => Stock,
12
+ Transaction::RESOURCE_TYPE => Transaction,
13
+ Transfer::RESOURCE_TYPE => Transfer,
14
+ User::RESOURCE_TYPE => User
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bridge_bankin/authorization"
4
+ require "bridge_bankin/account"
5
+ require "bridge_bankin/category"
6
+ require "bridge_bankin/stock"
7
+ require "bridge_bankin/bank"
8
+ require "bridge_bankin/user"
9
+ require "bridge_bankin/connect"
10
+ require "bridge_bankin/item"
11
+ require "bridge_bankin/transaction"
12
+ require "bridge_bankin/transfer"
13
+ require "bridge_bankin/insight"
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Stock < BridgeObject
5
+ RESOURCE_TYPE = "stock"
6
+
7
+ class << self
8
+ include API::Resource
9
+
10
+ def list(**params)
11
+ data = api_client.get("/v2/stocks", params)
12
+ convert_to_bridge_object(data)
13
+ end
14
+
15
+ def list_updated(**params)
16
+ data = api_client.get("/v2/stocks/updated", params)
17
+ convert_to_bridge_object(data)
18
+ end
19
+
20
+ def find(id:, **params)
21
+ data = api_client.get("/v2/stocks/#{id}", params)
22
+ convert_to_bridge_object(data)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BridgeBankin
4
+ class Transaction < BridgeObject
5
+ RESOURCE_TYPE = "transaction"
6
+
7
+ class << self
8
+ include API::Resource
9
+
10
+ def list(access_token:, **params)
11
+ protected_resource(access_token) do
12
+ data = api_client.get("/v2/transactions", params)
13
+ convert_to_bridge_object(data)
14
+ end
15
+ end
16
+
17
+ def list_updated(access_token:, **params)
18
+ protected_resource(access_token) do
19
+ data = api_client.get("/v2/transactions/updated", params)
20
+ convert_to_bridge_object(data)
21
+ end
22
+ end
23
+
24
+ def find(id:, access_token:, **params)
25
+ protected_resource(access_token) do
26
+ data = api_client.get("/v2/transactions/#{id}", params)
27
+ convert_to_bridge_object(data)
28
+ end
29
+ end
30
+
31
+ def list_by_account(account_id:, access_token:, **params)
32
+ protected_resource(access_token) do
33
+ data = api_client.get("/v2/accounts/#{account_id}/transactions", params)
34
+ convert_to_bridge_object(data)
35
+ end
36
+ end
37
+
38
+ def list_updated_by_account(account_id:, access_token:, **params)
39
+ protected_resource(access_token) do
40
+ data = api_client.get("/v2/accounts/#{account_id}/transactions/updated", params)
41
+ convert_to_bridge_object(data)
42
+ end
43
+ end
44
+
45
+ def list_by_iban(access_token:, **params)
46
+ protected_resource(access_token) do
47
+ data = api_client.post("/v2/transactions/search", params)
48
+ convert_to_bridge_object(data)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end