shipping-calc 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.
- data/History.txt +6 -0
- data/Manifest.txt +7 -0
- data/README.txt +64 -0
- data/Rakefile +10 -0
- data/lib/shipping_calc.rb +20 -0
- data/lib/shipping_calc/base.rb +13 -0
- data/lib/shipping_calc/dhl.rb +197 -0
- metadata +71 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
= ShippingCalc
|
2
|
+
|
3
|
+
* http://github.com/febuiles/shipping_calc/
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Shipping Calculator written in Ruby to get quick quotes from the major carriers (UPS, DHL, FedEX).
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
- Current version only supports DHL.
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
include ShippingCalc
|
16
|
+
|
17
|
+
opts = {
|
18
|
+
:api_user => "your_user",
|
19
|
+
:api_password => "your_pwd",
|
20
|
+
:shipping_key => "your_key",
|
21
|
+
:account_num => "your_accnt",
|
22
|
+
:date => "2008-03-10",
|
23
|
+
:service_code => "E", # check the docs to find out what this means
|
24
|
+
:shipment_code => "P", # check the docs to find out what this means
|
25
|
+
:weight => 34, # weight in lbs
|
26
|
+
:to_zip => 10001,
|
27
|
+
:to_state => "NY"
|
28
|
+
}
|
29
|
+
|
30
|
+
d = DHL.new
|
31
|
+
a = d.quote(opts)
|
32
|
+
p a
|
33
|
+
|
34
|
+
== REQUIREMENTS:
|
35
|
+
|
36
|
+
* You must obtain all the DHL ShipIt data (user, password, key and account) from http://www.dhl-usa.com/TechTools/detail/TTDetail.asp?nav=TechnologyTools/Shipping/OwnSoln
|
37
|
+
* REXML
|
38
|
+
|
39
|
+
== INSTALL:
|
40
|
+
|
41
|
+
* sudo gem install shipping_calc
|
42
|
+
|
43
|
+
== LICENSE:
|
44
|
+
|
45
|
+
Copyright (c) 2008 Federico Builes
|
46
|
+
|
47
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
48
|
+
a copy of this software and associated documentation files (the
|
49
|
+
'Software'), to deal in the Software without restriction, including
|
50
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
51
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
52
|
+
permit persons to whom the Software is furnished to do so, subject to
|
53
|
+
the following conditions:
|
54
|
+
|
55
|
+
The above copyright notice and this permission notice shall be
|
56
|
+
included in all copies or substantial portions of the Software.
|
57
|
+
|
58
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
59
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
60
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
61
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
62
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
63
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
64
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
require './lib/shipping_calc.rb'
|
4
|
+
|
5
|
+
Hoe.new('shipping-calc', ShippingCalc::VERSION) do |p|
|
6
|
+
p.rubyforge_name = "shipping-calc"
|
7
|
+
p.developer('Federico Builes', 'federico.builes@gmail.com')
|
8
|
+
p.remote_rdoc_dir = "" # publishes to root
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rexml/document'
|
5
|
+
require 'net/http'
|
6
|
+
require 'net/https'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
require 'shipping_calc/base'
|
10
|
+
require 'shipping_calc/dhl'
|
11
|
+
|
12
|
+
module ShippingCalc
|
13
|
+
class ShippingCalcError < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
VERSION = "0.0.1"
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ShippingCalc
|
2
|
+
|
3
|
+
class Base
|
4
|
+
US_STATES = ['AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC',
|
5
|
+
'DE', 'FL', 'GA', 'HI', 'IA', 'ID', 'IL', 'IN',
|
6
|
+
'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MI', 'MN',
|
7
|
+
'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ',
|
8
|
+
'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI',
|
9
|
+
'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VT', 'WA',
|
10
|
+
'WI', 'WV']
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'uri'
|
5
|
+
include REXML
|
6
|
+
|
7
|
+
module ShippingCalc
|
8
|
+
|
9
|
+
# Current version on their website is 1.0 and can be found in:
|
10
|
+
# https://eCommerce.airborne.com/ApiLandingTest.asp . To get full access to
|
11
|
+
# all their stuff you have to make sure they certify your application
|
12
|
+
# against their live platform tests. The test bed should be enough to get
|
13
|
+
# simple calculations.
|
14
|
+
# Currently, only shipments made inside the US are available.
|
15
|
+
class DHL < Base
|
16
|
+
|
17
|
+
|
18
|
+
# Obtains an estimate quote from the DHL site.
|
19
|
+
# <tt>params</tt> is a hash with all the settings for the shipment. They are:
|
20
|
+
#
|
21
|
+
# :*api_user*:: API access username, provided by DHL.
|
22
|
+
# :*api_password*:: API access password, provided by DHL.
|
23
|
+
# :*shipping_key*:: API shipping key, provided by DHL.
|
24
|
+
# :*account_num*:: Account number, provided by DHL.
|
25
|
+
# :*date*:: Date for the shipping in format YYYY-MM-DD (defaults to Time.now).
|
26
|
+
# :*service_code*:: Service code defined in Rate Estimate Specification(E, N, S, G). 1030 and SAT are not supported yet. Defaults to G (ground service).
|
27
|
+
# :*shipment_code*:: ShipmentType code defined in the Rate Estimate Specification. "P" for Package or "L" for Letter. Defaults to "P".
|
28
|
+
# :*weight*:: Order's weight. If the shipment code is a "L" (letter) then the weight will be 0.
|
29
|
+
# :*to_zip*:: Recipient's zip code.
|
30
|
+
# :*to_country*:: Recipient's country. Not used, currently DHL only supports US.
|
31
|
+
# :*to_state*:: Recipient's state.
|
32
|
+
|
33
|
+
def quote(params)
|
34
|
+
@xml = xml = Document.new
|
35
|
+
xml << XMLDecl.new("1.0' encoding='UTF-8")
|
36
|
+
|
37
|
+
auth(params[:api_user], params[:api_password])
|
38
|
+
rate_estimate(params)
|
39
|
+
request
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
# DHL gets the quotes in 2 steps, the first one is authentication. This
|
44
|
+
# generates the XML for that.
|
45
|
+
def auth(api_user, api_password)
|
46
|
+
ecomm = Element.new "eCommerce"
|
47
|
+
ecomm.attributes["action"] = "Request"
|
48
|
+
ecomm.attributes["version"] = "1.1"
|
49
|
+
|
50
|
+
user = Element.new "Requestor"
|
51
|
+
u_id = Element.new "ID"
|
52
|
+
u_id.text = api_user
|
53
|
+
|
54
|
+
u_pwd = Element.new "Password"
|
55
|
+
u_pwd.text = api_password
|
56
|
+
|
57
|
+
user << u_id
|
58
|
+
user << u_pwd
|
59
|
+
|
60
|
+
ecomm << user
|
61
|
+
@xml << ecomm
|
62
|
+
end
|
63
|
+
|
64
|
+
# After having the auth message ready, we create the RateEstimate request.
|
65
|
+
# shipping_key: API shipping key, provided by DHL.
|
66
|
+
# account_num: Account number, provided by DHL.
|
67
|
+
# date: Date for the shipping in format YYYY-MM-DD (defaults to
|
68
|
+
# Time.now).
|
69
|
+
# service_code: Service code defined in Rate Estimate Specification
|
70
|
+
# (E, N, S, G). 1030 and SAT are not supported yet. Defaults to G
|
71
|
+
# (ground service).
|
72
|
+
# shipment_code: ShipmentType code defined in the Rate Estimate
|
73
|
+
# Specification. "P" for Package or "L" for Letter. Defaults to "P".
|
74
|
+
# weight: Order's weight. If the shipment code is a "L" (letter) then
|
75
|
+
# the weight will be 0.
|
76
|
+
# to_zip: Recipient's zip code.
|
77
|
+
# to_country: Recipient's country. Not used, currently DHL only supports US.
|
78
|
+
# to_state: Recipient's state.
|
79
|
+
def rate_estimate(params)
|
80
|
+
shipment = Element.new "Shipment"
|
81
|
+
shipment.attributes["action"] = "RateEstimate"
|
82
|
+
shipment.attributes["version"] = "1.0"
|
83
|
+
|
84
|
+
credentials = Element.new "ShippingCredentials"
|
85
|
+
key = Element.new "ShippingKey"
|
86
|
+
key.text = params[:shipping_key]
|
87
|
+
|
88
|
+
account = Element.new "AccountNbr"
|
89
|
+
account.text = params[:account_num]
|
90
|
+
|
91
|
+
credentials << key
|
92
|
+
credentials << account
|
93
|
+
shipment << credentials
|
94
|
+
|
95
|
+
detail = Element.new "ShipmentDetail"
|
96
|
+
date = Element.new "ShipDate"
|
97
|
+
|
98
|
+
date.text = date(params[:date])
|
99
|
+
detail << date
|
100
|
+
|
101
|
+
# TODO: Implement SAT and 1030 services
|
102
|
+
service = Element.new "Service"
|
103
|
+
s_code = Element.new "Code"
|
104
|
+
s_code.text = service_code(params[:service_code])
|
105
|
+
detail << service << s_code
|
106
|
+
|
107
|
+
type = Element.new "ShipmentType"
|
108
|
+
t_code = Element.new "Code"
|
109
|
+
t_code.text = shipment_code(params[:shipment_code])
|
110
|
+
detail << type << t_code
|
111
|
+
|
112
|
+
weight = Element.new "Weight"
|
113
|
+
weight.text = weight(params[:weight])
|
114
|
+
shipment << detail << weight
|
115
|
+
|
116
|
+
billing = Element.new "Billing"
|
117
|
+
b_party = Element.new "Party"
|
118
|
+
p_code = Element.new "Code"
|
119
|
+
# Since we're just doing some quick calulations we don't want to be
|
120
|
+
# worrying about who's gonna send the package. Just make the calulations
|
121
|
+
# assuming the sender pays for the shipping.
|
122
|
+
p_code.text = "S"
|
123
|
+
shipment << billing << b_party << p_code
|
124
|
+
|
125
|
+
receiver = Element.new "Receiver"
|
126
|
+
r_addr = Element.new "Address"
|
127
|
+
r_state = Element.new "State"
|
128
|
+
r_country = Element.new "Country"
|
129
|
+
r_zipcode = Element.new "PostalCode"
|
130
|
+
|
131
|
+
r_state.text = state(params[:to_state])
|
132
|
+
r_country.text = "US"
|
133
|
+
r_zipcode.text = zip_code(params[:to_zip])
|
134
|
+
|
135
|
+
r_addr << r_state
|
136
|
+
r_addr << r_country
|
137
|
+
r_addr << r_zipcode
|
138
|
+
shipment << receiver << r_addr
|
139
|
+
|
140
|
+
root = @xml.elements["eCommerce"]
|
141
|
+
root.add shipment
|
142
|
+
end
|
143
|
+
|
144
|
+
# Sends the request to the web server and returns the response.
|
145
|
+
def request
|
146
|
+
server = Net::HTTP.new("eCommerce.airborne.com", 443)
|
147
|
+
path = path = "/ApiLandingTest.asp"
|
148
|
+
data = @xml.to_s
|
149
|
+
headers = { "Content-Type" => "text/xml"}
|
150
|
+
server.use_ssl = true
|
151
|
+
resp = server.post(path, data, headers)
|
152
|
+
price = parse_response(resp.body)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Parses the server's response. Currently, it only returns the estimate
|
156
|
+
# value of the shipping.
|
157
|
+
def parse_response(resp)
|
158
|
+
doc = Document.new(resp)
|
159
|
+
result = doc.elements["//Shipment/Result/Desc"].text
|
160
|
+
|
161
|
+
if result == "Shipment estimate successful."
|
162
|
+
doc.elements["//Shipment/EstimateDetail/RateEstimate/TotalChargeEstimate"].text.to_f
|
163
|
+
else
|
164
|
+
raise ShippingCalcError.new("Error calculating shipping costs: + #{result}")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def date(date)
|
169
|
+
date =~ /\d{4}-\d{2}-\d{2}/ ? date : Time.now.strftime("%Y-%m-%d")
|
170
|
+
end
|
171
|
+
|
172
|
+
def shipment_code(code)
|
173
|
+
["P", "L"].include?(code) ? code : "P"
|
174
|
+
end
|
175
|
+
|
176
|
+
def service_code(code)
|
177
|
+
["E", "N", "S", "G"].include?(code) ? code : "G"
|
178
|
+
end
|
179
|
+
|
180
|
+
def weight(w)
|
181
|
+
(w > 0 && w <= 150) ? w.to_s : (raise ShippingCalcError.new("Invalid weight - Must be between 1 and 150 lbs."))
|
182
|
+
end
|
183
|
+
|
184
|
+
def state(s)
|
185
|
+
valid_state?(s) ? s : (raise ShippingCalcError.new("Invalid state for recipient"))
|
186
|
+
end
|
187
|
+
|
188
|
+
def valid_state?(s)
|
189
|
+
US_STATES.include?(s)
|
190
|
+
end
|
191
|
+
|
192
|
+
def zip_code(code)
|
193
|
+
code.to_s =~ /\d{5}/ ? code.to_s : (raise ShippingCalcError.new("Invalid zip code for recipient"))
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shipping-calc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Federico Builes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-03-09 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.1
|
23
|
+
version:
|
24
|
+
description: Shipping Calculator written in Ruby to get quick quotes from the major carriers (UPS, DHL, FedEX).
|
25
|
+
email:
|
26
|
+
- federico.builes@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
files:
|
36
|
+
- History.txt
|
37
|
+
- Manifest.txt
|
38
|
+
- README.txt
|
39
|
+
- Rakefile
|
40
|
+
- lib/shipping_calc.rb
|
41
|
+
- lib/shipping_calc/base.rb
|
42
|
+
- lib/shipping_calc/dhl.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/febuiles/shipping_calc/
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --main
|
48
|
+
- README.txt
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: shipping-calc
|
66
|
+
rubygems_version: 1.0.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 2
|
69
|
+
summary: Shipping Calculator written in Ruby to get quick quotes from the major carriers (UPS, DHL, FedEX).
|
70
|
+
test_files: []
|
71
|
+
|