tochka_cyclops_api 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
 - data/README.md +65 -8
 - data/Rakefile +0 -4
 - data/lib/tasks/methods.rake +11 -0
 - data/lib/tochka_cyclops_api/data_processor.rb +44 -19
 - data/lib/tochka_cyclops_api/generators/templates/tochka_cyclops_request_model_template.rb +1 -1
 - data/lib/tochka_cyclops_api/generators/templates/tochka_cyclops_responses_migration_template.rb +1 -1
 - data/lib/tochka_cyclops_api/methods.rb +198 -5
 - data/lib/tochka_cyclops_api/request.rb +66 -31
 - data/lib/tochka_cyclops_api/response.rb +27 -34
 - data/lib/tochka_cyclops_api/result.rb +33 -0
 - data/lib/tochka_cyclops_api/schemas/requests/activate_beneficiary.rb +22 -0
 - data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_fl.rb +56 -0
 - data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_ip.rb +22 -10
 - data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_ul.rb +22 -10
 - data/lib/tochka_cyclops_api/schemas/requests/deactivate_beneficiary.rb +22 -0
 - data/lib/tochka_cyclops_api/schemas/requests/echo.rb +2 -0
 - data/lib/tochka_cyclops_api/schemas/requests/get_beneficiary.rb +22 -0
 - data/lib/tochka_cyclops_api/schemas/requests/list_beneficiary.rb +44 -0
 - data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_fl.rb +51 -0
 - data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_ip.rb +39 -0
 - data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_ul.rb +38 -0
 - data/lib/tochka_cyclops_api/schemas/responses/activate_beneficiary.rb +24 -0
 - data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_fl.rb +24 -0
 - data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_ip.rb +10 -1
 - data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_ul.rb +9 -9
 - data/lib/tochka_cyclops_api/schemas/responses/deactivate_beneficiary.rb +24 -0
 - data/lib/tochka_cyclops_api/schemas/responses/echo.rb +1 -1
 - data/lib/tochka_cyclops_api/schemas/responses/error.rb +5 -2
 - data/lib/tochka_cyclops_api/schemas/responses/get_beneficiary.rb +48 -0
 - data/lib/tochka_cyclops_api/schemas/responses/list_beneficiary.rb +38 -0
 - data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_fl.rb +20 -0
 - data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_ip.rb +20 -0
 - data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_ul.rb +24 -0
 - data/lib/tochka_cyclops_api/schemas/results/local_error.rb +0 -0
 - data/lib/tochka_cyclops_api/test.rb +0 -0
 - data/lib/tochka_cyclops_api/version.rb +1 -1
 - data/lib/tochka_cyclops_api.rb +5 -2
 - metadata +22 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 36957c52f3476c825762fda41ec211a1a55d7eb15337c3eae48e32cb38d61419
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: d3d39943258ce772f1a8f949c5bcee9f1abb692d189775b67c0873d2ab98ebd4
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: '096c88b4842314462b00977f267448bb6a3ee4043dc0b3d0efd921806f14be7655d43122b2e476216df9775b93fdf2cc214d119f95177c80cc6dad3ab41a43a1'
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9ebfe7d51a013072ddfa6b6ba33dcb767262a93eb1f57fd4c59aa1147422cf4377bcbe1f2683625c6e2d7495b48b348f882c844781fabe8a7c9cb495c1e0a1d0
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -8,6 +8,7 @@ A simple way to interact with the ["Tochka" bank's api][api_source_page] 
     | 
|
| 
       8 
8 
     | 
    
         
             
              - [Installation](#installation)
         
     | 
| 
       9 
9 
     | 
    
         
             
              - [Settings](#settings)
         
     | 
| 
       10 
10 
     | 
    
         
             
            - [Usage](#usage)
         
     | 
| 
      
 11 
     | 
    
         
            +
              - [Rake tasks](#rake)
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
            ## Getting started
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
         @@ -16,19 +17,26 @@ A simple way to interact with the ["Tochka" bank's api][api_source_page] 
     | 
|
| 
       16 
17 
     | 
    
         
             
            Add this line to your application's Gemfile:
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
            ```sh
         
     | 
| 
       19 
     | 
    
         
            -
            bundle add  
     | 
| 
      
 20 
     | 
    
         
            +
            bundle add tochka_cyclops_api
         
     | 
| 
       20 
21 
     | 
    
         
             
            ```
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            and run commands bellow to create  
     | 
| 
      
 23 
     | 
    
         
            +
            and run commands bellow to create models, migrations and the initializer:
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
       24 
25 
     | 
    
         
             
            ```sh
         
     | 
| 
       25 
26 
     | 
    
         
             
            rails generate tochka_cyclops_api:models
         
     | 
| 
       26 
27 
     | 
    
         
             
            rails generate tochka_cyclops_api:initializer
         
     | 
| 
       27 
28 
     | 
    
         
             
            ```
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
            to use rake tasks you should also add the following lines to Rakefile of your Rails project:
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 33 
     | 
    
         
            +
            spec = Gem::Specification.find_by_name 'tochka_cyclops_api'
         
     | 
| 
      
 34 
     | 
    
         
            +
            load "#{spec.gem_dir}/lib/tasks/methods.rake"
         
     | 
| 
      
 35 
     | 
    
         
            +
            ```
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       29 
37 
     | 
    
         
             
            ### Settings
         
     | 
| 
       30 
38 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
            You have to set the settings in the initializer file (_config/initializers/ 
     | 
| 
      
 39 
     | 
    
         
            +
            You have to set the settings in the initializer file (_config/initializers/tochka_cyclops_api.rb_):
         
     | 
| 
       32 
40 
     | 
    
         | 
| 
       33 
41 
     | 
    
         
             
            ```ruby
         
     | 
| 
       34 
42 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
         @@ -50,11 +58,58 @@ TochkaCyclopsApi.send_request(method, data) 
     | 
|
| 
       50 
58 
     | 
    
         
             
            method - name of the method defined on the bank side point;
         
     | 
| 
       51 
59 
     | 
    
         
             
            data - hash of the value required to fulfill the request.
         
     | 
| 
       52 
60 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 61 
     | 
    
         
            +
            There are special rake tasks to get information about available methods:
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 64 
     | 
    
         
            +
            bundle exec rake methods:list
         
     | 
| 
      
 65 
     | 
    
         
            +
            bundle exec rake methods:desc method=method_name
         
     | 
| 
      
 66 
     | 
    
         
            +
            ```
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            Examples
         
     | 
| 
      
 69 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 70 
     | 
    
         
            +
            > bundle exec rake methods:list
         
     | 
| 
      
 71 
     | 
    
         
            +
            # ** Invoke methods:list (first_time)
         
     | 
| 
      
 72 
     | 
    
         
            +
            # ** Execute methods:list
         
     | 
| 
      
 73 
     | 
    
         
            +
            # echo
         
     | 
| 
      
 74 
     | 
    
         
            +
            # create_beneficiary_ul
         
     | 
| 
      
 75 
     | 
    
         
            +
            # create_beneficiary_ip
         
     | 
| 
      
 76 
     | 
    
         
            +
            # ...
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            > bundle exec rake methods:desc method=create_beneficiary_ul
         
     | 
| 
      
 79 
     | 
    
         
            +
            # ** Invoke methods:desc (first_time)
         
     | 
| 
      
 80 
     | 
    
         
            +
            # ** Execute methods:desc
         
     | 
| 
      
 81 
     | 
    
         
            +
            # inn                  | mandatory | string
         
     | 
| 
      
 82 
     | 
    
         
            +
            # nominal_account_code | optional  | string
         
     | 
| 
      
 83 
     | 
    
         
            +
            # nominal_account_bic  | optional  | string
         
     | 
| 
      
 84 
     | 
    
         
            +
            # beneficiary_data     | mandatory | {
         
     | 
| 
      
 85 
     | 
    
         
            +
            #                                       name | mandatory | string
         
     | 
| 
      
 86 
     | 
    
         
            +
            #                                       kpp  | mandatory | string
         
     | 
| 
      
 87 
     | 
    
         
            +
            #                                       ogrn | optional  | string
         
     | 
| 
      
 88 
     | 
    
         
            +
            #                                    }
         
     | 
| 
      
 89 
     | 
    
         
            +
            #
         
     | 
| 
      
 90 
     | 
    
         
            +
            # ================================================================================
         
     | 
| 
      
 91 
     | 
    
         
            +
            #
         
     | 
| 
      
 92 
     | 
    
         
            +
            # EXAMPLE
         
     | 
| 
      
 93 
     | 
    
         
            +
            #
         
     | 
| 
      
 94 
     | 
    
         
            +
            # {
         
     | 
| 
      
 95 
     | 
    
         
            +
            #   inn: '7743745038',
         
     | 
| 
      
 96 
     | 
    
         
            +
            #   nominal_account_code: '40702810338170022645',
         
     | 
| 
      
 97 
     | 
    
         
            +
            #   nominal_account_bic: '044525225',
         
     | 
| 
      
 98 
     | 
    
         
            +
            #   beneficiary_data: {
         
     | 
| 
      
 99 
     | 
    
         
            +
            #     name: 'ООО «ТК ИнжСтройКомплект»',
         
     | 
| 
      
 100 
     | 
    
         
            +
            #     kpp: '773401001',
         
     | 
| 
      
 101 
     | 
    
         
            +
            #     ogrn: '1097746324169'
         
     | 
| 
      
 102 
     | 
    
         
            +
            #   }
         
     | 
| 
      
 103 
     | 
    
         
            +
            # }
         
     | 
| 
      
 104 
     | 
    
         
            +
            ```
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            Example of sending request:
         
     | 
| 
       54 
107 
     | 
    
         
             
            ```ruby
         
     | 
| 
       55 
     | 
    
         
            -
            TochkaCyclopsApi. 
     | 
| 
       56 
     | 
    
         
            -
               
     | 
| 
       57 
     | 
    
         
            -
               
     | 
| 
      
 108 
     | 
    
         
            +
            TochkaCyclopsApi.send_request(
         
     | 
| 
      
 109 
     | 
    
         
            +
              # Method contains the name of the TochkaCyclopsApi method
         
     | 
| 
      
 110 
     | 
    
         
            +
              method: 'create_beneficiary_ul',
         
     | 
| 
      
 111 
     | 
    
         
            +
              # Data is value for the "params" field of request body
         
     | 
| 
      
 112 
     | 
    
         
            +
              data: {
         
     | 
| 
       58 
113 
     | 
    
         
             
                inn: "7925930371",
         
     | 
| 
       59 
114 
     | 
    
         
             
                nominal_account_code: "000000000000000000000",
         
     | 
| 
       60 
115 
     | 
    
         
             
                nominal_account_bic: "0000000000",
         
     | 
| 
         @@ -62,7 +117,9 @@ TochkaCyclopsApi.send( 
     | 
|
| 
       62 
117 
     | 
    
         
             
                    name: "ООО \"Рога и Копыта\"",
         
     | 
| 
       63 
118 
     | 
    
         
             
                    kpp: "246301001"
         
     | 
| 
       64 
119 
     | 
    
         
             
                }
         
     | 
| 
       65 
     | 
    
         
            -
              }
         
     | 
| 
      
 120 
     | 
    
         
            +
              },
         
     | 
| 
      
 121 
     | 
    
         
            +
              # Layer have to has one of the following values: :stage, :pre, :prod
         
     | 
| 
      
 122 
     | 
    
         
            +
              layer: :stage
         
     | 
| 
       66 
123 
     | 
    
         
             
            )
         
     | 
| 
       67 
124 
     | 
    
         
             
            ```
         
     | 
| 
       68 
125 
     | 
    
         | 
    
        data/Rakefile
    CHANGED
    
    
| 
         @@ -6,56 +6,81 @@ require 'securerandom' 
     | 
|
| 
       6 
6 
     | 
    
         
             
            require 'json'
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            require_relative 'request'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'result'
         
     | 
| 
       9 
10 
     | 
    
         
             
            require_relative 'schemas/requests/echo'
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            module TochkaCyclopsApi
         
     | 
| 
       12 
13 
     | 
    
         
             
              # Module for input data validation and subsequent request invocation
         
     | 
| 
       13 
     | 
    
         
            -
               
     | 
| 
       14 
     | 
    
         
            -
                def send_request(method 
     | 
| 
      
 14 
     | 
    
         
            +
              class DataProcessor
         
     | 
| 
      
 15 
     | 
    
         
            +
                def self.send_request(method:, data:, layer: )
         
     | 
| 
       15 
16 
     | 
    
         
             
                  @method = method
         
     | 
| 
       16 
17 
     | 
    
         
             
                  @data = data
         
     | 
| 
       17 
     | 
    
         
            -
                  @ 
     | 
| 
      
 18 
     | 
    
         
            +
                  @layer = layer
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @errors = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @url = url_for
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @request_id = SecureRandom.uuid
         
     | 
| 
      
 22 
     | 
    
         
            +
                  schemas
         
     | 
| 
      
 23 
     | 
    
         
            +
                  validation = @request_schema&.call(@data.deep_symbolize_keys)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @validation_errors = validation&.errors.to_h
         
     | 
| 
       18 
25 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                  send_data
         
     | 
| 
      
 26 
     | 
    
         
            +
                  call
         
     | 
| 
       22 
27 
     | 
    
         
             
                end
         
     | 
| 
       23 
28 
     | 
    
         | 
| 
       24 
29 
     | 
    
         
             
                private
         
     | 
| 
       25 
30 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                def  
     | 
| 
       27 
     | 
    
         
            -
                  if  
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
                def self.call
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @errors[:url] = "Layer you called for is not exist" if @url.nil?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @errors[:request_schema] = "Request schema for method #{@method} is not found" if @request_schema.nil?
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @errors[:response_schema] = "Response schema for method #{@method} is not found" if @response_schema.nil?
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  @errors[:validation] = @validation_errors if @request_schemas.present?
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  if @errors.keys.any?
         
     | 
| 
      
 39 
     | 
    
         
            +
                    Result.failure(@errors)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  else
         
     | 
| 
      
 41 
     | 
    
         
            +
                    TochkaCyclopsApi::Request.send_request(method: @method, body: body, url: @url)
         
     | 
| 
       30 
42 
     | 
    
         
             
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
       31 
44 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                def self.url_for
         
     | 
| 
      
 46 
     | 
    
         
            +
                  {
         
     | 
| 
      
 47 
     | 
    
         
            +
                    stage: 'https://stage.tochka.com/api/v1/cyclops',
         
     | 
| 
      
 48 
     | 
    
         
            +
                    pre: 'https://pre.tochka.com/api/v1/cyclops',
         
     | 
| 
      
 49 
     | 
    
         
            +
                    prod: 'https://api.tochka.com/api/v1/cyclops'
         
     | 
| 
      
 50 
     | 
    
         
            +
                  }.fetch(@layer, nil)
         
     | 
| 
       33 
51 
     | 
    
         
             
                end
         
     | 
| 
       34 
52 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                def  
     | 
| 
       36 
     | 
    
         
            -
                   
     | 
| 
      
 53 
     | 
    
         
            +
                def self.schemas
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @request_schema = request_schema
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @response_schema = response_schema
         
     | 
| 
       37 
56 
     | 
    
         
             
                end
         
     | 
| 
       38 
57 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                def  
     | 
| 
      
 58 
     | 
    
         
            +
                def self.request_schema
         
     | 
| 
       40 
59 
     | 
    
         
             
                  require_relative "schemas/requests/#{@method}"
         
     | 
| 
       41 
60 
     | 
    
         
             
                  schema = ['TochkaCyclopsApi', 'Schemas', 'Requests', camel_case_method].join('::').constantize
         
     | 
| 
       42 
61 
     | 
    
         | 
| 
       43 
62 
     | 
    
         
             
                  schema.new
         
     | 
| 
       44 
63 
     | 
    
         
             
                rescue => e
         
     | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 64 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def self.response_schema
         
     | 
| 
      
 68 
     | 
    
         
            +
                  require_relative "schemas/responses/#{@method}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                  schema = ['TochkaCyclopsApi', 'Schemas', 'Responses', camel_case_method].join('::').constantize
         
     | 
| 
      
 70 
     | 
    
         
            +
                rescue => e
         
     | 
| 
      
 71 
     | 
    
         
            +
                  nil
         
     | 
| 
       47 
72 
     | 
    
         
             
                end
         
     | 
| 
       48 
73 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                def camel_case_method
         
     | 
| 
      
 74 
     | 
    
         
            +
                def self.camel_case_method
         
     | 
| 
       50 
75 
     | 
    
         
             
                  @method.split('_').map(&:capitalize).join
         
     | 
| 
       51 
76 
     | 
    
         
             
                end
         
     | 
| 
       52 
77 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                def body
         
     | 
| 
      
 78 
     | 
    
         
            +
                def self.body
         
     | 
| 
       54 
79 
     | 
    
         
             
                  {
         
     | 
| 
       55 
80 
     | 
    
         
             
                    "jsonrpc": '2.0',
         
     | 
| 
       56 
81 
     | 
    
         
             
                    "method": @method,
         
     | 
| 
       57 
82 
     | 
    
         
             
                    "params": @data,
         
     | 
| 
       58 
     | 
    
         
            -
                    "id": @ 
     | 
| 
      
 83 
     | 
    
         
            +
                    "id": @request_id
         
     | 
| 
       59 
84 
     | 
    
         
             
                  }.to_json
         
     | 
| 
       60 
85 
     | 
    
         
             
                end
         
     | 
| 
       61 
86 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,9 +1,202 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'dry/schema'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Undefined = Dry::Schema::Undefined
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module Types
         
     | 
| 
      
 8 
     | 
    
         
            +
              include Dry.Types()
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            class DocCompiler
         
     | 
| 
      
 12 
     | 
    
         
            +
              def visit(node)
         
     | 
| 
      
 13 
     | 
    
         
            +
                meth, rest = node
         
     | 
| 
      
 14 
     | 
    
         
            +
                public_send(:"visit_#{meth}", rest)
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def visit_set(nodes)
         
     | 
| 
      
 18 
     | 
    
         
            +
                nodes.map { |node| visit(node) }.flatten(1)
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def visit_and(node)
         
     | 
| 
      
 22 
     | 
    
         
            +
                left, right = node
         
     | 
| 
      
 23 
     | 
    
         
            +
                [visit(left), visit(right)].compact
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def visit_key(node)
         
     | 
| 
      
 27 
     | 
    
         
            +
                name, rest = node
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                predicates = visit(rest).flatten
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                if predicates[0].is_a? Symbol
         
     | 
| 
      
 32 
     | 
    
         
            +
                  validations = predicate_description(predicates[0], predicates[1])
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  { key: name, validations: validations }
         
     | 
| 
      
 35 
     | 
    
         
            +
                else
         
     | 
| 
      
 36 
     | 
    
         
            +
                  { key: name, validations: predicates }
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def visit_implication(node)
         
     | 
| 
      
 41 
     | 
    
         
            +
                _, right = node.map(&method(:visit))
         
     | 
| 
      
 42 
     | 
    
         
            +
                right.merge(optional: true)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def visit_predicate(node)
         
     | 
| 
      
 46 
     | 
    
         
            +
                name, args = node
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                return if name.equal?(:key?)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                { name => args.map(&:last).reject { |v| v.equal?(Dry::Schema::Undefined) } }
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def predicate_description(name, args)
         
     | 
| 
      
 54 
     | 
    
         
            +
                case name
         
     | 
| 
      
 55 
     | 
    
         
            +
                when :str? then "string"
         
     | 
| 
      
 56 
     | 
    
         
            +
                when :bool? then "true/false"
         
     | 
| 
      
 57 
     | 
    
         
            +
                when :filled? then "filled"
         
     | 
| 
      
 58 
     | 
    
         
            +
                when :int? then "integer"
         
     | 
| 
      
 59 
     | 
    
         
            +
                when :gt? then "greater than #{args[0]}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                else
         
     | 
| 
      
 61 
     | 
    
         
            +
                  raise NotImplementedError, "#{name} not supported yet"
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       3 
66 
     | 
    
         
             
            module TochkaCyclopsApi
         
     | 
| 
       4 
     | 
    
         
            -
               
     | 
| 
       5 
     | 
    
         
            -
                 
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
              class Methods
         
     | 
| 
      
 68 
     | 
    
         
            +
                METHODS = %w[
         
     | 
| 
      
 69 
     | 
    
         
            +
                  echo
         
     | 
| 
      
 70 
     | 
    
         
            +
                  create_beneficiary_ul
         
     | 
| 
      
 71 
     | 
    
         
            +
                  create_beneficiary_ip
         
     | 
| 
      
 72 
     | 
    
         
            +
                  create_beneficiary_fl
         
     | 
| 
      
 73 
     | 
    
         
            +
                  update_beneficiary_ul
         
     | 
| 
      
 74 
     | 
    
         
            +
                  update_beneficiary_ip
         
     | 
| 
      
 75 
     | 
    
         
            +
                  update_beneficiary_fl
         
     | 
| 
      
 76 
     | 
    
         
            +
                  get_beneficiary
         
     | 
| 
      
 77 
     | 
    
         
            +
                  list_beneficiary
         
     | 
| 
      
 78 
     | 
    
         
            +
                  activate_beneficiary
         
     | 
| 
      
 79 
     | 
    
         
            +
                  deactivate_beneficiary
         
     | 
| 
      
 80 
     | 
    
         
            +
                ]
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                DIVIDER = ["\n", "="*80, "\n"]
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def self.get_method(method)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  return unless method_exists? method
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  require_relative "schemas/requests/#{method}"
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  @method = method
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  define_schema_class
         
     | 
| 
      
 92 
     | 
    
         
            +
                  define_schema_ast
         
     | 
| 
      
 93 
     | 
    
         
            +
                  parse_schema_ast
         
     | 
| 
      
 94 
     | 
    
         
            +
                  @formatted_schema_ast = format_schema_ast
         
     | 
| 
      
 95 
     | 
    
         
            +
                  show_schema
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                  puts @method.split('_').map(&:capitalize).join
         
     | 
| 
      
 98 
     | 
    
         
            +
                  puts @formatted_schema_ast
         
     | 
| 
      
 99 
     | 
    
         
            +
                  puts DIVIDER
         
     | 
| 
      
 100 
     | 
    
         
            +
                  puts ['EXAMPLE', "\n"]
         
     | 
| 
      
 101 
     | 
    
         
            +
                  puts @schema_class.const_get('EXAMPLE')
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                private
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                def self.method_exists?(method)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  return true if method.in? METHODS
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  puts "Method #{method} is not found"
         
     | 
| 
      
 110 
     | 
    
         
            +
                  false
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def self.define_schema_class
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @schema_class = [
         
     | 
| 
      
 115 
     | 
    
         
            +
                    "TochkaCyclopsApi",
         
     | 
| 
      
 116 
     | 
    
         
            +
                    "Schemas",
         
     | 
| 
      
 117 
     | 
    
         
            +
                    "Requests",
         
     | 
| 
      
 118 
     | 
    
         
            +
                    camel_case(@method)].join('::').constantize
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                def self.define_schema_ast
         
     | 
| 
      
 122 
     | 
    
         
            +
                  @schema_ast = @schema_class.new.schema.ast
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                def self.parse_schema_ast
         
     | 
| 
      
 126 
     | 
    
         
            +
                  compiler = DocCompiler.new
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  @schema_ast = compiler.visit(@schema_ast).map do |row|
         
     | 
| 
      
 129 
     | 
    
         
            +
                    key = row[:key]
         
     | 
| 
      
 130 
     | 
    
         
            +
                    validations = row[:validations]
         
     | 
| 
      
 131 
     | 
    
         
            +
                    optional = row[:optional] ? 'optional' : 'mandatory'
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                    if validations.is_a? Array
         
     | 
| 
      
 134 
     | 
    
         
            +
                      validations = validations.map do |validation|
         
     | 
| 
      
 135 
     | 
    
         
            +
                        v_key = validation[:key]
         
     | 
| 
      
 136 
     | 
    
         
            +
                        v_validations = validation[:validations]
         
     | 
| 
      
 137 
     | 
    
         
            +
                        v_optional = validation[:optional] ? 'optional' : 'mandatory'
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                        [v_key, v_optional, v_validations]
         
     | 
| 
      
 140 
     | 
    
         
            +
                      end
         
     | 
| 
      
 141 
     | 
    
         
            +
                    end
         
     | 
| 
      
 142 
     | 
    
         
            +
                    [key, optional, validations]
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                def self.column_sizes(array)
         
     | 
| 
      
 147 
     | 
    
         
            +
                  sizes = []
         
     | 
| 
      
 148 
     | 
    
         
            +
                  3.times do |index|
         
     | 
| 
      
 149 
     | 
    
         
            +
                    size = array.map do |row|
         
     | 
| 
      
 150 
     | 
    
         
            +
                      next if row[index].is_a? Array
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                      row[index].to_s.length
         
     | 
| 
      
 153 
     | 
    
         
            +
                    end
         
     | 
| 
      
 154 
     | 
    
         
            +
                    sizes << size.compact.max
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
                  sizes
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                def self.format_schema_ast(array = @schema_ast)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  sizes = column_sizes(array)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  array.map do |sub_array|
         
     | 
| 
      
 162 
     | 
    
         
            +
                    sub_array.each_with_index.map { |row, index| format_row(row, sizes[index]) }
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                def self.format_row(row, indent)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  if row.is_a? Array
         
     | 
| 
      
 168 
     | 
    
         
            +
                    format_schema_ast(row)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  else
         
     | 
| 
      
 170 
     | 
    
         
            +
                    row.to_s.ljust(indent)
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                def self.show_schema
         
     | 
| 
      
 175 
     | 
    
         
            +
                  @formatted_schema_ast.map! do |row|
         
     | 
| 
      
 176 
     | 
    
         
            +
                    array = row.select { |element| element.is_a? Array }.last
         
     | 
| 
      
 177 
     | 
    
         
            +
                    if array.present?
         
     | 
| 
      
 178 
     | 
    
         
            +
                      max_first_element_size = array.map { |row| row[0].strip.to_s.length }.max
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                      # 9 is size of 2 dividers (" | ") and 1 brace
         
     | 
| 
      
 181 
     | 
    
         
            +
                      row_indent = row[0].size + row[1].size + 7
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                      # 2 is 2 spaces indent
         
     | 
| 
      
 184 
     | 
    
         
            +
                      array.map! do |row|
         
     | 
| 
      
 185 
     | 
    
         
            +
                        row[0] = row[0].rjust(row_indent + max_first_element_size + 2)
         
     | 
| 
      
 186 
     | 
    
         
            +
                        row.join(' | ')
         
     | 
| 
      
 187 
     | 
    
         
            +
                      end
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                      array = ["{"] + array + ["}".rjust(row_indent)]
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                      row[-1] = array.join("\n")
         
     | 
| 
      
 192 
     | 
    
         
            +
                    end
         
     | 
| 
      
 193 
     | 
    
         
            +
                    row.join(' | ')
         
     | 
| 
      
 194 
     | 
    
         
            +
                  end
         
     | 
| 
      
 195 
     | 
    
         
            +
                end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                def self.camel_case(string)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  string.split('_').map(&:capitalize).join
         
     | 
| 
      
 200 
     | 
    
         
            +
                end
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
       9 
202 
     | 
    
         
             
            end
         
     | 
| 
         @@ -6,53 +6,88 @@ require_relative 'response' 
     | 
|
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module TochkaCyclopsApi
         
     | 
| 
       8 
8 
     | 
    
         
             
              # Module for sending requests to the bank's api
         
     | 
| 
       9 
     | 
    
         
            -
               
     | 
| 
       10 
     | 
    
         
            -
                def self. 
     | 
| 
      
 9 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 10 
     | 
    
         
            +
                def self.send_request(body:, method:, url: )
         
     | 
| 
       11 
11 
     | 
    
         
             
                  @method = method
         
     | 
| 
       12 
     | 
    
         
            -
                   
     | 
| 
      
 12 
     | 
    
         
            +
                  @body = body
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @uri = URI(url)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @request_object = initialize_request_object
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @post_request = initialize_post_request
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @adapter = initialize_adapter
         
     | 
| 
       13 
17 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                  http.use_ssl = true
         
     | 
| 
      
 18 
     | 
    
         
            +
                  call
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
       17 
20 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                    'sign-data' => signature(body),
         
     | 
| 
       20 
     | 
    
         
            -
                    'sign-thumbprint' => TochkaCyclopsApi.configuration.sign_thumbprint,
         
     | 
| 
       21 
     | 
    
         
            -
                    'sign-system' => TochkaCyclopsApi.configuration.sign_system,
         
     | 
| 
       22 
     | 
    
         
            -
                    'Content-Type' => 'application/pdf'
         
     | 
| 
       23 
     | 
    
         
            -
                  })
         
     | 
| 
       24 
     | 
    
         
            -
                  request.body = body
         
     | 
| 
      
 21 
     | 
    
         
            +
                private
         
     | 
| 
       25 
22 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
                def self.call
         
     | 
| 
      
 24 
     | 
    
         
            +
                  get_response
         
     | 
| 
      
 25 
     | 
    
         
            +
                  response = handle_response
         
     | 
| 
       27 
26 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                  case response 
     | 
| 
       29 
     | 
    
         
            -
                  when  
     | 
| 
       30 
     | 
    
         
            -
                     
     | 
| 
       31 
     | 
    
         
            -
                    TochkaCyclopsApi::Response.create(@request, response, method)
         
     | 
| 
       32 
     | 
    
         
            -
                  when (400..499)
         
     | 
| 
       33 
     | 
    
         
            -
                    -> { 'Our server error' }[]
         
     | 
| 
      
 27 
     | 
    
         
            +
                  case response[:status]
         
     | 
| 
      
 28 
     | 
    
         
            +
                  when :error
         
     | 
| 
      
 29 
     | 
    
         
            +
                    Result.failure(response[:data])
         
     | 
| 
       34 
30 
     | 
    
         
             
                  else
         
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
       36 
     | 
    
         
            -
                    -> { 'Their server error' }[]
         
     | 
| 
      
 31 
     | 
    
         
            +
                    Response.new(request: @request_object, response: response[:data], method: @method)
         
     | 
| 
       37 
32 
     | 
    
         
             
                  end
         
     | 
| 
       38 
33 
     | 
    
         
             
                end
         
     | 
| 
       39 
34 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                def self. 
     | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
       44 
     | 
    
         
            -
                  base64_signature = Base64.strict_encode64(signature_key)
         
     | 
| 
       45 
     | 
    
         
            -
                  base64_signature.gsub("\n", '')
         
     | 
| 
      
 35 
     | 
    
         
            +
                def self.initialize_adapter
         
     | 
| 
      
 36 
     | 
    
         
            +
                  adapter = Net::HTTP.new(@uri.host, @uri.port)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  adapter.use_ssl = true
         
     | 
| 
      
 38 
     | 
    
         
            +
                  adapter
         
     | 
| 
       46 
39 
     | 
    
         
             
                end
         
     | 
| 
       47 
40 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                def self. 
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
      
 41 
     | 
    
         
            +
                def self.initialize_request_object
         
     | 
| 
      
 42 
     | 
    
         
            +
                  TochkaCyclopsRequest.create(
         
     | 
| 
       50 
43 
     | 
    
         
             
                    method: @method,
         
     | 
| 
       51 
     | 
    
         
            -
                    body: body,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    body: @body,
         
     | 
| 
       52 
45 
     | 
    
         
             
                    request_identifier: @id,
         
     | 
| 
       53 
46 
     | 
    
         
             
                    # idempotency_key:
         
     | 
| 
       54 
47 
     | 
    
         
             
                    status: 'initialized'
         
     | 
| 
       55 
48 
     | 
    
         
             
                  )
         
     | 
| 
       56 
49 
     | 
    
         
             
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def self.initialize_post_request
         
     | 
| 
      
 52 
     | 
    
         
            +
                  post_request = Net::HTTP::Post.new(@uri, {
         
     | 
| 
      
 53 
     | 
    
         
            +
                    'sign-data' => signature,
         
     | 
| 
      
 54 
     | 
    
         
            +
                    'sign-thumbprint' => TochkaCyclopsApi.configuration.sign_thumbprint,
         
     | 
| 
      
 55 
     | 
    
         
            +
                    'sign-system' => TochkaCyclopsApi.configuration.sign_system,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    'Content-Type' => 'application/json'
         
     | 
| 
      
 57 
     | 
    
         
            +
                  })
         
     | 
| 
      
 58 
     | 
    
         
            +
                  post_request.body = @body
         
     | 
| 
      
 59 
     | 
    
         
            +
                  post_request
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def self.get_response
         
     | 
| 
      
 63 
     | 
    
         
            +
                  @response = @adapter.request(@post_request)
         
     | 
| 
      
 64 
     | 
    
         
            +
                rescue => e
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @error = { request_error: e }
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def self.handle_response
         
     | 
| 
      
 69 
     | 
    
         
            +
                  return { status: :error, data: @error } if @error
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  status =  case @response.code.to_i
         
     | 
| 
      
 72 
     | 
    
         
            +
                            when (200..299)
         
     | 
| 
      
 73 
     | 
    
         
            +
                              {
         
     | 
| 
      
 74 
     | 
    
         
            +
                                status: :ok,
         
     | 
| 
      
 75 
     | 
    
         
            +
                                data: @response
         
     | 
| 
      
 76 
     | 
    
         
            +
                              }
         
     | 
| 
      
 77 
     | 
    
         
            +
                            else
         
     | 
| 
      
 78 
     | 
    
         
            +
                              {
         
     | 
| 
      
 79 
     | 
    
         
            +
                                status: :error,
         
     | 
| 
      
 80 
     | 
    
         
            +
                                data: { request_error: @response }
         
     | 
| 
      
 81 
     | 
    
         
            +
                              }
         
     | 
| 
      
 82 
     | 
    
         
            +
                            end
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def self.signature
         
     | 
| 
      
 86 
     | 
    
         
            +
                  digest = OpenSSL::Digest.new('sha256')
         
     | 
| 
      
 87 
     | 
    
         
            +
                  private_key = OpenSSL::PKey::RSA.new(TochkaCyclopsApi.configuration.private_key)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  signature_key = private_key.sign(digest, @body)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  base64_signature = Base64.strict_encode64(signature_key)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  base64_signature.gsub("\n", '')
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
       57 
92 
     | 
    
         
             
              end
         
     | 
| 
       58 
93 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,63 +1,56 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require_relative 'schemas/responses/ 
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'schemas/responses/error'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module TochkaCyclopsApi
         
     | 
| 
       6 
6 
     | 
    
         
             
              # Class for processing the response received from the api bank
         
     | 
| 
       7 
7 
     | 
    
         
             
              class Response
         
     | 
| 
       8 
     | 
    
         
            -
                def self.create(request,  
     | 
| 
       9 
     | 
    
         
            -
                  @method = method
         
     | 
| 
      
 8 
     | 
    
         
            +
                def self.create(request: ,response: ,method:)
         
     | 
| 
       10 
9 
     | 
    
         
             
                  @request = request
         
     | 
| 
       11 
     | 
    
         
            -
                  @ 
     | 
| 
       12 
     | 
    
         
            -
                  parse
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @method = method
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @body = JSON.parse(response.body)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @response_schema = "TochkaCyclopsApi::Schemas::Responses::#{camel_case_method}".constantize
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @error_schema = 'TochkaCyclopsApi::Schemas::Responses::Error'.constantize
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
                    response_struct: @response_struct,
         
     | 
| 
       16 
     | 
    
         
            -
                    result: @result
         
     | 
| 
       17 
     | 
    
         
            -
                  }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  call
         
     | 
| 
       18 
16 
     | 
    
         
             
                end
         
     | 
| 
       19 
17 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                 
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
      
 18 
     | 
    
         
            +
                private
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def self.call
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @result = @body['result']
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @error = @body['error']
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  if @error.present?
         
     | 
| 
       25 
25 
     | 
    
         
             
                    parse_error
         
     | 
| 
      
 26 
     | 
    
         
            +
                  else
         
     | 
| 
      
 27 
     | 
    
         
            +
                    parse_result
         
     | 
| 
       26 
28 
     | 
    
         
             
                  end
         
     | 
| 
       27 
29 
     | 
    
         
             
                end
         
     | 
| 
       28 
30 
     | 
    
         | 
| 
       29 
31 
     | 
    
         
             
                def self.parse_result
         
     | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
       31 
     | 
    
         
            -
                  response_schema = schema || -> { "Schema for #{@method} is not found" }[]
         
     | 
| 
      
 32 
     | 
    
         
            +
                  return nil if @result.nil?
         
     | 
| 
       32 
33 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
       34 
     | 
    
         
            -
                  @request.update(result:  
     | 
| 
      
 34 
     | 
    
         
            +
                  response = TochkaCyclopsResponse.create(body: @body, result: @result)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @request.update(result: response, status: 'success')
         
     | 
| 
       35 
36 
     | 
    
         
             
                  @result.deep_symbolize_keys if @result.is_a? Hash
         
     | 
| 
       36 
     | 
    
         
            -
                   
     | 
| 
      
 37 
     | 
    
         
            +
                  response_struct = @response_schema.new(@result)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  Result.success(response_struct)
         
     | 
| 
       37 
40 
     | 
    
         
             
                end
         
     | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
42 
     | 
    
         
             
                def self.parse_error
         
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
       41 
     | 
    
         
            -
                  require_relative 'schemas/responses/error'
         
     | 
| 
       42 
     | 
    
         
            -
                  response_schema = 'TochkaCyclopsApi::Schemas::Responses::Error'.constantize
         
     | 
| 
      
 43 
     | 
    
         
            +
                  return nil if @error.nil?
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                   
     | 
| 
      
 45 
     | 
    
         
            +
                  response = TochkaCyclopsError.create(
         
     | 
| 
       45 
46 
     | 
    
         
             
                    body: @body,
         
     | 
| 
       46 
47 
     | 
    
         
             
                    code: @error['code'],
         
     | 
| 
       47 
48 
     | 
    
         
             
                    message: @error['message']
         
     | 
| 
       48 
49 
     | 
    
         
             
                  )
         
     | 
| 
      
 50 
     | 
    
         
            +
                  @request.update(result: response, status: 'failure')
         
     | 
| 
      
 51 
     | 
    
         
            +
                  response_struct = @error_schema.new(@error.deep_symbolize_keys)
         
     | 
| 
       49 
52 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                   
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                  @response_struct = response_schema.new(@error.deep_symbolize_keys)
         
     | 
| 
       53 
     | 
    
         
            -
                end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                def self.schema
         
     | 
| 
       56 
     | 
    
         
            -
                  require_relative "schemas/responses/#{@method}"
         
     | 
| 
       57 
     | 
    
         
            -
                  "TochkaCyclopsApi::Schemas::Responses::#{camel_case_method}".constantize
         
     | 
| 
       58 
     | 
    
         
            -
                rescue StandardError => e
         
     | 
| 
       59 
     | 
    
         
            -
                  @errors = { error: e.message }
         
     | 
| 
       60 
     | 
    
         
            -
                  false
         
     | 
| 
      
 53 
     | 
    
         
            +
                  Result.success(response_struct)
         
     | 
| 
       61 
54 
     | 
    
         
             
                end
         
     | 
| 
       62 
55 
     | 
    
         | 
| 
       63 
56 
     | 
    
         
             
                def self.camel_case_method
         
     |