biro 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +21 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +11 -0
  11. data/bin/setup +8 -0
  12. data/biro.gemspec +34 -0
  13. data/lib/biro/configuration.rb +28 -0
  14. data/lib/biro/gateways/bacen/request.rb +54 -0
  15. data/lib/biro/gateways/bacen/response.rb +109 -0
  16. data/lib/biro/gateways/bacen.rb +2 -0
  17. data/lib/biro/gateways/base_request.rb +30 -0
  18. data/lib/biro/gateways/base_response.rb +5 -0
  19. data/lib/biro/gateways/bvs/builders/base_builder.rb +17 -0
  20. data/lib/biro/gateways/bvs/builders/debits_request_builder.rb +26 -0
  21. data/lib/biro/gateways/bvs/builders/debits_response_builder.rb +45 -0
  22. data/lib/biro/gateways/bvs/builders/score_request_builder.rb +24 -0
  23. data/lib/biro/gateways/bvs/builders/score_response_builder.rb +93 -0
  24. data/lib/biro/gateways/bvs/request.rb +71 -0
  25. data/lib/biro/gateways/bvs/response.rb +56 -0
  26. data/lib/biro/gateways/bvs.rb +7 -0
  27. data/lib/biro/gateways/cred_defense/request.rb +69 -0
  28. data/lib/biro/gateways/cred_defense/response.rb +131 -0
  29. data/lib/biro/gateways/cred_defense.rb +2 -0
  30. data/lib/biro/gateways/midia100/request.rb +59 -0
  31. data/lib/biro/gateways/midia100/response.rb +166 -0
  32. data/lib/biro/gateways/midia100.rb +2 -0
  33. data/lib/biro/gateways/ph3a/builders/login_builder.rb +15 -0
  34. data/lib/biro/gateways/ph3a/request.rb +72 -0
  35. data/lib/biro/gateways/ph3a/response.rb +340 -0
  36. data/lib/biro/gateways/ph3a.rb +3 -0
  37. data/lib/biro/gateways/spc/request.rb +59 -0
  38. data/lib/biro/gateways/spc/response.rb +190 -0
  39. data/lib/biro/gateways/spc.rb +2 -0
  40. data/lib/biro/gateways.rb +8 -0
  41. data/lib/biro/response.rb +15 -0
  42. data/lib/biro/utils/soap.rb +27 -0
  43. data/lib/biro/utils.rb +11 -0
  44. data/lib/biro/version.rb +3 -0
  45. data/lib/biro.rb +31 -0
  46. metadata +206 -0
@@ -0,0 +1,340 @@
1
+ require 'active_support/core_ext/array'
2
+
3
+ module Biro
4
+ module Ph3a
5
+ class Response < BaseResponse
6
+ def initialize response
7
+ @body = response.body
8
+ end
9
+
10
+ def addresses
11
+ Array.wrap(person_data_result.dig(:addresses)&.dig(:source)&.dig(:address)).map do |t|
12
+ {
13
+ city: t.dig(:city),
14
+ complement: t.dig(:complement),
15
+ country: t.dig(:country),
16
+ is_enabled: t.dig(:is_enabled),
17
+ match: t.dig(:match),
18
+ neighboorhood: t.dig(:district),
19
+ number: t.dig(:number),
20
+ score: t.dig(:score).to_i,
21
+ state: t.dig(:state),
22
+ street: t.dig(:street),
23
+ type: t.dig(:type),
24
+ zip_code: t.dig(:zip_code),
25
+ phone_area_code: t.dig(:area_code),
26
+ phone: t.dig(:phone)
27
+ }
28
+ end
29
+ end
30
+
31
+ def age
32
+ person_data_result.dig(:age).to_i
33
+ end
34
+
35
+ def birthdate
36
+ person_data_result.dig(:birth_date)
37
+ end
38
+
39
+ def blood_type
40
+ person_data_result.dig(:blood_type)
41
+ end
42
+
43
+ def ccf
44
+ person_data_result.dig(:ccf)
45
+ end
46
+
47
+ def ccf_history
48
+ Array.wrap(person_data_result.dig(:ccf_historico)&.dig(:ccf)).map do |t|
49
+ {
50
+ agency: t.dig(:agencia).to_i,
51
+ bank_code: t.dig(:codigo_banco).to_i,
52
+ reason: t.dig(:motivo),
53
+ amount: t.dig(:quantidade),
54
+ occurrence_date: t.dig(:ultima_ocorrencia),
55
+ }
56
+ end
57
+ end
58
+
59
+ def ccf_total
60
+ person_data_result.dig(:ccf_total).to_i
61
+ end
62
+
63
+ def compound_name
64
+ person_data_result.dig(:compound_name)
65
+ end
66
+
67
+ def contact_persons
68
+ person_data_result.dig(:contact_persons)
69
+ end
70
+
71
+ def contact_persons_history
72
+ person_data_result.dig(:contact_persons_history)
73
+ end
74
+
75
+ def death_date
76
+ person_data_result.dig(:death_date)
77
+ end
78
+
79
+ def death_year
80
+ person_data_result.dig(:death_year)
81
+ end
82
+
83
+ def deficiency
84
+ person_data_result.dig(:deficiency)
85
+ end
86
+
87
+ def deficiency_list
88
+ person_data_result.dig(:deficiencys)
89
+ end
90
+
91
+ def digital_behavior
92
+ person_data_result.dig(:digital_behavior)
93
+ end
94
+
95
+ def cpf
96
+ person_data_result.dig(:document)
97
+ end
98
+
99
+ def education
100
+ {
101
+ description: person_data_result.dig(:education_level)&.dig(:description),
102
+ level: person_data_result.dig(:education_level)&.dig(:education_level).to_i
103
+ }
104
+ end
105
+
106
+ def emails
107
+ Array.wrap(person_data_result.dig(:emails)&.dig(:email)).map do |t|
108
+ {
109
+ address: t.dig(:email_value),
110
+ is_enabled: t.dig(:is_enabled),
111
+ }
112
+ end
113
+ end
114
+
115
+ def eye_color
116
+ person_data_result.dig(:eye_color)
117
+ end
118
+
119
+ def fathers_document
120
+ person_data_result.dig(:father_document)
121
+ end
122
+
123
+ def fathers_name
124
+ person_data_result.dig(:father_name)
125
+ end
126
+
127
+ def first_name
128
+ person_data_result.dig(:first_name)
129
+ end
130
+
131
+ def gender
132
+ person_data_result.dig(:genre)
133
+ end
134
+
135
+ def hair_color
136
+ person_data_result.dig(:hair_color)
137
+ end
138
+
139
+ def height
140
+ person_data_result.dig(:height)
141
+ end
142
+
143
+ def rg
144
+ person_data_result.dig(:id_card)
145
+ end
146
+
147
+ def rg_state
148
+ person_data_result.dig(:id_card_state)
149
+ end
150
+
151
+ def last_name
152
+ person_data_result.dig(:last_name)
153
+ end
154
+
155
+ def marital_status
156
+ person_data_result.dig(:marital_status)
157
+ end
158
+
159
+ def match_name
160
+ person_data_result.dig(:match_name)
161
+ end
162
+
163
+ def middle_name
164
+ person_data_result.dig(:middle_name)
165
+ end
166
+
167
+ def mothers_document
168
+ person_data_result.dig(:mother_document)
169
+ end
170
+
171
+ def mothers_name
172
+ person_data_result.dig(:mother_name)
173
+ end
174
+
175
+ def nacionality
176
+ person_data_result.dig(:nacionality)
177
+ end
178
+
179
+ def name
180
+ person_data_result.dig(:name)
181
+ end
182
+
183
+ def name_cpf_brasil
184
+ person_data_result.dig(:name_cpf_brasil)
185
+ end
186
+
187
+ def number_dependents
188
+ person_data_result.dig(:number_dependents).to_i
189
+ end
190
+
191
+ def phones
192
+ Array.wrap(person_data_result.dig(:phones)&.dig(:phone)).map do |t|
193
+ {
194
+ area_code: t.dig(:area_code).to_i,
195
+ at_procon: t.dig(:at_procon),
196
+ document: t.dig(:document),
197
+ full_name: t.dig(:full_name),
198
+ is_enabled: t.dig(:is_enabled),
199
+ is_household: t.dig(:is_household),
200
+ is_mobile: t.dig(:is_mobile),
201
+ number_simple: t.dig(:number_simple),
202
+ number: t.dig(:phone_number),
203
+ operator_name: t.dig(:phone_operator_name)
204
+ }
205
+ end
206
+ end
207
+
208
+ def pep
209
+ person_data_result.dig(:politically_exposed_person)
210
+ end
211
+
212
+ def person_household
213
+ Array.wrap(person_data_result.dig(:person_household)&.dig(:person_household)).map do |t|
214
+ {
215
+ addresses: person_household_addresses(t.dig(:adresses)),
216
+ call_name: t.dig(:call_name),
217
+ complete_name: t.dig(:complete_name),
218
+ document: t.dig(:document),
219
+ father_name: t.dig(:father_name),
220
+ first_name: t.dig(:first_name),
221
+ genre: t.dig(:genre),
222
+ iptu: t.dig(:iptu),
223
+ kinship: t.dig(:kinship),
224
+ last_name: t.dig(:last_name),
225
+ match_name: t.dig(:match_name),
226
+ middle_name: t.dig(:middle_name),
227
+ mother_name: t.dig(:mother_name),
228
+ second_name: t.dig(:second_name),
229
+ suffix_name: t.dig(:suffix_name),
230
+ vehicles: t.dig(:vehicles)
231
+ }
232
+ end
233
+ end
234
+
235
+ def professional_info
236
+ Array.wrap(person_data_result.dig(:professional_data)&.dig(:professional_data)).map do |t|
237
+ {
238
+ cbo: t.dig(:cbo).to_i,
239
+ cbo_description: t.dig(:cbo_descricao),
240
+ company_cnpj: t.dig(:cnpj),
241
+ company_address: t.dig(:cmpany_address),
242
+ admission_date: t.dig(:data_admissao),
243
+ resignation_date: t.dig(:data_demissao),
244
+ family_salary: t.dig(:family_salary),
245
+ pis: t.dig(:pis),
246
+ social_name: t.dig(:razao_social),
247
+ income_from: t.dig(:renda_de).to_f,
248
+ income_to: t.dig(:renda_ate).to_f,
249
+ salary: t.dig(:salario).to_f,
250
+ admission_type: t.dig(:tipo_admissao).to_i,
251
+ resignation_type: t.dig(:tipo_demissao).to_i
252
+ }
253
+ end
254
+ end
255
+
256
+ def retired
257
+ person_data_result.dig(:retired_data)
258
+ end
259
+
260
+ def second_name
261
+ person_data_result.dig(:second_name)
262
+ end
263
+
264
+ def skin_color
265
+ person_data_result.dig(:skin_color)
266
+ end
267
+
268
+ def spouses_document
269
+ person_data_result.dig(:spouse_document)
270
+ end
271
+
272
+ def spouses_name
273
+ person_data_result.dig(:spouse_name)
274
+ end
275
+
276
+ def death
277
+ person_data_result.dig(:supposed_death)
278
+ end
279
+
280
+ def vehicles
281
+ person_data_result.dig(:vehicles)
282
+ end
283
+
284
+ def voter_id
285
+ person_data_result.dig(:voter_registration)
286
+ end
287
+
288
+ def weight
289
+ person_data_result.dig(:weight).to_f
290
+ end
291
+
292
+ private
293
+
294
+ def person_data_result
295
+ @body.dig(:get_person_data_response)&.dig(:get_person_data_result)
296
+ end
297
+
298
+ def person_household_addresses address_list
299
+ Array.wrap(address_list.dig(:source)&.dig(:address)).map do |t|
300
+ {
301
+ city: t.dig(:city),
302
+ complement: t.dig(:complement),
303
+ country: t.dig(:country),
304
+ is_enabled: t.dig(:is_enabled),
305
+ match: t.dig(:match),
306
+ neighboorhood: t.dig(:district),
307
+ number: t.dig(:number),
308
+ score: t.dig(:score).to_i,
309
+ state: t.dig(:state),
310
+ street: t.dig(:street),
311
+ type: t.dig(:type),
312
+ zip_code: t.dig(:zip_code),
313
+ phone_area_code: t.dig(:area_code),
314
+ phone: t.dig(:phone),
315
+ phones: person_household_phones(t.dig(:phones))
316
+ }
317
+ end
318
+ end
319
+
320
+ def person_household_phones phones
321
+ return if phones.blank?
322
+
323
+ Array.wrap(phones.dig(:phone)).map do |t|
324
+ {
325
+ area_code: t.dig(:area_code).to_i,
326
+ at_procon: t.dig(:at_procon),
327
+ document: t.dig(:document),
328
+ full_name: t.dig(:full_name),
329
+ is_enabled: t.dig(:is_enabled),
330
+ is_household: t.dig(:is_household),
331
+ is_mobile: t.dig(:is_mobile),
332
+ number_simple: t.dig(:number_simple),
333
+ number: t.dig(:phone_number),
334
+ operator_name: t.dig(:phone_operator_name)
335
+ }
336
+ end
337
+ end
338
+ end
339
+ end
340
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'ph3a/request'
2
+ require_relative 'ph3a/response'
3
+ require_relative 'ph3a/builders/login_builder'
@@ -0,0 +1,59 @@
1
+ module Biro
2
+ module Spc
3
+ class Request < BaseRequest
4
+ include Utils::Soap
5
+
6
+ SCORE_3_MONTHS = 77
7
+ SCORE_12_MONTHS = 78
8
+
9
+ def development_url
10
+ 'https://treina.spc.org.br/spc/remoting/ws/consulta/consultaWebService?wsdl'
11
+ end
12
+
13
+ def production_url
14
+ 'https://servicos.spc.org.br/spc/remoting/ws/consulta/consultaWebService?wsdl'
15
+ end
16
+
17
+ def required_params
18
+ [:username, :password]
19
+ end
20
+
21
+ def find(document, options = {})
22
+ begin
23
+ params = {}
24
+ add_basic_info(params, document, options[:kind] || 'F', options[:product_code])
25
+ add_score_info(params) if options[:include_score]
26
+
27
+ response = soap.call(:consultar, message: params)
28
+ Response.new(response)
29
+ rescue => e
30
+ Biro.log(:warn, "Unable to process SPC request")
31
+ raise AuthenticationError.new("Error at SPC request: #{e.message}") if e.message.include?("CS_AUT")
32
+ raise DocumentNotFoundError.new("Error at SPC request: #{e.message}") if e.message.include?("CPF inválido") || e.message.include?("(7)")
33
+ raise StandardError.new("Error at SPC request: #{e.message}")
34
+ end
35
+ end
36
+
37
+ def display_products
38
+ response = soap.call(:listar_produtos, xml: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header /><soapenv:Body /></soapenv:Envelope>')
39
+ response.body
40
+ end
41
+
42
+ private
43
+
44
+ def savon_options
45
+ { basic_auth: [@username, @password] }
46
+ end
47
+
48
+ def add_basic_info(params, document, kind, product_code)
49
+ params['codigo-produto'] = product_code
50
+ params['tipo-consumidor'] = kind
51
+ params['documento-consumidor'] = document
52
+ end
53
+
54
+ def add_score_info(request)
55
+ request['codigo-insumo-opcional'] = [SCORE_3_MONTHS, SCORE_12_MONTHS]
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,190 @@
1
+ require 'active_support/core_ext/array'
2
+
3
+ module Biro
4
+ module Spc
5
+ class Response < BaseResponse
6
+ def initialize(response)
7
+ @body = response.body
8
+ end
9
+
10
+ def cpf
11
+ person.dig(:cpf, :@numero)
12
+ end
13
+
14
+ def birthdate
15
+ fetch_date(person.dig(:@data_nascimento))
16
+ end
17
+
18
+ def marital_status
19
+ person.dig(:@estado_civil)
20
+ end
21
+
22
+ def mothers_name
23
+ person.dig(:@nome_mae)
24
+ end
25
+
26
+ def fathers_name
27
+ person.dig(:@nome_pai)
28
+ end
29
+
30
+ def rg
31
+ person.dig(:@numero_rg)
32
+ end
33
+
34
+ def name
35
+ person.dig(:@nome)
36
+ end
37
+
38
+ def voter_id
39
+ person.dig(:@numero_titulo_eleitor)
40
+ end
41
+
42
+ def gender
43
+ person.dig(:@sexo)
44
+ end
45
+
46
+ def income
47
+ result.dig(:renda_presumida_spc, :resumo, :@valor_total)&.to_f&.round(2)
48
+ end
49
+
50
+ def receita_federal
51
+ return nil unless rf
52
+
53
+ { status: rf.dig(:@descricao_situacao), date: fetch_date(rf.dig(:@data_situacao)) }
54
+ end
55
+
56
+ def addresses
57
+ [single_address] + all_addresses
58
+ end
59
+
60
+ def phones
61
+ [single_phone] + all_phones
62
+ end
63
+
64
+ def defaults
65
+ Array.wrap(spc).map do |d|
66
+ {
67
+ bureau: :spc,
68
+ company: d.dig(:@nome_associado)&.strip,
69
+ created_at: fetch_date(d.dig(:@data_inclusao)),
70
+ due_at: fetch_date(d.dig(:@data_vencimento)),
71
+ value: d.dig(:@valor)&.to_f,
72
+ city: d.dig(:cidade_associado, :@nome),
73
+ state: d.dig(:cidade_associado, :estado, :@sigla_uf),
74
+ phone: { ddd: d.dig(:telefone_associado, :@numero_ddd), number: d.dig(:telefone_associado, :@numero) },
75
+ contract: d.dig(:@contrato)
76
+ }
77
+ end
78
+ end
79
+
80
+ def scores
81
+ [:spc_score_3_meses, :spc_score_12_meses].map do |score|
82
+ next unless result.include? score
83
+
84
+ fetch_score(result.dig(score))
85
+ end.compact
86
+ end
87
+
88
+ def success?
89
+ error.blank?
90
+ end
91
+
92
+ def error
93
+ return nil unless registration.keys.first =~ /Erro/
94
+
95
+ error = registration.flatten
96
+ "#{error[0]} - #{error[1]['Mensagem']}"
97
+ end
98
+
99
+ def emails
100
+ Array.wrap(person&.dig(:@email))
101
+ end
102
+
103
+ private
104
+
105
+ def fetch_date(date)
106
+ Time.parse(date)
107
+ rescue
108
+ nil
109
+ end
110
+
111
+ def all_phones
112
+ phones = result.dig(:telefone_vinculado_consumidor, :detalhe_telefone_vinculado_consumidor)
113
+
114
+ Array.wrap(phones).map do |p|
115
+ phone = p.dig(:assinante, :telefone)
116
+ fetch_phone(phone)
117
+ end
118
+ end
119
+
120
+ def single_phone
121
+ phone = person.dig(:telefone_residencial)
122
+ return nil unless phone
123
+
124
+ fetch_phone(phone)
125
+ end
126
+
127
+ def fetch_phone(phone)
128
+ ddd = phone.dig(:@numero_ddd)
129
+ number = phone.dig(:@numero)
130
+ kind = (number.to_s[0] == '9' ? :mobile : :landline) if number
131
+
132
+ { ddd: ddd, number: number, kind: kind }
133
+ end
134
+
135
+ def all_addresses
136
+ Array.wrap(address&.fetch(:detalhe_ultimo_endereco_informado, nil)).map { |e| fetch_address(e) }
137
+ end
138
+
139
+
140
+ def single_address
141
+ fetch_address(person)
142
+ end
143
+
144
+ def fetch_address(e)
145
+ address = e.dig(:endereco)
146
+ city = address&.dig(:cidade, :@nome)
147
+ state = address&.dig(:cidade, :estado, :@sigla_uf)
148
+ street = address&.dig(:@logradouro)
149
+ number = address&.dig(:@numero)
150
+ complement = address&.dig(:@complemento)
151
+ zipcode = address&.dig(:@cep)
152
+
153
+ {
154
+ street: street,
155
+ number: number,
156
+ complement: complement,
157
+ city: city,
158
+ state: state,
159
+ zipcode: zipcode
160
+ }
161
+ end
162
+
163
+ def fetch_score(score)
164
+ data = score&.values&.first
165
+
166
+ { score_class: data.dig(:@classe), score: data.dig(:@score)&.to_i, period: data.dig(:@horizonte)&.to_i }
167
+ end
168
+
169
+ def address
170
+ result.dig(:ultimo_endereco_informado)
171
+ end
172
+
173
+ def rf
174
+ person.dig(:situacao_cpf)
175
+ end
176
+
177
+ def person
178
+ result.dig(:consumidor, :consumidor_pessoa_fisica)
179
+ end
180
+
181
+ def spc
182
+ result.dig(:spc, :detalhe_spc)
183
+ end
184
+
185
+ def result
186
+ @body.dig(:resultado)
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'spc/request'
2
+ require_relative 'spc/response'
@@ -0,0 +1,8 @@
1
+ require_relative 'gateways/base_request'
2
+ require_relative 'gateways/base_response'
3
+ require_relative 'gateways/spc'
4
+ require_relative 'gateways/midia100'
5
+ require_relative 'gateways/cred_defense'
6
+ require_relative 'gateways/bvs'
7
+ require_relative 'gateways/bacen'
8
+ require_relative 'gateways/ph3a'
@@ -0,0 +1,15 @@
1
+ module Biro
2
+ class Response
3
+ attr_reader :body, :message
4
+
5
+ def initialize(success, body = {})
6
+ @success = success
7
+ @message = message
8
+ @body = body
9
+ end
10
+
11
+ def success?
12
+ @success
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ require 'savon'
2
+
3
+ module Biro
4
+ module Utils
5
+ module Soap
6
+ def soap
7
+ default_options = {
8
+ wsdl: wsdl,
9
+ convert_request_keys_to: :none,
10
+ logger: Biro.config.logger,
11
+ log_level: :debug,
12
+ log: true
13
+ }
14
+
15
+ @savon ||= Savon.client(default_options.merge(savon_options))
16
+ end
17
+
18
+ def wsdl
19
+ url = Biro.development? ? self.development_url : self.production_url
20
+ end
21
+
22
+ def savon_options
23
+ {}
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/biro/utils.rb ADDED
@@ -0,0 +1,11 @@
1
+ require_relative 'utils/soap'
2
+
3
+ module Biro
4
+ module Utils
5
+ def camelize(word)
6
+ word.split('_').map(&:capitalize).join('')
7
+ end
8
+
9
+ module_function :camelize
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Biro
2
+ VERSION = "0.2.0"
3
+ end
data/lib/biro.rb ADDED
@@ -0,0 +1,31 @@
1
+ module Biro
2
+ class Error < StandardError; end
3
+
4
+ class << self
5
+ def config
6
+ Configuration.instance
7
+ end
8
+
9
+ def log(level, message)
10
+ config.logger.send(level, message)
11
+ end
12
+
13
+ def configure
14
+ yield config
15
+ end
16
+
17
+ def development?
18
+ config.development?
19
+ end
20
+
21
+ def gateways
22
+ @gateways ||= {}
23
+ end
24
+ end
25
+ end
26
+
27
+ require 'biro/version'
28
+ require 'biro/utils'
29
+ require "biro/configuration"
30
+ require "biro/response"
31
+ require "biro/gateways"