shipping-calc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 0.0.1 / 2008-03-09
2
+
3
+ * Initial buggy release
4
+
5
+ * Don't try this at home!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/shipping_calc.rb
6
+ lib/shipping_calc/base.rb
7
+ lib/shipping_calc/dhl.rb
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
+