corraios 0.0.1
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 +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
|
+
[ ](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: []
|