privat_bank_business_api 0.2.1

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 (102) hide show
  1. checksums.yaml +7 -0
  2. data/.devcontainer/Dockerfile +17 -0
  3. data/.devcontainer/devcontainer.json +33 -0
  4. data/.devcontainer/post-create.sh +8 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +9 -0
  7. data/.vscode/settings.json +6 -0
  8. data/CHANGELOG.md +12 -0
  9. data/CODE_OF_CONDUCT.md +132 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +123 -0
  12. data/Rakefile +12 -0
  13. data/lib/pb_api/base_transformer.rb +19 -0
  14. data/lib/pb_api/client.rb +41 -0
  15. data/lib/pb_api/models/balance.rb +79 -0
  16. data/lib/pb_api/models/base_struct.rb +30 -0
  17. data/lib/pb_api/models/transaction.rb +114 -0
  18. data/lib/pb_api/pagination_helper.rb +73 -0
  19. data/lib/pb_api/resource.rb +97 -0
  20. data/lib/pb_api/resources/balance_resource.rb +40 -0
  21. data/lib/pb_api/resources/transaction_resource.rb +105 -0
  22. data/lib/pb_api/transformers/balance_transformer.rb +35 -0
  23. data/lib/pb_api/transformers/transaction_transformer.rb +46 -0
  24. data/lib/pb_api/types.rb +8 -0
  25. data/lib/pb_api/version.rb +5 -0
  26. data/lib/pb_api.rb +34 -0
  27. data/sig/privat_bank_buisness_api.rbs +4 -0
  28. data/sorbet/config +4 -0
  29. data/sorbet/rbi/annotations/.gitattributes +1 -0
  30. data/sorbet/rbi/annotations/faraday.rbi +17 -0
  31. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  32. data/sorbet/rbi/gems/.gitattributes +1 -0
  33. data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
  34. data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
  35. data/sorbet/rbi/gems/bigdecimal@3.1.9.rbi +9 -0
  36. data/sorbet/rbi/gems/concurrent-ruby@1.3.5.rbi +9 -0
  37. data/sorbet/rbi/gems/date@3.4.1.rbi +75 -0
  38. data/sorbet/rbi/gems/diff-lcs@1.6.0.rbi +1134 -0
  39. data/sorbet/rbi/gems/dry-core@1.1.0.rbi +9 -0
  40. data/sorbet/rbi/gems/dry-inflector@1.2.0.rbi +9 -0
  41. data/sorbet/rbi/gems/dry-logic@1.6.0.rbi +9 -0
  42. data/sorbet/rbi/gems/dry-struct@1.7.1.rbi +925 -0
  43. data/sorbet/rbi/gems/dry-transformer@1.0.1.rbi +1512 -0
  44. data/sorbet/rbi/gems/dry-types@1.8.2.rbi +9 -0
  45. data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
  46. data/sorbet/rbi/gems/faraday-em_http@1.0.0.rbi +9 -0
  47. data/sorbet/rbi/gems/faraday-em_synchrony@1.0.0.rbi +9 -0
  48. data/sorbet/rbi/gems/faraday-excon@1.1.0.rbi +9 -0
  49. data/sorbet/rbi/gems/faraday-httpclient@1.0.1.rbi +9 -0
  50. data/sorbet/rbi/gems/faraday-multipart@1.1.0.rbi +9 -0
  51. data/sorbet/rbi/gems/faraday-net_http@1.0.2.rbi +9 -0
  52. data/sorbet/rbi/gems/faraday-net_http_persistent@1.2.0.rbi +9 -0
  53. data/sorbet/rbi/gems/faraday-patron@1.0.0.rbi +9 -0
  54. data/sorbet/rbi/gems/faraday-rack@1.0.0.rbi +9 -0
  55. data/sorbet/rbi/gems/faraday-retry@1.0.3.rbi +9 -0
  56. data/sorbet/rbi/gems/faraday@1.10.4.rbi +9 -0
  57. data/sorbet/rbi/gems/faraday_middleware@1.2.1.rbi +9 -0
  58. data/sorbet/rbi/gems/i18n@1.14.7.rbi +2208 -0
  59. data/sorbet/rbi/gems/ice_nine@0.11.2.rbi +9 -0
  60. data/sorbet/rbi/gems/io-console@0.8.0.rbi +9 -0
  61. data/sorbet/rbi/gems/json@2.10.1.rbi +2120 -0
  62. data/sorbet/rbi/gems/language_server-protocol@3.17.0.4.rbi +9 -0
  63. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +86 -0
  64. data/sorbet/rbi/gems/logger@1.6.6.rbi +940 -0
  65. data/sorbet/rbi/gems/money@6.19.0.rbi +2260 -0
  66. data/sorbet/rbi/gems/multipart-post@2.4.1.rbi +9 -0
  67. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  68. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  69. data/sorbet/rbi/gems/parser@3.3.7.1.rbi +5525 -0
  70. data/sorbet/rbi/gems/pp@0.6.2.rbi +368 -0
  71. data/sorbet/rbi/gems/prettyprint@0.2.0.rbi +477 -0
  72. data/sorbet/rbi/gems/prism@1.3.0.rbi +41403 -0
  73. data/sorbet/rbi/gems/psych@5.2.3.rbi +2435 -0
  74. data/sorbet/rbi/gems/racc@1.8.1.rbi +164 -0
  75. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
  76. data/sorbet/rbi/gems/rake@13.2.1.rbi +3028 -0
  77. data/sorbet/rbi/gems/rbi@0.2.4.rbi +4542 -0
  78. data/sorbet/rbi/gems/rdoc@6.12.0.rbi +12758 -0
  79. data/sorbet/rbi/gems/regexp_parser@2.10.0.rbi +3795 -0
  80. data/sorbet/rbi/gems/reline@0.6.0.rbi +2451 -0
  81. data/sorbet/rbi/gems/rspec-core@3.13.3.rbi +10986 -0
  82. data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
  83. data/sorbet/rbi/gems/rspec-mocks@3.13.2.rbi +5341 -0
  84. data/sorbet/rbi/gems/rspec-support@3.13.2.rbi +1630 -0
  85. data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
  86. data/sorbet/rbi/gems/rubocop-ast@1.38.0.rbi +7654 -0
  87. data/sorbet/rbi/gems/rubocop@1.72.2.rbi +61026 -0
  88. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  89. data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +9 -0
  90. data/sorbet/rbi/gems/spoom@1.5.4.rbi +5026 -0
  91. data/sorbet/rbi/gems/stringio@3.1.5.rbi +9 -0
  92. data/sorbet/rbi/gems/tapioca@0.16.11.rbi +3656 -0
  93. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  94. data/sorbet/rbi/gems/unicode-display_width@3.1.4.rbi +132 -0
  95. data/sorbet/rbi/gems/unicode-emoji@4.0.4.rbi +251 -0
  96. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  97. data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
  98. data/sorbet/rbi/gems/zeitwerk@2.7.2.rbi +9 -0
  99. data/sorbet/rbi/todo.rbi +17 -0
  100. data/sorbet/tapioca/config.yml +13 -0
  101. data/sorbet/tapioca/require.rb +8 -0
  102. metadata +231 -0
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ module Models
5
+ # Transaction model
6
+ #
7
+ # It automatically defines two money helper methods:
8
+ # - amount_money: converts the 'amount' field to Money.
9
+ # - amount_uah_money: converts the 'amount_uah' field to Money using UAH.
10
+ class Transaction < BaseStruct
11
+ # ЄДРПОУ одержувача / Recipient code
12
+ attribute :recipient_code, Types::String
13
+
14
+ # МФО одержувача / Recipient bank code
15
+ attribute :recipient_bank_code, Types::String
16
+
17
+ # Рахунок одержувача / Recipient account
18
+ attribute :recipient_account, Types::String
19
+
20
+ # Назва одержувача / Recipient name
21
+ attribute :recipient_name, Types::String
22
+
23
+ # Банк одержувача / Recipient bank name
24
+ attribute :recipient_bank_name, Types::String
25
+
26
+ # Місто банку одержувача / Recipient bank city
27
+ attribute :recipient_bank_city, Types::String
28
+
29
+ # ЄДРПОУ контрагента / Counterparty code
30
+ attribute :counterparty_code, Types::String
31
+
32
+ # МФО контрагента / Counterparty bank code
33
+ attribute :counterparty_bank_code, Types::String
34
+
35
+ # Рахунок контрагента / Counterparty account
36
+ attribute :counterparty_account, Types::String
37
+
38
+ # Назва контрагента / Counterparty name
39
+ attribute :counterparty_name, Types::String
40
+
41
+ # Банк контрагента / Counterparty bank name
42
+ attribute :counterparty_bank_name, Types::String
43
+
44
+ # Місто банку контрагента / Counterparty bank city
45
+ attribute :counterparty_bank_city, Types::String
46
+
47
+ # Валюта / Currency
48
+ attribute :currency, Types::String
49
+
50
+ # Ознака реальності проведення (r,i) / Indicates if the transaction is real (r) or imaginary (i)
51
+ attribute :real, Types::String
52
+
53
+ # Стан транзакції: p - проводиться, t - сторнована, r - проведена, n - забракована
54
+ # / Transaction status: p - processing, t - reversed, r - completed, n - rejected
55
+ attribute :status, Types::String
56
+
57
+ # Тип платіжного документа / Document type
58
+ attribute :document_type, Types::String
59
+
60
+ # Номер документа / Document number
61
+ attribute :document_number, Types::String
62
+
63
+ # Клієнтська дата (дд.мм.рррр) / Client date (dd.mm.yyyy)
64
+ attribute :client_date, Types::Params::DateTime
65
+
66
+ # Дата валютування (дд.мм.рррр) / Valuation date (dd.mm.yyyy)
67
+ attribute :valuation_date, Types::Params::DateTime
68
+
69
+ # Підстава платежу / Payment reason
70
+ attribute :reason, Types::String
71
+
72
+ # Сума / Amount
73
+ attribute :amount, Types::Coercible::Decimal
74
+
75
+ # Сума в національній валюті (грн) / Amount in UAH (national currency)
76
+ attribute :amount_uah, Types::Coercible::Decimal
77
+
78
+ # Референс проведення / Transaction reference
79
+ attribute :reference, Types::String
80
+
81
+ # Номер з/п всередині проведення / Internal sequence number within the transaction
82
+ attribute :reference_number, Types::String
83
+
84
+ # Час проведення (HH:MM) / Transaction time (HH:MM)
85
+ attribute :valuation_time, Types::JSON::Time
86
+
87
+ # Дата і час валютування (дд.мм.рррр HH:MM:SS) / Valuation date and time (dd.mm.yyyy HH:MM:SS)
88
+ attribute :valuation_date_time, Types::Params::DateTime
89
+
90
+ # ID транзакції / Transaction ID
91
+ attribute :id, Types::String
92
+
93
+ # Тип транзакції дебет/кредит (D, C) / Transaction type (debit/credit: D, C)
94
+ attribute :transaction_type, Types::String
95
+
96
+ # Референс платежу сервісу / Service payment reference
97
+ attribute :service_reference, Types::String
98
+
99
+ # Технічний ідентифікатор транзакції / Technical transaction ID
100
+ attribute :technical_id, Types::String
101
+
102
+ MONEY_FIELDS = %i[
103
+ amount amount_uah
104
+ ].freeze
105
+
106
+ MONEY_FIELDS.each do |field|
107
+ define_method("#{field}_money") do
108
+ currency_to_use = field.to_s.end_with?("_uah") ? "UAH" : currency
109
+ Money.from_amount(public_send(field), currency_to_use)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ # PaginationHelper provides pagination functionality by yielding individual items
5
+ # from paginated HTTP responses.
6
+ # @example
7
+ # Example of usage:
8
+ # class BalanceResource < PbAPI::Resource
9
+ # def common(uri, key, start_date, account, end_date)
10
+ # params_hash = form_query(start_date, account, end_date, nil, 20)
11
+ # # Pass a block to handle the HTTP request using your resource's get_request method.
12
+ # PbAPI::PaginationHelper
13
+ # .load(uri: uri, params_hash: params_hash, key: "balances", type: PbAPI::Models::Balance) do |uri, params|
14
+ # get_request(uri, params: params)
15
+ # end
16
+ # end
17
+ # end
18
+ class PaginationHelper < Dry::Struct
19
+ # @!attribute [r] data
20
+ # @return [Array] Array of transformed models.
21
+ attribute :data, Types::Array.of(Types::Any)
22
+ # @!attribute [r] next_page_exists
23
+ # @return [Boolean] Indicates if the next page exists.
24
+ attribute :next_page_exists, Types::Bool
25
+ # @!attribute [r] next_page_id
26
+ # @return [Any, nil] The identifier for the next page.
27
+ attribute :next_page_id, Types::Any.optional
28
+
29
+ # Loads paginated data and yields individual items.
30
+ #
31
+ # See example of usage in the class description.
32
+ #
33
+ # @param params_hash [Hash] Query parameters for the HTTP request.
34
+ # @param key [String, Symbol] The key to extract data from the response body.
35
+ # @param type [Class] A Dry::Struct model class used for transforming each item.
36
+ # @yield [params] Must perform the HTTP request and return a response object.
37
+ # @yieldreturn [Array] The HTTP response with a 'body' method containing a hash.
38
+ # @return [Enumerator] An enumerator yielding individual items.
39
+ def self.paginate(params_hash:, key:, type:)
40
+ Enumerator.new do |yielder|
41
+ last_page_id = 0
42
+ loop do
43
+ # The block is used to perform the HTTP request, decoupling the helper from the client.
44
+ response = yield(params_hash)
45
+ processed = from_response(response_body: response.body, key: key, type: type)
46
+ processed.data.each { |item| yielder << item }
47
+ break unless processed.next_page_exists && processed.next_page_id != last_page_id
48
+
49
+ last_page_id = params_hash[:followId] = processed.next_page_id
50
+ end
51
+ end
52
+ end
53
+
54
+ # Transforms the HTTP response and returns a new instance of PaginationHelper.
55
+ #
56
+ # @param response_body [Hash] The parsed HTTP response body.
57
+ # @param key [String, Symbol] The key that holds the array of items.
58
+ # @param type [Class] A Dry::Struct model class used to encapsulate each item.
59
+ # @return [PaginationHelper] An instance containing the transformed data and pagination flags.
60
+ def self.from_response(response_body:, key:, type:)
61
+ body = response_body
62
+
63
+ transformer = type.transformer
64
+ transformed = transformer.call(body[key])
65
+ # Create an array of Balance models from the transformed hashes
66
+ new(
67
+ data: transformed.map { |hash| type.new(hash) },
68
+ next_page_exists: body["exist_next_page"],
69
+ next_page_id: body["next_page_id"]
70
+ )
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module PbAPI
5
+ # internal
6
+ class Resource
7
+ DATE_FORMAT_STRING = "%d-%m-%Y"
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ end
13
+
14
+ ##
15
+ # Builds the query parameters hash for API requests.
16
+ #
17
+ # This method generates a hash of query parameters based on the provided options.
18
+ # It is designed to work with multiple endpoints:
19
+ #
20
+ # 1. **Date Interval Endpoints** (e.g., balances or transactions):
21
+ # - Requires :start_date (formatted as DD-MM-YYYY)
22
+ # - Optionally includes :end_date (formatted as DD-MM-YYYY)
23
+ # - :acc (account IBAN) is optional; if omitted, data for all active accounts are returned.
24
+ #
25
+ # 2. **Interim/Final Endpoints** (for getting partial or final data):
26
+ # - Date parameters are omitted.
27
+ # - Only :acc, :follow_id, and :limit are used.
28
+ #
29
+ # Additionally, if the API response contains:
30
+ # - "exist_next_page" as true, then the "next_page_id" value should be passed in subsequent requests
31
+ # using the :follow_id parameter.
32
+ #
33
+ # @param start_date [Date, nil] the starting date (required for date interval endpoints)
34
+ # @param end_date [Date, nil] the ending date (optional)
35
+ # @param account [String, nil] the account number (IBAN); mapped to :acc in the query
36
+ # @param follow_id [String, nil] identifier for the next page of results (pagination)
37
+ # @param limit [Integer] number of records per page (default: 20, maximum recommended: 100)
38
+ #
39
+ # @return [Hash] the query parameters hash to be appended to the request URL
40
+ def form_query(start_date: nil, end_date: nil, account: nil, follow_id: nil, limit: 20)
41
+ params = {}
42
+ # For date interval endpoints, only add date parameters if provided.
43
+ params[:startDate] = start_date.strftime(DATE_FORMAT_STRING) if start_date
44
+ params[:endDate] = end_date.strftime(DATE_FORMAT_STRING) if end_date
45
+ # Account number is expected under the key :acc by the API.
46
+ params[:acc] = account if account
47
+ # Pagination parameter.
48
+ params[:followId] = follow_id if follow_id
49
+ # Set limit for results per page.
50
+ params[:limit] = limit
51
+ params
52
+ end
53
+
54
+ private
55
+
56
+ def get_request(url, params: {}, headers: {})
57
+ handle_response client.connection.get(url, params, headers)
58
+ end
59
+
60
+ def post_request(url, body:, headers: {})
61
+ handle_response client.connection.post(url, body, headers)
62
+ end
63
+
64
+ def patch_request(url, body:, headers: {})
65
+ handle_response client.connection.patch(url, body, headers)
66
+ end
67
+
68
+ def put_request(url, body:, headers: {})
69
+ handle_response client.connection.put(url, body, headers)
70
+ end
71
+
72
+ def delete_request(url, params: {}, headers: {})
73
+ handle_response client.connection.delete(url, params, headers)
74
+ end
75
+
76
+ def handle_response(response)
77
+ case response.status
78
+ when 400
79
+ raise Error, "Your request was malformed. #{response.body["message"]}"
80
+ when 401
81
+ raise Error, "You did not supply valid authentication credentials. #{response.body["message"]}"
82
+ when 403
83
+ raise Error, "You are not allowed to perform that action. #{response.body["message"]}"
84
+ when 404
85
+ raise Error, "No results were found for your request. #{response.body["message"]}"
86
+ when 429
87
+ raise Error, "Your request exceeded the API rate limit. #{response.body["message"]}"
88
+ when 500
89
+ raise Error, "We were unable to perform the request due to server-side problems. #{response.body["message"]}"
90
+ else
91
+ raise Error, response.body["message"] unless response.status == 200
92
+ end
93
+
94
+ response
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module PbAPI
5
+ module Resources
6
+ # see api docs
7
+ class BalanceResource < PbAPI::Resource
8
+ def common(uri, _key, start_date, account, end_date)
9
+ params_hash = form_query(start_date:, account:, end_date:)
10
+ # Pass a block to handle the HTTP request using your resource's get_request method.
11
+
12
+ PbAPI::PaginationHelper
13
+ .paginate(params_hash:, key: "balances", type: PbAPI::Models::Balance) do |params|
14
+ get_request(uri, params: params)
15
+ end
16
+ end
17
+
18
+ # Get balance(s)
19
+ # start_date required
20
+ # account(iban string) and end_date optional
21
+ def list(start_date, account = nil, end_date = nil)
22
+ common("statements/balance", "balances", start_date, account, end_date)
23
+ end
24
+
25
+ # Get interim balance(s)
26
+ #
27
+ # @param start_date [String] the start date for the balance query (required)
28
+ # @param account [String, nil] the account IBAN (optional)
29
+ # @return [Array<PbAPI::Models::Balance>] an array of Balance models
30
+ def list_interim(start_date, account = nil, end_date = nil)
31
+ common("statements/balance/interim", "balances", start_date, account, end_date)
32
+ end
33
+
34
+ # account = string iban, optional
35
+ def list_final(account = nil)
36
+ common("statements/balance/final", "balances", start_date, account, end_date)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module PbAPI
5
+ module Resources
6
+ ##
7
+ # TransactionResource is responsible for fetching transaction data from the API.
8
+ # It supports three endpoints:
9
+ #
10
+ # 1. Standard transactions endpoint (with a date interval).
11
+ # 2. Interim transactions endpoint (for data from the last day up to today).
12
+ # 3. Final transactions endpoint (for final transactions on the last day).
13
+ #
14
+ # Each endpoint is paginated. The methods in this class return an Enumerator that
15
+ # lazily fetches and yields transactions page by page.
16
+ class TransactionResource < PbAPI::Resource
17
+ # TODO: make common method private, or refactor it into a parent class. In all classes
18
+
19
+ ##
20
+ # Executes a paginated request for transactions.
21
+ #
22
+ # @param uri [String] the API endpoint URI (e.g., "statements/transactions",
23
+ # "statements/transactions/interim", or "statements/transactions/final").
24
+ # @param query_params [Hash] the query parameters generated by form_query.
25
+ #
26
+ # @return [Enumerator] an enumerator that yields each transaction as it is fetched.
27
+ def common(uri:, query_params:)
28
+ PbAPI::PaginationHelper
29
+ .paginate(params_hash: query_params, key: "transactions", type: PbAPI::Models::Transaction) do |params|
30
+ get_request(uri, params: params)
31
+ end
32
+ end
33
+
34
+ ##
35
+ # Retrieves transactions for a specified date range.
36
+ #
37
+ # This method is used when you need to filter transactions by a start (and optional end) date.
38
+ # @example
39
+ # transactions = PbAPI::Client.transactions.list(
40
+ # start_date: Date.new(2025, 2, 1),
41
+ # end_date: Date.new(2025, 2, 28),
42
+ # account: "UA1234567890",
43
+ # results_per_page: 50
44
+ # )
45
+ #
46
+ # @param start_date [Date] the starting date (required).
47
+ # @param end_date [Date, nil] the ending date (optional).
48
+ # @param account [String, nil] the account IBAN (optional). If omitted, data for all active accounts are returned.
49
+ # @param next_page_id [String, nil] an identifier for the next page (pagination).
50
+ # @param results_per_page [Integer] number of records per page (default: 20; maximum recommended: 100).
51
+ #
52
+ # @return [Enumerator] an enumerator that yields transaction objects.
53
+ def list(start_date:, end_date: nil, account: nil, next_page_id: nil, results_per_page: 20)
54
+ query_params = form_query(
55
+ start_date:,
56
+ end_date:,
57
+ account:,
58
+ follow_id: next_page_id,
59
+ limit: results_per_page
60
+ )
61
+ common(uri: "statements/transactions", query_params: query_params)
62
+ end
63
+
64
+ ##
65
+ # Retrieves interim transactions.
66
+ #
67
+ # Interim endpoints do not require date parameters; they return transactions
68
+ # for the period from the last day to today.
69
+ #
70
+ # @param account [String, nil] the account IBAN (optional).
71
+ # @param next_page_id [String, nil] an identifier for the next page (pagination).
72
+ # @param results_per_page [Integer] number of records per page (default: 20).
73
+ #
74
+ # @return [Enumerator] an enumerator that yields interim transaction objects.
75
+ def list_interim(account: nil, next_page_id: nil, results_per_page: 20)
76
+ query_params = form_query(
77
+ account: account,
78
+ follow_id: next_page_id,
79
+ limit: results_per_page
80
+ )
81
+ common(uri: "statements/transactions/interim", query_params: query_params)
82
+ end
83
+
84
+ ##
85
+ # Retrieves final transactions.
86
+ #
87
+ # Final endpoints return transactions for the final (last) day.
88
+ # Like the interim endpoint, date parameters are not required.
89
+ #
90
+ # @param account [String, nil] the account IBAN (optional).
91
+ # @param next_page_id [String, nil] an identifier for the next page (pagination).
92
+ # @param results_per_page [Integer] number of records per page (default: 20).
93
+ #
94
+ # @return [Enumerator] an enumerator that yields final transaction objects.
95
+ def list_final(account: nil, next_page_id: nil, results_per_page: 20)
96
+ query_params = form_query(
97
+ account: account,
98
+ follow_id: next_page_id,
99
+ limit: results_per_page
100
+ )
101
+ common(uri: "statements/transactions/final", query_params: query_params)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ module Transformers
5
+ # balance field name mappings
6
+ class BalanceTransformer < PbAPI::BaseTransformer
7
+ # Define the mapping for keys that need renaming
8
+ KEY_MAPPING = {
9
+ "acc" => :account,
10
+ "atp" => :account_type,
11
+ "currency" => :currency,
12
+ "flmn" => :location,
13
+ "state" => :state,
14
+ "balanceIn" => :balance_in,
15
+ "balanceInEq" => :balance_in_uah,
16
+ "balanceOut" => :balance_out,
17
+ "balanceOutEq" => :balance_out_uah,
18
+ "turnoverDebt" => :turnover_debt,
19
+ "turnoverDebtEq" => :turnover_debt_uah,
20
+ "turnoverCred" => :turnover_cred,
21
+ "turnoverCredEq" => :turnover_cred_uah,
22
+ "bgfIBrnm" => :counterparty_branch,
23
+ "brnm" => :account_branch,
24
+ "dpd" => :last_operation_date_time,
25
+ "nameACC" => :account_name,
26
+ "date_open_acc_reg" => :open_account_reg_date_time,
27
+ "date_open_acc_sys" => :open_account_sys_date_time,
28
+ "date_close_acc" => :close_account_date_time,
29
+ "is_final_bal" => :final_balance
30
+ }.freeze
31
+
32
+ build_pipeline(KEY_MAPPING)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ module Transformers
5
+ # transaction field name mappings
6
+ class TransactionTransformer < PbAPI::BaseTransformer
7
+ # Define the mapping for keys that need renaming
8
+ # rubocop:disable Layout/HashAlignment
9
+ KEY_MAPPING = {
10
+ "AUT_MY_CRF" => :recipient_code,
11
+ "AUT_MY_MFO" => :recipient_bank_code,
12
+ "AUT_MY_ACC" => :recipient_account,
13
+ "AUT_MY_NAM" => :recipient_name,
14
+ "AUT_MY_MFO_NAME" => :recipient_bank_name,
15
+ "AUT_MY_MFO_CITY" => :recipient_bank_city,
16
+ "AUT_CNTR_CRF" => :counterparty_code,
17
+ "AUT_CNTR_MFO" => :counterparty_bank_code,
18
+ "AUT_CNTR_ACC" => :counterparty_account,
19
+ "AUT_CNTR_NAM" => :counterparty_name,
20
+ "AUT_CNTR_MFO_NAME" => :counterparty_bank_name,
21
+ "AUT_CNTR_MFO_CITY" => :counterparty_bank_city,
22
+ "CCY" => :currency,
23
+ "FL_REAL" => :real,
24
+ "PR_PR" => :status,
25
+ "DOC_TYP" => :document_type,
26
+ "NUM_DOC" => :document_number,
27
+ "DAT_KL" => :client_date,
28
+ "DAT_OD" => :valuation_date,
29
+ "OSND" => :reason,
30
+ "SUM" => :amount,
31
+ "SUM_E" => :amount_uah,
32
+ "REF" => :reference,
33
+ "REFN" => :reference_number,
34
+ "TIM_P" => :valuation_time,
35
+ "DATE_TIME_DAT_OD_TIM_P" => :valuation_date_time,
36
+ "ID" => :id,
37
+ "TRANTYPE" => :transaction_type,
38
+ "DLR" => :service_reference,
39
+ "TECHNICAL_TRANSACTION_ID" => :technical_id
40
+ }.freeze
41
+ # rubocop:enable Layout/HashAlignment
42
+
43
+ build_pipeline(KEY_MAPPING)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ # best practices
5
+ module Types
6
+ include Dry.Types()
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PbAPI
4
+ VERSION = "0.2.1"
5
+ end
data/lib/pb_api.rb ADDED
@@ -0,0 +1,34 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "faraday"
5
+ require "faraday_middleware"
6
+ require "dry-types"
7
+ require "dry-struct"
8
+ require "dry-transformer"
9
+ require "money"
10
+
11
+ require_relative "pb_api/version"
12
+ require_relative "pb_api/types"
13
+ require_relative "pb_api/client"
14
+ require_relative "pb_api/resource"
15
+ require_relative "pb_api/base_transformer"
16
+ require_relative "pb_api/models/base_struct"
17
+
18
+ require_relative "pb_api/resources/balance_resource"
19
+ require_relative "pb_api/transformers/balance_transformer"
20
+ require_relative "pb_api/models/balance"
21
+
22
+ require_relative "pb_api/resources/transaction_resource"
23
+ require_relative "pb_api/transformers/transaction_transformer"
24
+ require_relative "pb_api/models/transaction"
25
+ require_relative "pb_api/pagination_helper"
26
+
27
+ # Main entry point for the gem, use client = PbAPI::Client.new(api_token: "token") to start using the API.
28
+ module PbAPI
29
+ class Error < StandardError; end
30
+
31
+ def self.logger
32
+ @@logger ||= defined?(Rails) ? Rails.logger : Logger.new($stdout, progname: "PbApi") # rubocop:disable Style/ClassVars
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ module PrivatBankBusinessApi
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
data/sorbet/config ADDED
@@ -0,0 +1,4 @@
1
+ --dir
2
+ .
3
+ --ignore=tmp/
4
+ --ignore=vendor/
@@ -0,0 +1 @@
1
+ **/*.rbi linguist-vendored=true
@@ -0,0 +1,17 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Faraday
8
+ class << self
9
+ sig { params(url: T.untyped, options: T::Hash[Symbol, T.untyped], block: T.nilable(T.proc.params(connection: Faraday::Connection).void)).returns(Faraday::Connection) }
10
+ def new(url = nil, options = {}, &block); end
11
+ end
12
+ end
13
+
14
+ class Faraday::Response
15
+ sig { returns(T::Boolean) }
16
+ def success?; end
17
+ end