biro 0.2.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.
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"