corraios 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +134 -0
- data/Rakefile +14 -0
- data/corraios.gemspec +28 -0
- data/lib/corraios/calculator.rb +56 -0
- data/lib/corraios/containers/base.rb +82 -0
- data/lib/corraios/containers/envelope.rb +31 -0
- data/lib/corraios/containers/package.rb +50 -0
- data/lib/corraios/containers/roll.rb +40 -0
- data/lib/corraios/delivery.rb +45 -0
- data/lib/corraios/packer.rb +91 -0
- data/lib/corraios/services/pac.rb +14 -0
- data/lib/corraios/version.rb +3 -0
- data/lib/corraios.rb +30 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2dc25cea9a5e60dde42ce515603aec5bba1f5fb7
|
4
|
+
data.tar.gz: 9d93c867ec259333d5d903d00cb623e9dfd6fe2c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6c8da3d01efd11ccc24374cc9fbd177ed4b5f7aaaaafdf8b05f171876395316469c70886b8c71528fa217ee0cf642c234b94b7676e267423ea633c2305291971
|
7
|
+
data.tar.gz: bf379ef78277aaeae26d891430b78b58ed5ac898fe2f855b93a911749d5a9f44d24cb6b457c363a8e73017cb1cdbf773a09405bac5bd412bd7457905fc8f1a12
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Rodrigo Ra
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# Corraios
|
2
|
+
|
3
|
+
[ ![Codeship Status for imaboldcompany/corrails](https://codeship.com/projects/b77b8780-9531-0132-ffbf-466960a0e7d2/status?branch=master)](https://codeship.com/projects/62768)
|
4
|
+
|
5
|
+
gem que visa facilitar o cálculo do valor do frete cobrado pelo Correios para entregas
|
6
|
+
simples e para entregas com multiplos itens.
|
7
|
+
|
8
|
+
Essa gem é focada para aplicações de e-commerce. Assim, os únicos serviços suportados são
|
9
|
+
**PAC**, **SEDEX** e **E-SEDEX**.
|
10
|
+
|
11
|
+
##Motivação:
|
12
|
+
|
13
|
+
Existem outras gems para cálculo de frete, mas elas não incluem todas as regras de cubagem
|
14
|
+
que o Correios aplica.
|
15
|
+
|
16
|
+
##Regras utilizadas
|
17
|
+
|
18
|
+
### Para frete de 1 item:
|
19
|
+
|
20
|
+
Esse é o caso mais simples. A documentação do Correios explica bem quais são as restrições nesses casos: http://www.correios.com.br/para-voce/correios-de-a-a-z/pdf/calculador-remoto-de-precos-e-prazos/manual-de-implementacao-do-calculo-remoto-de-precos-e-prazos.
|
21
|
+
|
22
|
+
### Para frete de múltiplos itens com embalagens iguais:
|
23
|
+
|
24
|
+
Para o frete de múltiplos itens, sempre somaremos o peso dos itens. O que difere são os calculos das medidas finais de acordo com o tipo de embalagem:
|
25
|
+
|
26
|
+
- Envelopes
|
27
|
+
|
28
|
+
O tamanho do envelope não interfere no valor do frete, apenas o peso.
|
29
|
+
Sabendo disso, para unificar os itens e fazer apenas uma requisição ao webservice do Correios,
|
30
|
+
somamos os pesos dos envelopes, com limite de 1kg e desconsideramos os tamanhos dos envelopes.
|
31
|
+
|
32
|
+
Quando o peso dos itens superam 1kg, tratamos a entrega como um pacote. Por exemplo, o valor do
|
33
|
+
frete de 3 envelopes de 30x30 (centímetros) de 500g cada, será calculado como um pacote de 30x30x2
|
34
|
+
com 1,5kg.
|
35
|
+
|
36
|
+
- Caixas
|
37
|
+
|
38
|
+
Os volumes das caixas serão somados e um novo valor para os lados da caixa final são calculados. Por exemplo: 2 Caixa de 30x30x30 com 1kg cada, resulta em uma caixa de 2 kg com 37.7976315 centímetros para cada lado.
|
39
|
+
|
40
|
+
- Rolos
|
41
|
+
|
42
|
+
Para entrega de multiplos rolos, eles serão convertidos em pacotes. Um rolo com 30 centímetros de comprimero com 10 de diametro é convertido para uma pacote com 30x10x10 e o mesmo peso.
|
43
|
+
|
44
|
+
### Para frete de múltiplos itens com embalagens diferentes:
|
45
|
+
|
46
|
+
**TODO**
|
47
|
+
|
48
|
+
## Instalação
|
49
|
+
|
50
|
+
Add this line to your application's Gemfile:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'corrails'
|
54
|
+
```
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
$ bundle
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
$ gem install corrails
|
63
|
+
|
64
|
+
## Como usar?
|
65
|
+
|
66
|
+
São utilizadas 3 classes principais:
|
67
|
+
|
68
|
+
### Corraios::Packer
|
69
|
+
|
70
|
+
Classe utilizada para agrupar diferentes tipos de embalagens
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
packer = Corraios::Packer.new
|
74
|
+
packer.add_item weight: 0.3, height: 30, width: 50, length: 30 # pacote
|
75
|
+
packer.add_item weight: 1.3, width: 50, length: 30 # envelope
|
76
|
+
packer.add_item weight: 0.3, diameter: 20, length: 30 # rolo
|
77
|
+
|
78
|
+
```
|
79
|
+
|
80
|
+
|
81
|
+
### Corraios::Calculator
|
82
|
+
|
83
|
+
Essa classe recebe o cep de origem e destino juntamente com uma instância de `Corraios::Packer`.
|
84
|
+
|
85
|
+
O método `perform` deve receber quais serviços devem ser calculados.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
|
89
|
+
calculator = Corraios::Calculator.new '38408-090', '38320-000', packer
|
90
|
+
calculator.perform :pac #=> [Delivery]
|
91
|
+
calculator.perform :pac, :sedex #=> [Delivery, Delivery]
|
92
|
+
|
93
|
+
|
94
|
+
# quando possuir contrato
|
95
|
+
calculator.contract_number = '1321231123'
|
96
|
+
calculator.contract_password = '63h5nch13kd'
|
97
|
+
|
98
|
+
````
|
99
|
+
|
100
|
+
### Corraios::Delivery
|
101
|
+
|
102
|
+
Classe retornada pelo método `Corraios::Calculator#perform`, e possui os valores retornados pelo
|
103
|
+
webservices do Correios.
|
104
|
+
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
|
108
|
+
delivery = calculator.perform :pac #=> Delivery
|
109
|
+
|
110
|
+
if delivery.success?
|
111
|
+
delivery.deadline # 3
|
112
|
+
delivery.value # 32.12
|
113
|
+
delivery.number_of_posts # 1
|
114
|
+
else
|
115
|
+
delivery.error_message #
|
116
|
+
end
|
117
|
+
|
118
|
+
````
|
119
|
+
|
120
|
+
|
121
|
+
## TODO
|
122
|
+
|
123
|
+
- adicionar opção mão própria
|
124
|
+
- adicionar opção aviso recebimento
|
125
|
+
- adicionar opção valor declarado
|
126
|
+
|
127
|
+
|
128
|
+
## Contributing
|
129
|
+
|
130
|
+
1. Fork it ( https://github.com/[my-github-username]/corrails/fork )
|
131
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
132
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
133
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
134
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/corraios.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'corraios/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "corraios"
|
8
|
+
spec.version = Corraios::VERSION
|
9
|
+
spec.authors = ["Rodrigo Ra"]
|
10
|
+
spec.email = ["rodrigorcomp@gmail.com"]
|
11
|
+
spec.summary = %q{ Gem to calculate Correios' freight values for multiple items }
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = "https://github.com/imaboldcompany/corraios"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "httparty", "~>0.13.3"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "activesupport", "~> 4.2"
|
26
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.0'
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
class Calculator
|
4
|
+
include HTTParty
|
5
|
+
base_uri 'ws.correios.com.br'
|
6
|
+
|
7
|
+
attr_accessor :contract_number, :contract_password
|
8
|
+
|
9
|
+
def initialize(source, destination, packer)
|
10
|
+
@source = source
|
11
|
+
@destination = destination
|
12
|
+
@packer = packer
|
13
|
+
end
|
14
|
+
|
15
|
+
def perform(*services)
|
16
|
+
services.map do |service|
|
17
|
+
calculate_delivery(service)
|
18
|
+
end.flatten
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def calculate_delivery(service)
|
25
|
+
@packer.containers.map do |container|
|
26
|
+
query_string = "#{to_query_params(service)}&#{container.to_query_params}"
|
27
|
+
parse_delivery(calculate_container(query_string))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def calculate_container(query_string)
|
32
|
+
self.class.get("/calculador/CalcPrecoPrazo.aspx?#{query_string}")
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_delivery(response)
|
36
|
+
if response.code == 200
|
37
|
+
Delivery.new(response.parsed_response)
|
38
|
+
else
|
39
|
+
raise ServiceUnreachable
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_query_params(service)
|
44
|
+
query_string = "#{default_query_params}&sCepOrigem=#{@source}&sCepDestino=#{@destination}"
|
45
|
+
query_string << "&nCdServico=#{Corraios::code_for(service)}"
|
46
|
+
query_string << "&nCdEmpresa=#{contract_number}" if contract_number
|
47
|
+
query_string << "&sDsSenha=#{contract_password}" if contract_password
|
48
|
+
query_string
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_query_params
|
52
|
+
"sCdMaoPropria=N&nVlValorDeclarado=0&sCdAvisoRecebimento=N&nIndicaCalculo=3&StrRetorno=XML"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
module Containers
|
4
|
+
|
5
|
+
class Base
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
attributes.each do |attr, value|
|
9
|
+
send "#{attr}=", value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_a?(type)
|
14
|
+
self.class.name.split('::').last.underscore.to_sym == type
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_package
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_query_params
|
22
|
+
attributes_names.map do |attr|
|
23
|
+
"#{self.class.query_attribute_name(attr)}=#{send(attr)}"
|
24
|
+
end.join('&') + "&nCdFormato=#{format}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def format
|
28
|
+
self.class.instance_variable_get('@format')
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes_names
|
32
|
+
self.class.instance_variable_get('@attributes_restrictions').keys
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
|
37
|
+
def add_attribute name, restrictions, query_attribute_name = nil
|
38
|
+
attributes_restrictions[name] = restrictions
|
39
|
+
query_attribute_names[name] = query_attribute_name
|
40
|
+
attr_accessor name
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_format(format)
|
44
|
+
@format = format
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_field?(attribute, value)
|
48
|
+
attributes_restrictions[attribute] && attributes_restrictions[attribute].include?(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def attributes_restrictions
|
52
|
+
@attributes_restrictions ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
def query_attribute_names
|
56
|
+
@query_attribute_names ||= {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def valid_fields?(attributes)
|
60
|
+
attributes.keys.size == attributes_restrictions.keys.size &&
|
61
|
+
attributes.all? { |attribute, value| valid_field?(attribute, value) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def floor_for(attribute, value)
|
65
|
+
minimum_value = minimum_value_for(attribute)
|
66
|
+
|
67
|
+
minimum_value < value ? value : minimum_value
|
68
|
+
end
|
69
|
+
|
70
|
+
def minimum_value_for(attribute)
|
71
|
+
attributes_restrictions[attribute].first
|
72
|
+
end
|
73
|
+
|
74
|
+
def query_attribute_name(attribute_name)
|
75
|
+
query_attribute_names[attribute_name]
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
module Containers
|
4
|
+
|
5
|
+
class Envelope < Base
|
6
|
+
set_format 3
|
7
|
+
add_attribute :weight, 0.0..1, 'nVlPeso'
|
8
|
+
add_attribute :width, 11..60, 'nVlLargura'
|
9
|
+
add_attribute :length, 16..60, 'nVlComprimento'
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
self.class.valid_fields? @attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def can_merge?(envelope)
|
16
|
+
new_weight = self.weight + envelope.weight
|
17
|
+
|
18
|
+
self.class.valid_field? :weight, new_weight
|
19
|
+
end
|
20
|
+
|
21
|
+
def merge!(other)
|
22
|
+
self.weight += other.weight
|
23
|
+
#TODO: usar maiores
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_package
|
27
|
+
Package.new weight: self.weight, height: 2, width: self.width, length: self.length
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
module Containers
|
4
|
+
|
5
|
+
class Package < Base
|
6
|
+
set_format 1
|
7
|
+
add_attribute :weight, 0.0..30, 'nVlPeso'
|
8
|
+
add_attribute :width, 11..105, 'nVlLargura'
|
9
|
+
add_attribute :length, 16..105, 'nVlComprimento'
|
10
|
+
add_attribute :height, 2..105, 'nVlAltura'
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
self.class.valid_fields? @attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
def can_merge?(other)
|
17
|
+
new_volume = self.volume + other.volume
|
18
|
+
new_sides_size = (new_volume ** (1.0/3))
|
19
|
+
|
20
|
+
attributes = { weight: self.weight + other.weight }
|
21
|
+
[:width, :length, :height].each do |attr|
|
22
|
+
attributes[attr] = self.class.floor_for attr, new_sides_size
|
23
|
+
end
|
24
|
+
|
25
|
+
self.class.valid_fields? attributes
|
26
|
+
end
|
27
|
+
|
28
|
+
def merge!(other)
|
29
|
+
self.weight += other.weight
|
30
|
+
self.width = self.length = self.height = ((self.volume + other.volume) ** (1.0/3))
|
31
|
+
end
|
32
|
+
|
33
|
+
def volume
|
34
|
+
width * length * height
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_package
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
class << self
|
42
|
+
|
43
|
+
def valid_fields?(attributes)
|
44
|
+
super(attributes) &&
|
45
|
+
(attributes[:width] + attributes[:height] + attributes[:length]) <= 200.0
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
module Containers
|
4
|
+
|
5
|
+
class Roll < Base
|
6
|
+
set_format 2
|
7
|
+
add_attribute :weight, 0..30, 'nVlPeso'
|
8
|
+
add_attribute :length, 18..105, 'nVlComprimento'
|
9
|
+
add_attribute :diameter, 5..91, 'nVlDiametro'
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
self.class.valid_fields? @attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def can_merge?(other)
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def merge!(other)
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
def volume
|
24
|
+
3.1415 * (diameter/2)**2 * length
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_package
|
28
|
+
Package.new weight: self.weight, length: self.length, width: self.diameter, height: self.diameter
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
|
33
|
+
def valid_fields?(attributes)
|
34
|
+
super(attributes) &&
|
35
|
+
(attributes[:diameter] * 2 + attributes[:length]) <= 200.0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
class Delivery
|
4
|
+
attr_reader :value, :deadline, :error_message
|
5
|
+
|
6
|
+
attr_reader :amount_of_posts
|
7
|
+
|
8
|
+
def initialize(correios_response)
|
9
|
+
@amount_of_posts = 1
|
10
|
+
parse_response(correios_response)
|
11
|
+
end
|
12
|
+
|
13
|
+
def error?
|
14
|
+
!!@error_message
|
15
|
+
end
|
16
|
+
|
17
|
+
def success?
|
18
|
+
!error?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def parse_response(response)
|
23
|
+
service = validate_response(response)
|
24
|
+
value = to_float(service['Valor'])
|
25
|
+
if value > 0.0
|
26
|
+
@value = value
|
27
|
+
@deadline = service['PrazoEntrega'].to_i
|
28
|
+
else
|
29
|
+
@error_message = service['MsgErro'].strip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_float(string)
|
34
|
+
string.to_s.gsub(',', '.').to_f
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_response(response)
|
38
|
+
if response['Servicos'] && response['Servicos']['cServico']
|
39
|
+
response['Servicos']['cServico']
|
40
|
+
else
|
41
|
+
raise InvalidResponse
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Corraios
|
2
|
+
|
3
|
+
class Packer
|
4
|
+
|
5
|
+
attr_reader :containers
|
6
|
+
|
7
|
+
def initialize()
|
8
|
+
@containers = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_item(attributes)
|
12
|
+
container = build_container(attributes)
|
13
|
+
add_to_containers container
|
14
|
+
end
|
15
|
+
|
16
|
+
def total_weight
|
17
|
+
@containers.inject(0) { |sum, item| sum + item.weight }.round(3)
|
18
|
+
end
|
19
|
+
|
20
|
+
def amount_of_posts
|
21
|
+
@containers.size
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def build_container(attributes)
|
26
|
+
container = infers_container(attributes)
|
27
|
+
raise UnknownMeasures unless container
|
28
|
+
container.new(attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_to_containers(container)
|
32
|
+
if @containers.empty?
|
33
|
+
@containers << container
|
34
|
+
else
|
35
|
+
if container.is_a? :package
|
36
|
+
add_package(container.to_package)
|
37
|
+
else
|
38
|
+
add_envelope_or_roll container
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def first_empty
|
44
|
+
@containers.last
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_envelope_or_roll(envelope)
|
48
|
+
unless using_envelope? && try_merge(first_empty, envelope)
|
49
|
+
convert_containers_into_package
|
50
|
+
add_package(envelope.to_package)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def convert_containers_into_package
|
55
|
+
@containers = @containers.map &:to_package
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_package(package)
|
59
|
+
unless try_merge(first_empty, package)
|
60
|
+
@containers << package
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def try_merge(container, new_container)
|
65
|
+
if container.can_merge? new_container
|
66
|
+
container.merge! new_container
|
67
|
+
true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def using_package?
|
72
|
+
@containers.any? { |container| container.is_a? :package }
|
73
|
+
end
|
74
|
+
|
75
|
+
def using_envelope?
|
76
|
+
@containers.size == 1 && @containers[0].is_a?(:envelope)
|
77
|
+
end
|
78
|
+
|
79
|
+
def pack_all_into_one_package(container)
|
80
|
+
weight_sum = total_weight + container.weight
|
81
|
+
measures = { height: 2, length: container.length, width: container.width }
|
82
|
+
@containers = [ Containers::Package.new(measures.merge(weight: weight_sum)) ]
|
83
|
+
end
|
84
|
+
|
85
|
+
def infers_container(attributes)
|
86
|
+
[Containers::Package, Containers::Envelope, Containers::Roll].find do |clazz|
|
87
|
+
clazz.valid_fields?(attributes)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/corraios.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
|
4
|
+
module Corraios
|
5
|
+
SERVICES = {
|
6
|
+
pac: 41106,
|
7
|
+
sedex: 40010,
|
8
|
+
e_sedex: 81019
|
9
|
+
}
|
10
|
+
|
11
|
+
def self.code_for(service)
|
12
|
+
SERVICES[service]
|
13
|
+
end
|
14
|
+
|
15
|
+
class CorraiosError < StandardError; end
|
16
|
+
class InvalidMeasures < CorraiosError; end
|
17
|
+
class UnknownMeasures < CorraiosError; end
|
18
|
+
class ServiceUnreachable < CorraiosError; end
|
19
|
+
class InvalidResponse < CorraiosError; end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
require 'corraios/containers/base'
|
24
|
+
require 'corraios/containers/envelope'
|
25
|
+
require 'corraios/containers/package'
|
26
|
+
require 'corraios/containers/roll'
|
27
|
+
require 'corraios/calculator'
|
28
|
+
require 'corraios/delivery'
|
29
|
+
require 'corraios/packer'
|
30
|
+
require 'corraios/version'
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: corraios
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rodrigo Ra
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.13.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.13.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-reporters
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
description: ''
|
84
|
+
email:
|
85
|
+
- rodrigorcomp@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- corraios.gemspec
|
96
|
+
- lib/corraios.rb
|
97
|
+
- lib/corraios/calculator.rb
|
98
|
+
- lib/corraios/containers/base.rb
|
99
|
+
- lib/corraios/containers/envelope.rb
|
100
|
+
- lib/corraios/containers/package.rb
|
101
|
+
- lib/corraios/containers/roll.rb
|
102
|
+
- lib/corraios/delivery.rb
|
103
|
+
- lib/corraios/packer.rb
|
104
|
+
- lib/corraios/services/pac.rb
|
105
|
+
- lib/corraios/version.rb
|
106
|
+
homepage: https://github.com/imaboldcompany/corraios
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.4.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Gem to calculate Correios' freight values for multiple items
|
130
|
+
test_files: []
|