orangedata 0.0.6 → 0.0.7
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 +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +13 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +3 -1
- data/README.md +8 -0
- data/Rakefile +6 -5
- data/lib/orange_data/credentials.rb +47 -8
- data/lib/orange_data/generated_attributes.rb +19 -8
- data/lib/orange_data/receipt.rb +12 -6
- data/lib/orange_data/schema_definitions.yml +23 -4
- data/lib/orange_data/transport.rb +26 -8
- data/lib/orange_data/version.rb +1 -1
- data/orangedata.gemspec +1 -0
- metadata +17 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 8af88534119802c5e031fff99d54faeda092ed09f35c220b6c298330a733c9a8
         | 
| 4 | 
            +
              data.tar.gz: 63b7bac4c5594d2f4d90eb8243b5179977c434ab1b47691878d5c3313e0d25c7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9f534d7ef8d02e88bb6cfe9fb28deaa66c51d745bc6681d158c127d314854f1878e9e1372e3511a21d81d9d243d960dfb7f8b4e9954afadf926e32090fe6629a
         | 
| 7 | 
            +
              data.tar.gz: '09d9ae86ca7bfd561b9ab5b5bbe8b8c1a09bab0a6986efc41caf732ea1b8fe1a75f98a263d4b1de666d59dc1f2f7701f62f588b9596beea2548fcf592791071d'
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -10,7 +10,7 @@ Gemspec/RequiredRubyVersion: | |
| 10 10 | 
             
              Enabled: false
         | 
| 11 11 |  | 
| 12 12 | 
             
            Metrics/LineLength:
         | 
| 13 | 
            -
              Max:  | 
| 13 | 
            +
              Max: 130
         | 
| 14 14 | 
             
              Exclude:
         | 
| 15 15 | 
             
                - 'spec/**/*'
         | 
| 16 16 |  | 
| @@ -19,6 +19,9 @@ Metrics/BlockLength: | |
| 19 19 | 
             
              Exclude:
         | 
| 20 20 | 
             
                - 'spec/**/*'
         | 
| 21 21 |  | 
| 22 | 
            +
            Metrics/BlockNesting:
         | 
| 23 | 
            +
              Max: 4
         | 
| 24 | 
            +
             | 
| 22 25 | 
             
            Metrics/MethodLength:
         | 
| 23 26 | 
             
              Max: 20
         | 
| 24 27 | 
             
              Enabled: false
         | 
| @@ -36,6 +39,9 @@ Metrics/CyclomaticComplexity: | |
| 36 39 | 
             
            Metrics/PerceivedComplexity:
         | 
| 37 40 | 
             
              Max: 50
         | 
| 38 41 |  | 
| 42 | 
            +
            Metrics/ParameterLists:
         | 
| 43 | 
            +
              Max: 10
         | 
| 44 | 
            +
             | 
| 39 45 | 
             
            Style/StringLiterals:
         | 
| 40 46 | 
             
              Enabled: false
         | 
| 41 47 | 
             
              # EnforcedStyle: double_quotes
         | 
| @@ -43,6 +49,9 @@ Style/StringLiterals: | |
| 43 49 | 
             
            Style/RedundantReturn:
         | 
| 44 50 | 
             
              Enabled: false
         | 
| 45 51 |  | 
| 52 | 
            +
            Layout/AlignArguments:
         | 
| 53 | 
            +
              EnforcedStyle: with_fixed_indentation
         | 
| 54 | 
            +
             | 
| 46 55 | 
             
            Layout/SpaceBeforeBlockBraces:
         | 
| 47 56 | 
             
              EnforcedStyle: no_space
         | 
| 48 57 |  | 
| @@ -99,3 +108,6 @@ Style/TrailingCommaInHashLiteral: | |
| 99 108 | 
             
              Enabled: false
         | 
| 100 109 | 
             
            Style/TrailingCommaInArrayLiteral:
         | 
| 101 110 | 
             
              Enabled: false
         | 
| 111 | 
            +
             | 
| 112 | 
            +
            Naming/AccessorMethodName:
         | 
| 113 | 
            +
              Enabled: false
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,9 @@ | |
| 1 | 
            +
            # 0.0.7
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - data schema update to 2.23.0 (15.06.2019)
         | 
| 4 | 
            +
            - Added: load credentials from zip file via rubyzip (no dependency, only accept already opened object)
         | 
| 5 | 
            +
            - Added: Credentials#from_hash now accepts `key_pass` argument
         | 
| 6 | 
            +
             | 
| 1 7 | 
             
            # 0.0.6
         | 
| 2 8 |  | 
| 3 9 | 
             
            - data schema changes:
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                orangedata (0.0. | 
| 4 | 
            +
                orangedata (0.0.7)
         | 
| 5 5 | 
             
                  faraday (>= 0.15)
         | 
| 6 6 | 
             
                  faraday_middleware
         | 
| 7 7 |  | 
| @@ -52,6 +52,7 @@ GEM | |
| 52 52 | 
             
                  ruby-progressbar (~> 1.7)
         | 
| 53 53 | 
             
                  unicode-display_width (>= 1.4.0, < 1.7)
         | 
| 54 54 | 
             
                ruby-progressbar (1.10.1)
         | 
| 55 | 
            +
                rubyzip (1.2.3)
         | 
| 55 56 | 
             
                safe_yaml (1.0.5)
         | 
| 56 57 | 
             
                simplecov (0.16.1)
         | 
| 57 58 | 
             
                  docile (~> 1.1)
         | 
| @@ -74,6 +75,7 @@ DEPENDENCIES | |
| 74 75 | 
             
              rake (~> 10.0)
         | 
| 75 76 | 
             
              rspec
         | 
| 76 77 | 
             
              rubocop
         | 
| 78 | 
            +
              rubyzip
         | 
| 77 79 | 
             
              simplecov
         | 
| 78 80 | 
             
              webmock
         | 
| 79 81 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -142,6 +142,14 @@ res = transport.get_correction(correction.inn, correction.id) | |
| 142 142 | 
             
              transport.post_document # и далее по тексту, осторожно - не пробейте лишние чеки во время проверок
         | 
| 143 143 | 
             
            ```
         | 
| 144 144 |  | 
| 145 | 
            +
            Еще есть `OrangeData::Credentials.read_certs_from_zip_pack`, куда можно скормить нераспакованный файлик, если у вас есть `gem 'rubyzip'`:
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            ```ruby
         | 
| 148 | 
            +
              c = Zip::File.open("cert_123.zip") do |zip_file|
         | 
| 149 | 
            +
                OrangeData::Credentials.read_certs_from_zip_pack(zip_file, cert_key_pass:'1234')
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
            ```
         | 
| 152 | 
            +
             | 
| 145 153 | 
             
            ## Разработка
         | 
| 146 154 |  | 
| 147 155 | 
             
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -34,7 +34,7 @@ namespace :swagger do | |
| 34 34 | 
             
                  puts "No top-level definitions changed"
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 | 
            -
                new_definitions.each_pair do|key, new_schema|
         | 
| 37 | 
            +
                new_definitions.each_pair do |key, new_schema|
         | 
| 38 38 | 
             
                  old_schema = old_definitions[key]
         | 
| 39 39 | 
             
                  next unless old_schema
         | 
| 40 40 |  | 
| @@ -43,12 +43,13 @@ namespace :swagger do | |
| 43 43 | 
             
                      puts "\t#{key} added: #{new_schema['properties'].keys - old_schema['properties'].keys}"
         | 
| 44 44 | 
             
                      puts "\t#{key} removed: #{old_schema['properties'].keys - new_schema['properties'].keys}"
         | 
| 45 45 | 
             
                    else
         | 
| 46 | 
            -
                      puts "\t#{key} property order changed"
         | 
| 46 | 
            +
                      puts "\t#{key} property order changed:"
         | 
| 47 | 
            +
                      puts "\t\told:#{old_schema['properties'].keys}"
         | 
| 48 | 
            +
                      puts "\t\tnew:#{new_schema['properties'].keys}"
         | 
| 47 49 | 
             
                    end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                    #TODO: deep compare
         | 
| 50 | 
            +
                    # else
         | 
| 51 | 
            +
                    # TODO: deep compare
         | 
| 50 52 | 
             
                  end
         | 
| 51 53 | 
             
                end
         | 
| 52 | 
            -
             | 
| 53 54 | 
             
              end
         | 
| 54 55 | 
             
            end
         | 
| @@ -33,9 +33,16 @@ module OrangeData | |
| 33 33 | 
             
                      raise ArgumentError, 'no RSAKeyValue in xml' unless kv && kv.name == 'RSAKeyValue'
         | 
| 34 34 |  | 
| 35 35 | 
             
                      mapping = {
         | 
| 36 | 
            -
                        "Modulus" | 
| 37 | 
            -
                        " | 
| 38 | 
            -
             | 
| 36 | 
            +
                        "Modulus" => :n,
         | 
| 37 | 
            +
                        "Exponent" => :e,
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        "D" => :d,
         | 
| 40 | 
            +
                        "P" => :p,
         | 
| 41 | 
            +
                        "Q" => :q,
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                        "DP" => :dmp1,
         | 
| 44 | 
            +
                        "DQ" => :dmq1,
         | 
| 45 | 
            +
                        "InverseQ" => :iqmp
         | 
| 39 46 | 
             
                      }
         | 
| 40 47 | 
             
                      from_hash(
         | 
| 41 48 | 
             
                        kv.elements.each_with_object({}){|k, h| h[mapping[k.name]] = k.text if mapping[k.name] }
         | 
| @@ -82,6 +89,7 @@ module OrangeData | |
| 82 89 |  | 
| 83 90 | 
             
                    def load_from(val, key_pass=nil)
         | 
| 84 91 | 
             
                      return val unless val
         | 
| 92 | 
            +
             | 
| 85 93 | 
             
                      case val
         | 
| 86 94 | 
             
                      when self
         | 
| 87 95 | 
             
                        val
         | 
| @@ -97,9 +105,7 @@ module OrangeData | |
| 97 105 | 
             
                        raise ArgumentError, "cannot load from #{val.class}"
         | 
| 98 106 | 
             
                      end
         | 
| 99 107 | 
             
                    end
         | 
| 100 | 
            -
             | 
| 101 108 | 
             
                  end
         | 
| 102 | 
            -
             | 
| 103 109 | 
             
                end
         | 
| 104 110 |  | 
| 105 111 | 
             
                using KeyEncoding
         | 
| @@ -109,6 +115,7 @@ module OrangeData | |
| 109 115 | 
             
                def initialize(signature_key_name:nil, signature_key:nil, certificate:nil, certificate_key:nil, title:nil)
         | 
| 110 116 | 
             
                  raise ArgumentError, "Signature key should be a private key" if signature_key && !signature_key.private?
         | 
| 111 117 | 
             
                  raise ArgumentError, "Certificate key should be a private key" if certificate_key && !certificate_key.private?
         | 
| 118 | 
            +
             | 
| 112 119 | 
             
                  @signature_key_name = signature_key_name
         | 
| 113 120 | 
             
                  @signature_key = signature_key
         | 
| 114 121 | 
             
                  @certificate = certificate
         | 
| @@ -126,6 +133,7 @@ module OrangeData | |
| 126 133 |  | 
| 127 134 | 
             
                def ==(other)
         | 
| 128 135 | 
             
                  return false unless %i[signature_key_name title].all?{|m| send(m) == other.send(m) }
         | 
| 136 | 
            +
             | 
| 129 137 | 
             
                  # certificates/keys cannot be compared directly, so dump
         | 
| 130 138 | 
             
                  %i[signature_key certificate certificate_key].all?{|m|
         | 
| 131 139 | 
             
                    c1 = send(m)
         | 
| @@ -134,13 +142,14 @@ module OrangeData | |
| 134 142 | 
             
                  }
         | 
| 135 143 | 
             
                end
         | 
| 136 144 |  | 
| 137 | 
            -
                def self.from_hash(creds)
         | 
| 145 | 
            +
                def self.from_hash(creds, key_pass:nil)
         | 
| 146 | 
            +
                  key_pass ||= '' # to prevent password prompt, works in fresh openssl gem/ruby
         | 
| 138 147 | 
             
                  new(
         | 
| 139 148 | 
             
                    title: creds[:title],
         | 
| 140 149 | 
             
                    signature_key_name: creds[:signature_key_name],
         | 
| 141 | 
            -
                    signature_key: OpenSSL::PKey::RSA.load_from(creds[:signature_key], creds[:signature_key_pass]),
         | 
| 150 | 
            +
                    signature_key: OpenSSL::PKey::RSA.load_from(creds[:signature_key], creds[:signature_key_pass] || key_pass),
         | 
| 142 151 | 
             
                    certificate: creds[:certificate] && OpenSSL::X509::Certificate.new(creds[:certificate]),
         | 
| 143 | 
            -
                    certificate_key: OpenSSL::PKey::RSA.load_from(creds[:certificate_key], creds[:certificate_key_pass])
         | 
| 152 | 
            +
                    certificate_key: OpenSSL::PKey::RSA.load_from(creds[:certificate_key], creds[:certificate_key_pass] || key_pass)
         | 
| 144 153 | 
             
                  )
         | 
| 145 154 | 
             
                end
         | 
| 146 155 |  | 
| @@ -204,6 +213,7 @@ module OrangeData | |
| 204 213 |  | 
| 205 214 | 
             
                def self.generate_signature_key(key_length=DEFAULT_KEY_LENGTH)
         | 
| 206 215 | 
             
                  raise ArgumentError, "key length should be >= 489, recomended #{DEFAULT_KEY_LENGTH}" unless key_length >= 489
         | 
| 216 | 
            +
             | 
| 207 217 | 
             
                  OpenSSL::PKey::RSA.new(key_length)
         | 
| 208 218 | 
             
                end
         | 
| 209 219 |  | 
| @@ -211,6 +221,7 @@ module OrangeData | |
| 211 221 | 
             
                  path = File.expand_path(path)
         | 
| 212 222 | 
             
                  client_cert = Dir.glob(path + '/*.{crt}').select{|f| File.file?(f.sub(/.crt\z/, '.key')) }
         | 
| 213 223 | 
             
                  raise 'Expect to find exactly one <num>.crt with corresponding <num>.key file' unless client_cert.size == 1
         | 
| 224 | 
            +
             | 
| 214 225 | 
             
                  client_cert = client_cert.first
         | 
| 215 226 |  | 
| 216 227 | 
             
                  unless signature_key
         | 
| @@ -234,6 +245,34 @@ module OrangeData | |
| 234 245 | 
             
                  )
         | 
| 235 246 | 
             
                end
         | 
| 236 247 |  | 
| 248 | 
            +
                def self.read_certs_from_zip_pack(rubyzip_object, signature_key_name:nil, cert_key_pass:nil, title:nil, signature_key:nil)
         | 
| 249 | 
            +
                  client_cert = rubyzip_object.glob("*.crt").select{|f| rubyzip_object.glob(f.name.sub(/.crt\z/, '.key')).any? }
         | 
| 250 | 
            +
                  raise 'Expect to find exactly one <num>.crt with corresponding <num>.key file' unless client_cert.size == 1
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                  client_cert = client_cert.first
         | 
| 253 | 
            +
                  client_key = rubyzip_object.glob(client_cert.name.sub(/.crt\z/, '.key')).first
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                  unless signature_key
         | 
| 256 | 
            +
                    # private_key_test.xml || rsa_\d+_private_key.xml
         | 
| 257 | 
            +
                    xmls = rubyzip_object.glob('/*.{xml}').select{|f| f =~ /private/ }
         | 
| 258 | 
            +
                    signature_key = if xmls.size == 1
         | 
| 259 | 
            +
                      xmls.first.get_input_stream.read
         | 
| 260 | 
            +
                    else
         | 
| 261 | 
            +
                      generate_signature_key(DEFAULT_KEY_LENGTH)
         | 
| 262 | 
            +
                      # .tap{|k| logger.info("Generated public signature key: #{k.public_key.to_xml}") }
         | 
| 263 | 
            +
                    end
         | 
| 264 | 
            +
                  end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                  from_hash(
         | 
| 267 | 
            +
                    title: title || "Generated from zip",
         | 
| 268 | 
            +
                    signature_key_name: signature_key_name || File.basename(client_cert.name).gsub(/\..*/, ''),
         | 
| 269 | 
            +
                    certificate: client_cert.get_input_stream.read,
         | 
| 270 | 
            +
                    certificate_key: client_key.get_input_stream.read,
         | 
| 271 | 
            +
                    certificate_key_pass: cert_key_pass,
         | 
| 272 | 
            +
                    signature_key: signature_key
         | 
| 273 | 
            +
                  )
         | 
| 274 | 
            +
                end
         | 
| 275 | 
            +
             | 
| 237 276 | 
             
                # публичная часть ключа подписи в формате пригодном для отдачи в ЛК
         | 
| 238 277 | 
             
                def signature_public_xml
         | 
| 239 278 | 
             
                  signature_key.public_key.to_xml
         | 
| @@ -10,7 +10,7 @@ module OrangeData | |
| 10 10 | 
             
                module StringExt
         | 
| 11 11 | 
             
                  refine String do
         | 
| 12 12 | 
             
                    def underscore
         | 
| 13 | 
            -
                       | 
| 13 | 
            +
                      gsub(/::/, '/').
         | 
| 14 14 | 
             
                        gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
         | 
| 15 15 | 
             
                        gsub(/([a-z\d])([A-Z])/, '\1_\2').
         | 
| 16 16 | 
             
                        tr("-", "_").
         | 
| @@ -30,25 +30,32 @@ module OrangeData | |
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 32 | 
             
                protected
         | 
| 33 | 
            +
             | 
| 33 34 | 
             
                def generate_accessors_from_schema(schema)
         | 
| 34 35 | 
             
                  plain_types = %w[integer string number]
         | 
| 35 36 | 
             
                  schema["properties"].each_pair do |property, info|
         | 
| 36 37 | 
             
                    property_name = info["x-name"] || property.underscore
         | 
| 37 38 |  | 
| 38 | 
            -
                    if plain_types.include?(info["type"])
         | 
| 39 | 
            +
                    if plain_types.include?(info["type"]) ||
         | 
| 40 | 
            +
                       info["type"].is_a?(Array) && plain_types.include?(info["type"].first) &&
         | 
| 41 | 
            +
                       info["type"].last == "null" && info["type"].size == 2
         | 
| 39 42 | 
             
                      if info["x-enum"]
         | 
| 40 43 | 
             
                        inverse_map = info["x-enum"].map{|k, v| [v['val'], k.to_sym] }.to_h
         | 
| 44 | 
            +
             | 
| 41 45 | 
             
                        define_method(property_name){
         | 
| 42 46 | 
             
                          return nil if @payload[property].nil?
         | 
| 47 | 
            +
             | 
| 43 48 | 
             
                          inverse_map[@payload[property]] ||
         | 
| 44 49 | 
             
                            raise("unknown value #{@payload[property].inspect} for field #{property}")
         | 
| 45 50 | 
             
                        }
         | 
| 46 51 | 
             
                        define_method(:"#{property_name}="){|val|
         | 
| 47 52 | 
             
                          unless val.nil?
         | 
| 48 | 
            -
                            val = ( | 
| 53 | 
            +
                            val = (
         | 
| 54 | 
            +
                              info["x-enum"][val.to_s] ||
         | 
| 49 55 | 
             
                              raise(ArgumentError, "unknown value #{val.inspect} for property #{property}")
         | 
| 50 56 | 
             
                            )["val"]
         | 
| 51 57 | 
             
                          end
         | 
| 58 | 
            +
             | 
| 52 59 | 
             
                          @payload[property] = val
         | 
| 53 60 | 
             
                        }
         | 
| 54 61 |  | 
| @@ -57,6 +64,7 @@ module OrangeData | |
| 57 64 | 
             
                        # TODO: return wrapper so that :<< etc will work
         | 
| 58 65 | 
             
                        define_method(property_name){
         | 
| 59 66 | 
             
                          return nil if @payload[property].nil?
         | 
| 67 | 
            +
             | 
| 60 68 | 
             
                          data = @payload[property].to_i
         | 
| 61 69 | 
             
                          # FIXME: unknown bits will be silently lost
         | 
| 62 70 | 
             
                          bitmap.reject{|_, v| (data & v).zero? }.map(&:first)
         | 
| @@ -64,7 +72,9 @@ module OrangeData | |
| 64 72 | 
             
                        define_method(:"#{property_name}="){|val|
         | 
| 65 73 | 
             
                          unless val.nil?
         | 
| 66 74 | 
             
                            val = [val] unless val.is_a?(Array)
         | 
| 67 | 
            -
                            val = val.map{|v| | 
| 75 | 
            +
                            val = val.map{|v|
         | 
| 76 | 
            +
                              bitmap[v] || raise(ArgumentError, "unknown value #{v.inspect} for property #{property}")
         | 
| 77 | 
            +
                            }.reduce(:|)
         | 
| 68 78 | 
             
                          end
         | 
| 69 79 | 
             
                          @payload[property] = val
         | 
| 70 80 | 
             
                        }
         | 
| @@ -80,15 +90,16 @@ module OrangeData | |
| 80 90 | 
             
                          val = [val] unless val.is_a?(Array)
         | 
| 81 91 | 
             
                          @payload[property] = val
         | 
| 82 92 | 
             
                        }
         | 
| 83 | 
            -
             | 
| 93 | 
            +
                        # else
         | 
| 84 94 | 
             
                        # ref?
         | 
| 85 95 | 
             
                      end
         | 
| 86 | 
            -
             | 
| 96 | 
            +
             | 
| 97 | 
            +
                      # else
         | 
| 87 98 |  | 
| 88 99 | 
             
                    end
         | 
| 89 100 |  | 
| 90 101 | 
             
                    if info["x-alias"]
         | 
| 91 | 
            -
                      alias_method  | 
| 102 | 
            +
                      alias_method info['x-alias'].to_s, property_name
         | 
| 92 103 | 
             
                      alias_method "#{info['x-alias']}=", "#{property_name}="
         | 
| 93 104 | 
             
                    end
         | 
| 94 105 | 
             
                  end
         | 
| @@ -111,7 +122,7 @@ module OrangeData | |
| 111 122 | 
             
                end
         | 
| 112 123 |  | 
| 113 124 | 
             
                def attributes
         | 
| 114 | 
            -
                  to_hash.map{|(k,v)| [k.underscore, v] }.to_h
         | 
| 125 | 
            +
                  to_hash.map{|(k, v)| [k.underscore, v] }.to_h
         | 
| 115 126 | 
             
                end
         | 
| 116 127 |  | 
| 117 128 | 
             
                def ==(other)
         | 
    
        data/lib/orange_data/receipt.rb
    CHANGED
    
    | @@ -11,14 +11,15 @@ module OrangeData | |
| 11 11 | 
             
              # main class for receipt/correction
         | 
| 12 12 | 
             
              class Document
         | 
| 13 13 |  | 
| 14 | 
            -
                attr_accessor :id, :inn, :group, :key_name, :content
         | 
| 14 | 
            +
                attr_accessor :id, :inn, :group, :key_name, :content, :callback_url
         | 
| 15 15 |  | 
| 16 | 
            -
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil)
         | 
| 16 | 
            +
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil, callback_url: nil)
         | 
| 17 17 | 
             
                  @id = id
         | 
| 18 18 | 
             
                  @inn = inn
         | 
| 19 19 | 
             
                  @group = group
         | 
| 20 20 | 
             
                  @key_name = key_name || inn
         | 
| 21 21 | 
             
                  @content = content if content
         | 
| 22 | 
            +
                  @callback_url = callback_url
         | 
| 22 23 | 
             
                  yield @content if block_given?
         | 
| 23 24 | 
             
                end
         | 
| 24 25 |  | 
| @@ -29,12 +30,14 @@ module OrangeData | |
| 29 30 | 
             
                    group: group || 'Main',
         | 
| 30 31 | 
             
                    content: content,
         | 
| 31 32 | 
             
                    key: key_name
         | 
| 33 | 
            +
                  }.tap{|h|
         | 
| 34 | 
            +
                    h[:callbackUrl] = @callback_url if @callback_url
         | 
| 32 35 | 
             
                  }.to_json(*args)
         | 
| 33 36 | 
             
                end
         | 
| 34 37 | 
             
              end
         | 
| 35 38 |  | 
| 36 39 | 
             
              class Receipt < Document
         | 
| 37 | 
            -
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil)
         | 
| 40 | 
            +
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil, callback_url: nil)
         | 
| 38 41 | 
             
                  @content = ReceiptContent.new(content || {})
         | 
| 39 42 | 
             
                  super
         | 
| 40 43 | 
             
                end
         | 
| @@ -53,10 +56,11 @@ module OrangeData | |
| 53 56 | 
             
                  # TODO: import...
         | 
| 54 57 | 
             
                  # TODO: taxationSystem default in checkclose
         | 
| 55 58 | 
             
                  @check_close = CheckClose.new(@payload['checkClose'])
         | 
| 56 | 
            -
                  @positions = (@payload['positions'] || []).map{|pos| Position.new(pos) }
         | 
| 57 59 | 
             
                  if @payload["additionalUserAttribute"]
         | 
| 58 60 | 
             
                    @additional_user_attribute = AdditionalUserAttribute.new(@payload["additionalUserAttribute"])
         | 
| 59 61 | 
             
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  @positions = (@payload['positions'] || []).map{|pos| Position.new(pos) }
         | 
| 60 64 | 
             
                end
         | 
| 61 65 |  | 
| 62 66 | 
             
                # сырой тип используется в qr_code
         | 
| @@ -98,7 +102,7 @@ module OrangeData | |
| 98 102 | 
             
                def set_agent_info(**options)
         | 
| 99 103 | 
             
                  # agent info may have some validations/transformations, so
         | 
| 100 104 | 
             
                  agent_info = AgentInfo.new.assign_attributes(options)
         | 
| 101 | 
            -
                  assign_attributes(agent_info.attributes.reject{|_k,v| v.nil?})
         | 
| 105 | 
            +
                  assign_attributes(agent_info.attributes.reject{|_k, v| v.nil? })
         | 
| 102 106 | 
             
                end
         | 
| 103 107 |  | 
| 104 108 | 
             
                class Position < PayloadContent
         | 
| @@ -178,6 +182,7 @@ module OrangeData | |
| 178 182 |  | 
| 179 183 | 
             
                def self.from_hash(hash)
         | 
| 180 184 | 
             
                  raise ArgumentError, 'Expect hash here' unless hash.is_a?(Hash)
         | 
| 185 | 
            +
             | 
| 181 186 | 
             
                  new(hash)
         | 
| 182 187 | 
             
                end
         | 
| 183 188 |  | 
| @@ -207,7 +212,7 @@ module OrangeData | |
| 207 212 | 
             
              # Correction
         | 
| 208 213 |  | 
| 209 214 | 
             
              class Correction < Document
         | 
| 210 | 
            -
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil)
         | 
| 215 | 
            +
                def initialize(id:SecureRandom.uuid, inn:, group:nil, key_name:nil, content:nil, callback_url: nil)
         | 
| 211 216 | 
             
                  @content = CorrectionContent.new(content || {})
         | 
| 212 217 | 
             
                  super
         | 
| 213 218 | 
             
                end
         | 
| @@ -232,6 +237,7 @@ module OrangeData | |
| 232 237 |  | 
| 233 238 | 
             
                def self.from_hash(hash)
         | 
| 234 239 | 
             
                  raise ArgumentError, 'Expect hash here' unless hash.is_a?(Hash)
         | 
| 240 | 
            +
             | 
| 235 241 | 
             
                  new(hash)
         | 
| 236 242 | 
             
                end
         | 
| 237 243 |  | 
| @@ -42,6 +42,10 @@ definitions: | |
| 42 42 | 
             
                  content:
         | 
| 43 43 | 
             
                    title: Содержимое документа
         | 
| 44 44 | 
             
                    "$ref": "#/definitions/CheckContent"
         | 
| 45 | 
            +
                  callbackUrl:
         | 
| 46 | 
            +
                    description: URL для отправки результатов обработки чека POST запросом
         | 
| 47 | 
            +
                    type: [string, "null"]
         | 
| 48 | 
            +
                    maxLength: 1024
         | 
| 45 49 |  | 
| 46 50 |  | 
| 47 51 | 
             
              CheckContent:
         | 
| @@ -361,15 +365,15 @@ definitions: | |
| 361 365 | 
             
                    format: byte
         | 
| 362 366 | 
             
                    minLength: 1
         | 
| 363 367 | 
             
                    maxLength: 32
         | 
| 368 | 
            +
                  supplierINN:
         | 
| 369 | 
            +
                    title: ИНН поставщика
         | 
| 370 | 
            +
                    x-tag-id: 1226
         | 
| 371 | 
            +
                    type: string
         | 
| 364 372 | 
             
                  supplierInfo:
         | 
| 365 373 | 
             
                    "$ref": "#/definitions/SupplierInfo"
         | 
| 366 374 | 
             
                    title: Данные поставщика
         | 
| 367 375 | 
             
                    nullable: true
         | 
| 368 376 | 
             
                    x-tag-id: 1224
         | 
| 369 | 
            -
                  supplierINN:
         | 
| 370 | 
            -
                    title: ИНН поставщика
         | 
| 371 | 
            -
                    x-tag-id: 1226
         | 
| 372 | 
            -
                    type: string
         | 
| 373 377 | 
             
                  agentType:
         | 
| 374 378 | 
             
                    x-tag-id: 1222
         | 
| 375 379 | 
             
                    x-todo: DRY 1057?
         | 
| @@ -613,6 +617,11 @@ definitions: | |
| 613 617 | 
             
                    type: string
         | 
| 614 618 | 
             
                  content:
         | 
| 615 619 | 
             
                    "$ref": "#/definitions/CorrectionContent"
         | 
| 620 | 
            +
                  callbackUrl:
         | 
| 621 | 
            +
                    description: URL для отправки результатов обработки чека POST запросом
         | 
| 622 | 
            +
                    type: [string, "null"]
         | 
| 623 | 
            +
                    maxLength: 1024
         | 
| 624 | 
            +
             | 
| 616 625 |  | 
| 617 626 |  | 
| 618 627 | 
             
              CorrectionContent:
         | 
| @@ -833,6 +842,11 @@ definitions: | |
| 833 842 | 
             
                  fp:
         | 
| 834 843 | 
             
                    title: Фискальный признак
         | 
| 835 844 | 
             
                    type: string
         | 
| 845 | 
            +
                  callbackUrl:
         | 
| 846 | 
            +
                    description: URL для отправки результатов обработки чека POST запросом
         | 
| 847 | 
            +
                    type: [string, "null"]
         | 
| 848 | 
            +
                    maxLength: 1024
         | 
| 849 | 
            +
             | 
| 836 850 |  | 
| 837 851 |  | 
| 838 852 | 
             
              CheckStatusViewModel[CorrectionContent]:
         | 
| @@ -902,3 +916,8 @@ definitions: | |
| 902 916 | 
             
                    title: Фискальный признак
         | 
| 903 917 | 
             
                    type: string
         | 
| 904 918 | 
             
                    maxLength: 10
         | 
| 919 | 
            +
                  callbackUrl:
         | 
| 920 | 
            +
                    description: URL для отправки результатов обработки чека POST запросом
         | 
| 921 | 
            +
                    type: [string, "null"]
         | 
| 922 | 
            +
                    maxLength: 1024
         | 
| 923 | 
            +
             | 
| @@ -14,6 +14,7 @@ module OrangeData | |
| 14 14 |  | 
| 15 15 | 
             
                def initialize(api_url=DEFAULT_TEST_API_URL, credentials=Credentials.default_test)
         | 
| 16 16 | 
             
                  raise ArgumentError, "Need full credentials for connection" unless credentials.valid?
         | 
| 17 | 
            +
             | 
| 17 18 | 
             
                  @credentials = credentials
         | 
| 18 19 | 
             
                  @api_url = api_url
         | 
| 19 20 | 
             
                end
         | 
| @@ -92,15 +93,20 @@ module OrangeData | |
| 92 93 |  | 
| 93 94 | 
             
                  def retry
         | 
| 94 95 | 
             
                    raise "not-retriable" unless should_retry?
         | 
| 95 | 
            -
             | 
| 96 | 
            +
             | 
| 97 | 
            +
                    @transport.post_entity(@sub_url, @data,
         | 
| 98 | 
            +
                      raise_errors:false, result_class:self.class, retry_count:(retry_count + 1))
         | 
| 96 99 | 
             
                  end
         | 
| 97 100 |  | 
| 98 101 | 
             
                  protected
         | 
| 99 | 
            -
             | 
| 102 | 
            +
             | 
| 103 | 
            +
                  def get_result_with(get_method)
         | 
| 100 104 | 
             
                    raise "Non-success" unless success?
         | 
| 101 | 
            -
             | 
| 105 | 
            +
             | 
| 106 | 
            +
                    @transport.send(
         | 
| 107 | 
            +
                      get_method,
         | 
| 102 108 | 
             
                      @data.respond_to?(:inn) && @data.inn || @data[:inn] || @data["inn"],
         | 
| 103 | 
            -
                      @data.respond_to?(:id) && @data.id || @data[:id] || @data["id"] | 
| 109 | 
            +
                      @data.respond_to?(:id) && @data.id || @data[:id] || @data["id"]
         | 
| 104 110 | 
             
                    )
         | 
| 105 111 | 
             
                  end
         | 
| 106 112 | 
             
                end
         | 
| @@ -122,20 +128,32 @@ module OrangeData | |
| 122 128 |  | 
| 123 129 | 
             
                  case res.status
         | 
| 124 130 | 
             
                  when 201
         | 
| 125 | 
            -
                    return result_class.new(success: true, data:data, sub_url:sub_url, retry_count: | 
| 131 | 
            +
                    return result_class.new(success: true, data:data, sub_url:sub_url, retry_count:retry_count, transport:self)
         | 
| 126 132 | 
             
                  when 409
         | 
| 127 133 | 
             
                    raise "Conflict" if raise_errors
         | 
| 128 | 
            -
             | 
| 134 | 
            +
             | 
| 135 | 
            +
                    return result_class.new(data:data, sub_url:sub_url, errors:["Duplicate id"], retry_count:retry_count)
         | 
| 129 136 | 
             
                  when 400
         | 
| 130 137 | 
             
                    raise "Invalid doc: #{res.body['errors'] || res.body}" if raise_errors
         | 
| 131 | 
            -
             | 
| 138 | 
            +
             | 
| 139 | 
            +
                    return result_class.new(data:data, sub_url:sub_url, errors:res.body['errors'], retry_count:retry_count)
         | 
| 132 140 | 
             
                  when 503
         | 
| 133 141 | 
             
                    if res.headers['Retry-After']
         | 
| 134 142 | 
             
                      raise "Document queue full, retry in #{res.headers['Retry-After']}" if raise_errors
         | 
| 135 | 
            -
             | 
| 143 | 
            +
             | 
| 144 | 
            +
                      return result_class.new(
         | 
| 145 | 
            +
                        attempt_retry: true,
         | 
| 146 | 
            +
                        retry_in: res.headers['Retry-After'].to_i,
         | 
| 147 | 
            +
                        data: data,
         | 
| 148 | 
            +
                        sub_url: sub_url,
         | 
| 149 | 
            +
                        retry_count: retry_count,
         | 
| 150 | 
            +
                        transport: self
         | 
| 151 | 
            +
                      )
         | 
| 136 152 | 
             
                    end
         | 
| 137 153 | 
             
                  end
         | 
| 154 | 
            +
             | 
| 138 155 | 
             
                  raise "Unknown code from OD: #{res.status} #{res.reason_phrase} #{res.body}" if raise_errors
         | 
| 156 | 
            +
             | 
| 139 157 | 
             
                  result_class.new(attempt_retry:true, data:data, sub_url:sub_url, retry_count:0, transport:self)
         | 
| 140 158 | 
             
                end
         | 
| 141 159 |  | 
    
        data/lib/orange_data/version.rb
    CHANGED
    
    
    
        data/orangedata.gemspec
    CHANGED
    
    | @@ -33,6 +33,7 @@ Gem::Specification.new do |spec| | |
| 33 33 | 
             
              spec.add_development_dependency "rake", "~> 10.0"
         | 
| 34 34 | 
             
              spec.add_development_dependency "rspec"
         | 
| 35 35 | 
             
              spec.add_development_dependency "rubocop"
         | 
| 36 | 
            +
              spec.add_development_dependency "rubyzip"
         | 
| 36 37 | 
             
              spec.add_development_dependency "simplecov"
         | 
| 37 38 | 
             
              spec.add_development_dependency "webmock"
         | 
| 38 39 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: orangedata
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Vasily Fedoseyev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2019-06- | 
| 11 | 
            +
            date: 2019-06-20 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: faraday
         | 
| @@ -108,6 +108,20 @@ dependencies: | |
| 108 108 | 
             
                - - ">="
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: rubyzip
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 111 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 126 | 
             
              name: simplecov
         | 
| 113 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -185,8 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 185 199 | 
             
                - !ruby/object:Gem::Version
         | 
| 186 200 | 
             
                  version: '0'
         | 
| 187 201 | 
             
            requirements: []
         | 
| 188 | 
            -
             | 
| 189 | 
            -
            rubygems_version: 2.5.1
         | 
| 202 | 
            +
            rubygems_version: 3.0.2
         | 
| 190 203 | 
             
            signing_key: 
         | 
| 191 204 | 
             
            specification_version: 4
         | 
| 192 205 | 
             
            summary: Ruby client for orangedata.ru service
         |