correios 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -5,46 +5,59 @@ Gem para cálculo de frete usando o e rastreamento dos correios usando webservic
5
5
  == Instalação
6
6
 
7
7
  $ gem install correios
8
-
8
+
9
9
  == Como Usar
10
10
 
11
11
  > require 'correios'
12
-
12
+
13
13
  # Para calcular apenas um serviço
14
14
  > correios = Correios.new(76410000, 74932180)
15
15
  > correios.calcular_frete(Correios::Servico::PAC, 0.4, 17, 16, 16)
16
16
 
17
17
 
18
18
  # Para calcular mais de um serviço
19
- # Neste caso o retorno será um hash.
19
+ # Neste caso o retorno será um hash.
20
20
  > correios = Correios.new(76410000, 74932180)
21
21
  > frete = correios.calcular_frete([Correios::Servico::PAC, Correios::Servico::SEDEX], 0.4, 17, 16, 16)
22
22
 
23
23
  > frete[:pac]
24
24
  => #<Correios::Servico:0x10189ad08 @message="", @servico=:pac, @erro="0", @prazo=5, @valor=11.5>
25
25
  > frete[:sedex]
26
- => #<Correios::Servico:0x10189a948 @message="", @servico=:sedex, @erro="0", @prazo=4, @valor=14.7>
26
+ => #<Correios::Servico:0x10189a948 @message="", @servico=:sedex, @erro="0", @prazo=4, @valor=14.7>
27
27
 
28
28
  == Outras informações
29
29
 
30
30
  Definição do método calcula frete:
31
31
 
32
- calcular_frete(servicos, peso, comprimento,
33
- altura, largura, diametro = 0, mao_propria = NAO,
34
- valor_declarado = 0, aviso_recebimento = NAO)
35
-
32
+ calcular_frete(servicos, peso, comprimento,
33
+ altura, largura, diametro = 0, mao_propria = NAO,
34
+ valor_declarado = 0, aviso_recebimento = NAO)
35
+
36
36
 
37
37
  Serviços:
38
-
38
+
39
39
  Correios::Servico::PAC
40
40
  Correios::Servico::SEDEX
41
41
  Correios::Servico::SEDEX10
42
42
  Correios::Servico::SEDEX_HOJE
43
43
  Correios::Servico::ESEDEX
44
-
44
+
45
+ == Rastreamento
46
+
47
+ require "correios"
48
+
49
+ rastreamento = Correios::Rastreamento.new "SS987654321BR"
50
+ rastreamento.buscar
51
+
52
+ #=> [{ :data => "21/04/2012 14:21", :local => "CTE SAUDE - SAO PAULO/SP", :descricao => "", :detalhes => "Entrega Efetuada" }]
53
+
54
+ rastreamento.chegou?
55
+
56
+ #=> true
57
+
45
58
  == Contato
46
59
 
47
60
  Caso tenha alguma dúvida ou sugestão entre em contato: bfscordeiro (em) gmail.com
48
61
 
49
62
 
50
- Copyright (c) 2010 Bruno Cordeiro, released under the MIT license
63
+ Copyright (c) 2010 Bruno Cordeiro, released under the MIT license
data/correios.gemspec CHANGED
@@ -6,12 +6,14 @@ Gem::Specification.new do |s|
6
6
  s.name = "correios"
7
7
  s.version = Correios::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Bruno Frank", "kurko"]
9
+ s.authors = ["Bruno Frank"]
10
10
  s.email = ["bfscordeiro@gmail.com"]
11
11
  s.homepage = "https://github.com/brunofrank/correios"
12
12
  s.summary = %q{Calcula o valor do frete dos Correios.}
13
13
  s.description = %q{Gem para calculo de valor e restreamento dos Correios.}
14
14
  s.add_dependency("xml-simple")
15
+ s.add_dependency("nokogiri")
16
+ s.add_development_dependency("mocha")
15
17
 
16
18
  s.rubyforge_project = "correios"
17
19
 
data/lib/correios.rb CHANGED
@@ -1,25 +1,27 @@
1
- require 'open-uri'
2
- require 'xmlsimple'
1
+ # -*- encoding: utf-8 -*-
2
+ require "open-uri"
3
+ require "xmlsimple"
4
+ require "date"
5
+ require "nokogiri"
3
6
 
4
7
  class Correios
5
-
6
8
  class Servico
7
9
  PAC = 41106
8
10
  SEDEX = 40010
9
11
  SEDEX10 = 40215
10
12
  SEDEX_HOJE = 40290
11
- ESEDEX = 81019
12
-
13
+ ESEDEX = 81019
14
+
13
15
  SERVICOS = {
14
16
  41106 => :pac,
15
17
  40010 => :sedex,
16
18
  40215 => :sedex10,
17
19
  40290 => :sedex_hoje,
18
20
  81019 => :esedex
19
- }
20
-
21
+ }
22
+
21
23
  attr_reader :servico, :valor, :prazo, :erro, :message
22
-
24
+
23
25
  def initialize(servico)
24
26
  @servico = SERVICOS[servico["Codigo"].first.to_i]
25
27
  @valor = servico["Valor"].first.gsub(/,/, '.').to_f
@@ -27,28 +29,73 @@ class Correios
27
29
  @erro = servico["Erro"].first.to_i
28
30
  @message = servico["MsgErro"].first
29
31
  end
30
-
32
+
31
33
  def valid?
32
34
  @erro == '0'
33
35
  end
34
36
  end
35
-
37
+
38
+ class Rastreamento
39
+ WEBSRO = "http://websro.correios.com.br/sro_bin/txect01$.QueryList?P_LINGUA=001&P_TIPO=001&P_COD_UNI"
40
+
41
+ def initialize(codigo)
42
+ if codigo.nil? or codigo.empty?
43
+ raise ArgumentError, "Especifique o código de rastreamento corretamente."
44
+ end
45
+
46
+ @codigo = codigo
47
+ end
48
+
49
+ def buscar
50
+ pagina = rastrear
51
+
52
+ return if pagina.xpath("//tr").count == 0
53
+
54
+ sro = []
55
+
56
+ pagina.xpath("//tr[position() > 1]").each do |linha|
57
+ if linha.search("td").count > 1
58
+ sro << {
59
+ :data => DateTime.strptime(linha.search("td[@rowspan][1]").text.strip, "%d/%m/%Y %H:%M"),
60
+ :local => linha.search("td[2]").text.strip,
61
+ :descricao => linha.search("td[3]").text.strip
62
+ }
63
+
64
+ if linha.search("td[@rowspan='2'][1]").count > 0
65
+ sro.last.merge! :detalhes => linha.search(".//following-sibling::tr[1]").text.strip
66
+ end
67
+ end
68
+ end
69
+
70
+ sro
71
+ end
72
+
73
+ def chegou?
74
+ buscar.first[:descricao] == "Entrega Efetuada"
75
+ end
76
+
77
+ private
78
+ def rastrear
79
+ Nokogiri::HTML open("#{WEBSRO}=#{@codigo}")
80
+ end
81
+ end
82
+
36
83
  SIM = 'S'
37
84
  NAO = 'N'
38
-
85
+
39
86
  def initialize(cep_origem, cep_destino)
40
- @cep_origem = cep_origem
41
- @cep_destino = cep_destino
87
+ @cep_origem = cep_origem
88
+ @cep_destino = cep_destino
42
89
  end
43
-
44
- def calcular_frete(servicos, peso, comprimento, altura, largura, diametro = 0, mao_propria = NAO,
90
+
91
+ def calcular_frete(servicos, peso, comprimento, altura, largura, diametro = 0, mao_propria = NAO,
45
92
  valor_declarado = 0, aviso_recebimento = NAO)
46
93
  host = 'http://ws.correios.com.br'
47
94
  path = '/calculador/CalcPrecoPrazo.aspx'
48
-
95
+
49
96
  identificadores = servicos
50
97
  identificadores = servicos.to_a.join(',') unless servicos.kind_of? Fixnum
51
-
98
+
52
99
  params = {
53
100
  :nCdEmpresa => '',
54
101
  :sDsSenha => '',
@@ -66,17 +113,17 @@ class Correios
66
113
  :nVlValorDeclarado => valor_declarado,
67
114
  :sCdAvisoRecebimento => aviso_recebimento
68
115
  }
69
-
116
+
70
117
  params = params.to_a.map {|item| item.to_a.join('=')} .join('&')
71
118
  xml = XmlSimple.xml_in(open("#{host}#{path}?#{params}").read)
72
119
 
73
120
  setup_services xml, servicos
74
121
  end
75
-
122
+
76
123
  def get_xml url
77
124
  XmlSimple.xml_in(open(url).read)
78
125
  end
79
-
126
+
80
127
  def setup_services xml, servicos
81
128
  if xml["cServico"].size > 1
82
129
  servicos = {}
@@ -88,4 +135,4 @@ class Correios
88
135
  end
89
136
  servicos
90
137
  end
91
- end
138
+ end
@@ -1,3 +1,3 @@
1
1
  class Correios
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><META http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>
2
+ <div bgcolor="d8e6ed" text="0000FF" link="000000" vlink="800040" alink="0FF000">
3
+ <form action="http://txect01$.ResultList" method="POST" target="_blank" onsubmit="return window.confirm(&quot;Você está enviando informações para uma página externa.\nTem certeza?&quot;);">
4
+ <input type="hidden" name="Z_START" value="1">
5
+ <input type="hidden" name="P_ITEMCODE" value="PB000000000BR">
6
+ <input type="hidden" name="P_LINGUA" value="001">
7
+ <input type="hidden" name="P_COD_UNI" value="PB000000000BR">
8
+ <input type="hidden" name="P_COD_INI" value="">
9
+ <input type="hidden" name="P_COD_FIN" value="">
10
+ <input type="hidden" name="P_COD_LIS" value="">
11
+ <input type="hidden" name="P_TESTE" value="">
12
+ <input type="hidden" name="P_TIPO" value="001">
13
+ <h1> </h1>
14
+ <img align="absmiddle" src="http://../correios/Img/correios.gif"><font face="Arial" size="3" color="#000000"><b>
15
+ PB000000000BR
16
+ - Histórico do Objeto</b></font>
17
+ <font face="Arial" color="black" size="2">
18
+ <br>O horário não indica quando a situação ocorreu, mas sim quando os dados foram recebidos pelo sistema, exceto no caso do <b>SEDEX 10 e do SEDEX Hoje, </b>em que ele representa o horário real da entrega.<p>
19
+ <table border cellpadding="1" hspace="10">
20
+ <colgroup valign="top"><colgroup><colgroup>
21
+
22
+ <tr>
23
+ <td><font face="Tahoma" color="#CC0000" size="2"><b>Data</b></font></td>
24
+ <td><font face="Tahoma" color="#CC0000" size="2"><b>Local</b></font></td>
25
+ <td><font face="Tahoma" color="#CC0000" size="2"><b>Situação</b></font></td>
26
+ </tr>
27
+ <tr><td rowspan="1">19/04/2012 12:39</td><td>CEE LOREM - LOREM/LR</td><td><font color="5F9F9F">Entrega Efetuada</font></td></tr>
28
+ <tr><td rowspan="1">19/04/2012 09:45</td><td>CEE LOREM - LOREM/LR</td><td><font color="007FFF">Saiu para entrega</font></td></tr>
29
+ <tr><td rowspan="2">16/04/2012 15:29</td><td>CTE LOREM - LOREM/LR</td><td><font color="000000">Encaminhado</font></td></tr>
30
+ <tr><td colspan="2">Encaminhado para CEE LOREM - LOREM/LR</td></tr>
31
+ <tr><td rowspan="2">12/04/2012 11:39</td><td>ACF LOREM - LOREM/LR</td><td><font color="000000">Encaminhado</font></td></tr>
32
+ <tr><td colspan="2">Em trânsito para CTE LOREM - LOREM/LR</td></tr>
33
+ <tr><td rowspan="2">10/04/2012 18:17</td><td>ACF LOREM - LOREM/LP</td><td><font color="000000">Postagem - DH</font></td></tr>
34
+ <tr><td colspan="2">Postagem depois da hora </td></tr>
35
+ </colgroup></colgroup></colgroup></table>
36
+ <hr width="500" color="#FFCC33" size="1" align="left"><font face="Tahoma" size="2" color="black"><center><br><p><a href="http://www.correios.com.br/encomendas/servicos/sedex/contaSedex/default.cfm" target="_blank">Conta SEDEX</a> - saiba como contratar o SEDEX para sua empresa.<p>
37
+ <p><a href="http://www.correios.com.br/enderecador/default.cfm" target="_blank">Endereçador</a> - conheça o software gratuito dos Correios para geração de etiquetas.
38
+ <input type="hidden" name="Z_ACTION">
39
+ <input type="button" name="done" value="Nova Consulta">
40
+ <input type="button" name="Imprimir" value="Imprimir">
41
+ </p></p></p></center></font></p></font></form></div>
42
+
43
+ </body></html>
@@ -1,9 +1,9 @@
1
1
  # encoding: UTF-8
2
2
  require "test/unit"
3
3
  require "correios"
4
+ require "mocha/setup"
4
5
 
5
6
  class CorreiosTest < Test::Unit::TestCase
6
-
7
7
  def setup
8
8
  @obj = Correios.new(76410000, 74932180)
9
9
  end
@@ -14,8 +14,8 @@ class CorreiosTest < Test::Unit::TestCase
14
14
  assert xml.has_key? "cServico"
15
15
  first_service = xml["cServico"].first
16
16
  assert_equal ["41106"], first_service["Codigo"], "Codigo"
17
- assert_equal ["11,50"], first_service["Valor"], "Valor"
18
- assert_equal ["5"], first_service["PrazoEntrega"], "PrazoEntrega"
17
+ assert_equal ["12,50"], first_service["Valor"], "Valor"
18
+ assert_equal ["4"], first_service["PrazoEntrega"], "PrazoEntrega"
19
19
  assert_equal ["0,00"], first_service["ValorMaoPropria"], "ValorMaoPropria"
20
20
  assert_equal ["0,00"], first_service["ValorAvisoRecebimento"], "ValorAvisoRecebimento"
21
21
  assert_equal ["0,00"], first_service["ValorValorDeclarado"], "ValorValorDeclarado"
@@ -33,18 +33,19 @@ class CorreiosTest < Test::Unit::TestCase
33
33
 
34
34
  # first service
35
35
  assert_equal ["41106"], first_service["Codigo"], "Codigo"
36
- assert_equal ["11,50"], first_service["Valor"], "Valor"
37
- assert_equal ["5"], first_service["PrazoEntrega"], "PrazoEntrega"
36
+ assert_equal ["12,50"], first_service["Valor"], "Valor"
37
+ assert_equal ["4"], first_service["PrazoEntrega"], "PrazoEntrega"
38
38
  assert_equal ["0,00"], first_service["ValorMaoPropria"], "ValorMaoPropria"
39
39
  assert_equal ["0,00"], first_service["ValorAvisoRecebimento"], "ValorAvisoRecebimento"
40
40
  assert_equal ["0,00"], first_service["ValorValorDeclarado"], "ValorValorDeclarado"
41
41
  assert_equal ["N"], first_service["EntregaSabado"], "EntregaSabado"
42
42
  assert_equal ["S"], first_service["EntregaDomiciliar"], "EntregaDomiciliar"
43
43
  assert_equal ["0"], first_service["Erro"], "Erro"
44
+
44
45
  # second service
45
46
  assert_equal ["40010"], second_service["Codigo"], "Codigo"
46
- assert_equal ["14,70"], second_service["Valor"], "Valor"
47
- assert_equal ["3"], second_service["PrazoEntrega"], "PrazoEntrega"
47
+ assert_equal ["15,40"], second_service["Valor"], "Valor"
48
+ assert_equal ["1"], second_service["PrazoEntrega"], "PrazoEntrega"
48
49
  assert_equal ["0,00"], second_service["ValorMaoPropria"], "ValorMaoPropria"
49
50
  assert_equal ["0,00"], second_service["ValorAvisoRecebimento"], "ValorAvisoRecebimento"
50
51
  assert_equal ["0,00"], second_service["ValorValorDeclarado"], "ValorValorDeclarado"
@@ -52,13 +53,13 @@ class CorreiosTest < Test::Unit::TestCase
52
53
  assert_equal ["S"], second_service["EntregaDomiciliar"], "EntregaDomiciliar"
53
54
  assert_equal ["0"], second_service["Erro"], "Erro"
54
55
  end
55
-
56
+
56
57
  def test_integration
57
58
  correios = Correios.new(76410000, 74932180)
58
59
  frete = correios.calcular_frete(Correios::Servico::PAC, 0.4, 17, 16, 16)
59
60
  assert_equal :pac, frete.servico, "Servico"
60
- assert_equal 11.5, frete.valor, "Valor"
61
- assert_equal 5, frete.prazo, "Prazo"
61
+ assert_equal 12.5, frete.valor, "Valor"
62
+ assert_equal 4, frete.prazo, "Prazo"
62
63
  assert_equal 0, frete.erro, "Erro?"
63
64
  end
64
65
 
@@ -68,4 +69,35 @@ class CorreiosTest < Test::Unit::TestCase
68
69
  assert_equal -1, frete.erro, "Código de erro incorreto"
69
70
  assert_equal "Codigo de servico invalido.", frete.message, "Servico inválido"
70
71
  end
71
- end
72
+
73
+ def test_track_service_with_invalid_parameters
74
+ assert_raise ArgumentError do
75
+ Correios::Rastreamento.new ""
76
+ end
77
+
78
+ assert_raise ArgumentError do
79
+ Correios::Rastreamento.new
80
+ end
81
+ end
82
+
83
+ def test_parsing_tracking
84
+ fixture = File.open("test/fixture/rastreamento.html").read
85
+
86
+ rastreamento = Correios::Rastreamento.new "BR01"
87
+ rastreamento.stubs(:rastrear).returns Nokogiri::HTML(fixture)
88
+
89
+ result = rastreamento.buscar
90
+
91
+ assert_equal result.first[:descricao], "Entrega Efetuada"
92
+ assert_equal result.last[:descricao], "Postagem - DH"
93
+ end
94
+
95
+ def test_check_the_receipt_of_package
96
+ fixture = File.open("test/fixture/rastreamento.html").read
97
+
98
+ rastreamento = Correios::Rastreamento.new "BR01"
99
+ rastreamento.stubs(:rastrear).returns Nokogiri::HTML(fixture)
100
+
101
+ assert_equal rastreamento.chegou?, true
102
+ end
103
+ end
metadata CHANGED
@@ -1,40 +1,71 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: correios
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
4
5
  prerelease:
5
- version: 0.6.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Bruno Frank
9
- - kurko
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
-
14
- date: 2011-06-06 00:00:00 -03:00
15
- default_executable:
16
- dependencies:
17
- - !ruby/object:Gem::Dependency
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
18
15
  name: xml-simple
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
19
23
  prerelease: false
20
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
21
33
  none: false
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: "0"
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
26
38
  type: :runtime
27
- version_requirements: *id001
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
28
62
  description: Gem para calculo de valor e restreamento dos Correios.
29
- email:
63
+ email:
30
64
  - bfscordeiro@gmail.com
31
65
  executables: []
32
-
33
66
  extensions: []
34
-
35
67
  extra_rdoc_files: []
36
-
37
- files:
68
+ files:
38
69
  - .gitignore
39
70
  - Gemfile
40
71
  - README.rdoc
@@ -42,34 +73,30 @@ files:
42
73
  - correios.gemspec
43
74
  - lib/correios.rb
44
75
  - lib/correios/version.rb
76
+ - test/fixture/rastreamento.html
45
77
  - test/test_correios.rb
46
- has_rdoc: true
47
78
  homepage: https://github.com/brunofrank/correios
48
79
  licenses: []
49
-
50
80
  post_install_message:
51
81
  rdoc_options: []
52
-
53
- require_paths:
82
+ require_paths:
54
83
  - lib
55
- required_ruby_version: !ruby/object:Gem::Requirement
84
+ required_ruby_version: !ruby/object:Gem::Requirement
56
85
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: "0"
61
- required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
91
  none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- version: "0"
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
67
96
  requirements: []
68
-
69
97
  rubyforge_project: correios
70
- rubygems_version: 1.6.2
98
+ rubygems_version: 1.8.25
71
99
  signing_key:
72
100
  specification_version: 3
73
101
  summary: Calcula o valor do frete dos Correios.
74
- test_files:
75
- - test/test_correios.rb
102
+ test_files: []