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 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
+