dhl-get_quote 0.4.25
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rvmrc.example +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +357 -0
- data/Rakefile +11 -0
- data/dhl-get_quote.gemspec +30 -0
- data/lib/dhl/get_quote/errors.rb +13 -0
- data/lib/dhl/get_quote/helper.rb +16 -0
- data/lib/dhl/get_quote/market_service.rb +42 -0
- data/lib/dhl/get_quote/piece.rb +59 -0
- data/lib/dhl/get_quote/request.rb +183 -0
- data/lib/dhl/get_quote/response.rb +94 -0
- data/lib/dhl/get_quote/version.rb +5 -0
- data/lib/dhl-get_quote.rb +96 -0
- data/spec/lib/dhl/dh-get_quote_spec.rb +177 -0
- data/spec/lib/dhl/get_quote/market_service_spec.rb +78 -0
- data/spec/lib/dhl/get_quote/piece_spec.rb +104 -0
- data/spec/lib/dhl/get_quote/request_spec.rb +482 -0
- data/spec/lib/dhl/get_quote/response_spec.rb +146 -0
- data/spec/spec_helper.rb +508 -0
- data/tpl/request.xml.erb +40 -0
- metadata +172 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc.example
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use ruby-1.9.3@dhl-get_quote
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Deseret Book
|
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,357 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/deseretbook/dhl-get_quote.png)](https://travis-ci.org/deseretbook/dhl-get_quote)
|
2
|
+
|
3
|
+
# Dhl::GetQuote
|
4
|
+
|
5
|
+
Get shipping quotes from DHL's XML-PI Service.
|
6
|
+
|
7
|
+
Use of the XML-PI Service requires you to have Site ID and Password from DHL. You can sign up here: https://myaccount.dhl.com/MyAccount/jsp/TermsAndConditionsIndex.htm
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'dhl-get_quote'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install dhl-get_quote
|
22
|
+
|
23
|
+
## Basic Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'dhl-get_quote'
|
27
|
+
|
28
|
+
r = Dhl::GetQuote::Request.new(
|
29
|
+
:site_id => "SiteIdHere",
|
30
|
+
:password => "p4ssw0rd",
|
31
|
+
:test_mode => true # changes the url being hit
|
32
|
+
)
|
33
|
+
|
34
|
+
r.kilograms!
|
35
|
+
r.centimeters!
|
36
|
+
|
37
|
+
r.add_special_service("DD")
|
38
|
+
|
39
|
+
r.to('CA', "T1H 0A1")
|
40
|
+
r.from('US', 84010)
|
41
|
+
|
42
|
+
r.pieces << Dhl::GetQuote::Piece.new(
|
43
|
+
:height => 20,
|
44
|
+
:weight => 20,
|
45
|
+
:width => 20,
|
46
|
+
:depth => 19
|
47
|
+
)
|
48
|
+
|
49
|
+
resp = r.post
|
50
|
+
if response.error?
|
51
|
+
raise "There was an error: #{resp.raw_xml}"
|
52
|
+
else
|
53
|
+
puts "Your cost to ship will be: #{resp.total_amount} in #{resp.currency_code}."
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
---
|
58
|
+
|
59
|
+
### Dhl::GetQuote::Request
|
60
|
+
|
61
|
+
#### Making a new request
|
62
|
+
|
63
|
+
This is where the magic starts. It accepts a hash that, at minimum, requires :site\_id and :password. Optionally, :test\_mode may be passed in to tell the gem to use the XML-PI test URL. The default is to *not* use test mode and to hit the production URL.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
request = Dhl::GetQuote::Request.new(
|
67
|
+
:site_id => "SiteIdHere",
|
68
|
+
:password => "p4ssw0rd",
|
69
|
+
:test_mode => false
|
70
|
+
)
|
71
|
+
```
|
72
|
+
|
73
|
+
*NOTE*: You can also set default beforehand in, for example, an initializer. For more information on this, please see the section "Initializers with Dhl::GetQuote"
|
74
|
+
|
75
|
+
#### Package Source and Destination
|
76
|
+
|
77
|
+
To set the source and destination, use the #to() and #from() methods:
|
78
|
+
|
79
|
+
#to(_country_code_, _postal_code_), #from(_country_code_, _postal_code_)
|
80
|
+
|
81
|
+
The country code must be the two-letter capitalized ISO country code. The postal code will be cast in to a string.
|
82
|
+
|
83
|
+
Example:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
request.from('US', 84111)
|
87
|
+
request.to('CA', 'T1H 0A1')
|
88
|
+
```
|
89
|
+
|
90
|
+
#### Measurement Units
|
91
|
+
|
92
|
+
DHL can accept weights and measures in both Metric and US Customary units. Weights are given in either pounds or kilograms, dimensions in either inches or centimeters. This gem defaults to use metric measurements.
|
93
|
+
|
94
|
+
To set to US Customary, use:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
request.inches! # set dimensions to inches
|
98
|
+
request.pounds! # set weight to pounds
|
99
|
+
```
|
100
|
+
|
101
|
+
To set back to Metric, use
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
request.centimeters! # set dimensions to centimeters
|
105
|
+
request.centimetres! # alternate spelling
|
106
|
+
|
107
|
+
request.kilograms! # set weight to kilograms
|
108
|
+
request.kilogrammes! # alternate spelling
|
109
|
+
```
|
110
|
+
|
111
|
+
To query what measurement system the object is currently using, use the following boolean calls:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
request.inches?
|
115
|
+
request.centimeters? # or request.centimetres?
|
116
|
+
|
117
|
+
request.pounds?
|
118
|
+
request.kilograms? # or request.kilogrammes?
|
119
|
+
```
|
120
|
+
|
121
|
+
You can also get the value directly:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
request.dimensions_unit # will return either "CM" or "IN"
|
125
|
+
request.weight_unit # will return either "KG" or "LB"
|
126
|
+
```
|
127
|
+
|
128
|
+
#### Setting Duty
|
129
|
+
|
130
|
+
You can toggle whether or not a shipment is dutiable with the #dutiable!() and #not_dutiable!() methods.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
request.dutiable!
|
134
|
+
request.not_dutiable!
|
135
|
+
```
|
136
|
+
|
137
|
+
You can absolutely set the dutiable stage with the #dutiable() method:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
request.dutiable(true)
|
141
|
+
request.dutiable(false)
|
142
|
+
```
|
143
|
+
|
144
|
+
You can query the current state with #dutiable?:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
request.dutiable? # returns true or false
|
148
|
+
```
|
149
|
+
|
150
|
+
The default is for the request is "not dutiable".
|
151
|
+
|
152
|
+
#### Shipment Services
|
153
|
+
|
154
|
+
Shipment services (speed, features, etc) can be added, listed and removed.
|
155
|
+
|
156
|
+
To add a special service, call #add_special_service as pass in DHL-standard code for the service:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
request.add_special_service("D")
|
160
|
+
```
|
161
|
+
|
162
|
+
To list all services currently added to a request, use #special_services:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
request.special_services
|
166
|
+
```
|
167
|
+
|
168
|
+
To remove a special service, use #remove_special_service and pass the code:
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
request.remove_special_service("D")
|
172
|
+
```
|
173
|
+
|
174
|
+
The interface will not allow the same special service code to be added twice, it will be silently ignored if you try.
|
175
|
+
|
176
|
+
|
177
|
+
#### Adding items to the request
|
178
|
+
|
179
|
+
To add items to the shipping quote request, generate a new Dhl::GetQuote::Piece instance and append it to #pieces:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# minimal
|
183
|
+
request.pieces << Dhl::GetQuote::Piece.new( :weight => 20 )
|
184
|
+
|
185
|
+
# more details
|
186
|
+
request.pieces << Dhl::GetQuote::Piece.new(
|
187
|
+
:weight => 20, :height => 20, :width => 20, :depth => 19
|
188
|
+
)
|
189
|
+
```
|
190
|
+
|
191
|
+
Dhl::GetQuote::Piece requires *at least* :weight to be specified, and it must be a nonzero integer. Optionally, you can provide :width, :depth and :height. The measurement options must all be added at once and cannot be added individually. They must be integers.
|
192
|
+
|
193
|
+
#### Posting to DHL
|
194
|
+
|
195
|
+
Once the request is prepared, call #post() to post the request to the DHL XML-PI. This will return a Dhl::GetQuote::Response object.
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
response = request.post
|
199
|
+
response.class == Dhl::GetQuote::Response # true
|
200
|
+
```
|
201
|
+
|
202
|
+
---
|
203
|
+
|
204
|
+
### Dhl::GetQuote::Response
|
205
|
+
|
206
|
+
Once a post is sent to DHL, this gem will interpret the XML returned and create a Dhl::GetQuote::Response object.
|
207
|
+
|
208
|
+
#### Checking for errors
|
209
|
+
|
210
|
+
To check for errors in the response (both local and upstream), query the #error? and #error methods
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
response.error? # true
|
214
|
+
response.error
|
215
|
+
# => < Dhl::GetQuote::Upstream::ValidationFailureError: your site id is not correct blah blah >
|
216
|
+
```
|
217
|
+
|
218
|
+
#### Getting costs
|
219
|
+
|
220
|
+
The response object exposes the following values:
|
221
|
+
|
222
|
+
* currency_code
|
223
|
+
* currency_role_type_code
|
224
|
+
* weight_charge
|
225
|
+
* total_amount
|
226
|
+
* total_tax_amount
|
227
|
+
* weight_charge_tax
|
228
|
+
|
229
|
+
To find the total change:
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
puts "Your cost to ship will be: #{response.total_amount} in #{response.currency_code}."
|
233
|
+
# Your cost to ship will be: 337.360 in USD.
|
234
|
+
```
|
235
|
+
|
236
|
+
DHL can return the cost in currency unit based on sender location or reciever location. It is unlikely this will be used much, but you can change the currency by calling #load_costs with the CurrencyRoleTypeCode:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
response.load_costs('PULCL')
|
240
|
+
puts "Your cost to ship will be: #{response.total_amount} in #{response.currency_code}."
|
241
|
+
# Your cost to ship will be: 341.360 in CAD.
|
242
|
+
```
|
243
|
+
|
244
|
+
CurrencyRoleTypeCodes that can be used are:
|
245
|
+
|
246
|
+
* BILLCU – Billing currency
|
247
|
+
* PULCL – Country of pickup local currency
|
248
|
+
* INVCU – Invoice currency
|
249
|
+
* BASEC – Base currency
|
250
|
+
|
251
|
+
#### Accessing the raw response
|
252
|
+
|
253
|
+
If you need data from the response that is not exposed by this gem, you can access both the raw xml and parsed xml directly:
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
response.raw_xml # raw xml string as returned by DHL
|
257
|
+
response.parsed_xml # xml parsed in to a Hash for easy traversal
|
258
|
+
```
|
259
|
+
|
260
|
+
\#parsed\_xml() is not always available in the case of errors. #raw\_xml() is, except in cases of network transport errors.
|
261
|
+
|
262
|
+
#### Accessing offered services
|
263
|
+
|
264
|
+
In cases where you have either sent many special service code, or you are evaluating all available services (via the 'OSINFO' special service code), you can obtain a list of all the services with the #offred_services() and #all_services() methods. Both methods return an array of Dhl::GetQuote::MarketService objects.
|
265
|
+
|
266
|
+
The #offered_services() method returns only those services intended to be shown to the end user an optional services (XCH) they can apply. These would be services with either 'TransInd' or 'MrkSrvInd' set to 'Y'.
|
267
|
+
|
268
|
+
The #all_services() methods returns all associated services, including everything in #offered_services and also including possible fees (FEE) and surcharges (SCH).
|
269
|
+
|
270
|
+
If using 'OSINFO' to obtain all offered services, you pass the value of #code() in to Request#add_special_service() to apply this services to another request:
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
# assume we already did an 'OSINFO' request.
|
274
|
+
new_request.add_special_service(response.offered_services.first.code)
|
275
|
+
```
|
276
|
+
|
277
|
+
---
|
278
|
+
|
279
|
+
### Dhl::GetQuote::MarketService
|
280
|
+
|
281
|
+
Instances of this object are returned from Response#offered_services() and Response#all_services().
|
282
|
+
|
283
|
+
#### Methods for parameters
|
284
|
+
|
285
|
+
All XML parameters in the response will be added as methods to this object. They may vary but generally include:
|
286
|
+
|
287
|
+
* #local\_product\_code() - code for user-offered services (signature, tracking, overnight, etc)
|
288
|
+
* #local\_service_type() code for non-offered special services (fees, surcharges, etc)
|
289
|
+
* #local\_service\_type\_name() - Name for a non-offered service
|
290
|
+
* #local\_product\_name() - Name for a user-offered service
|
291
|
+
* #mrk\_srv\_ind() - Should this be offered to the user?
|
292
|
+
* #trans\_ind() - Should this be shown to every user regardless of shipping options?
|
293
|
+
|
294
|
+
#### Getting the code for a service
|
295
|
+
|
296
|
+
The #code() method will return the code for a given service. It will work on both non-offered and user-offered services, it queries both LocalProductCode and LocalServiceType.
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
market_service.code # "D"
|
300
|
+
```
|
301
|
+
|
302
|
+
This code can be passed in to Request#add_special_service()
|
303
|
+
|
304
|
+
#### Getting the name for a service
|
305
|
+
|
306
|
+
The #name() method will return the name for a given service. It will work on both non-offered and user-offered services, it queries both LocalProductName and LocalServiceTypeName.
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
market_service.name # "EXPRESS WORLDWIDE DOC"
|
310
|
+
```
|
311
|
+
|
312
|
+
---
|
313
|
+
|
314
|
+
### Initializers with Dhl::GetQuote
|
315
|
+
|
316
|
+
If you don't want to have to pass email, password, weight setting, etc, every time you build a new request object you can set these defaults beforehand. This works well in cases where you want to put setting in something like a Rails initializer.
|
317
|
+
|
318
|
+
To do this, call Dhl::GetQuote::configure and pass a block:
|
319
|
+
|
320
|
+
```ruby
|
321
|
+
Dhl::GetQuote::configure do |c|
|
322
|
+
|
323
|
+
c.side_id "SomeSiteId"
|
324
|
+
c.password "p4ssw0rd"
|
325
|
+
|
326
|
+
c.production_mode! # or test_mode!
|
327
|
+
|
328
|
+
c.kilograms! # or kilogrammes!
|
329
|
+
c.centimeters! # or centimetres!
|
330
|
+
c.inches!
|
331
|
+
c.pounds!
|
332
|
+
|
333
|
+
c.dutiable! # or not_dutiable!
|
334
|
+
|
335
|
+
end
|
336
|
+
```
|
337
|
+
|
338
|
+
The above block sets defaults for use thereafter. You would then not have to pass site\_id or password in to Dhl::GetQuote::new():
|
339
|
+
|
340
|
+
```ruby
|
341
|
+
Dhl::GetQuote::configure do
|
342
|
+
side_id "SomeSiteId"
|
343
|
+
password "p4ssw0rd"
|
344
|
+
end
|
345
|
+
|
346
|
+
request = Dhl::GetQuote::new()
|
347
|
+
```
|
348
|
+
|
349
|
+
*Note*: options passed in to _Dhl::GetQuote::new()_ will override setting in the _Dhl::GetQuote::configure_ block.
|
350
|
+
## Contributing
|
351
|
+
|
352
|
+
1. Fork it
|
353
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
354
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
355
|
+
4. Add tests, make sure existing tests pass.
|
356
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
357
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dhl/get_quote/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "dhl-get_quote"
|
8
|
+
gem.version = Dhl::GetQuote::VERSION
|
9
|
+
gem.authors = ["Deseret Book", "Matthew Nielsen"]
|
10
|
+
gem.email = ["mnielsen@deseretbook.com"]
|
11
|
+
gem.description = %q{Get shipping quotes from DHL}
|
12
|
+
gem.summary = %q{Gem to interface with DHL's XML-PI shipping quote service.}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'httparty', '~>0.10.2'
|
21
|
+
gem.add_dependency 'multi_xml', '~>0.5.3'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rake', '~>10.0.4'
|
24
|
+
gem.add_development_dependency 'rake', '10.0.4'
|
25
|
+
gem.add_development_dependency 'rspec', '2.13.0'
|
26
|
+
gem.add_development_dependency 'rspec-must', '0.0.1'
|
27
|
+
# gem.add_development_dependency 'autotest'
|
28
|
+
# gem.add_development_dependency 'debugger'
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Dhl::GetQuote
|
2
|
+
class InputError < StandardError; end
|
3
|
+
class OptionsError < InputError; end
|
4
|
+
class FromNotSetError < InputError; end
|
5
|
+
class ToNotSetError < InputError; end
|
6
|
+
class CountryCodeError < InputError; end
|
7
|
+
class PieceError < InputError; end
|
8
|
+
|
9
|
+
class Upstream < StandardError
|
10
|
+
class UnknownError < Upstream; end
|
11
|
+
class ValidationFailureError < Upstream; end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dhl::GetQuote::Helper
|
2
|
+
def underscore(camel_cased_word)
|
3
|
+
self.class.underscore(camel_cased_word)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def underscore(camel_cased_word)
|
8
|
+
camel_cased_word.gsub(/([A-Z]{1})([A-Z]{1})/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Dhl::GetQuote::MarketService
|
2
|
+
include Dhl::GetQuote::Helper
|
3
|
+
|
4
|
+
def initialize(options)
|
5
|
+
@options = {}
|
6
|
+
if options.class.to_s == 'Hash'
|
7
|
+
build_from_hash(options)
|
8
|
+
else
|
9
|
+
build_from_xml(options.to_s)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def code
|
14
|
+
@local_service_type || @local_product_code
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
@local_service_type_name || @local_product_name
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def build_from_xml(xml_string)
|
24
|
+
@parsed_xml = MultiXml.parse(xml_string)
|
25
|
+
|
26
|
+
@parsed_xml['MrkSrv'].each do |k,v|
|
27
|
+
@options[k] = v
|
28
|
+
instance_variable_set("@#{underscore(k)}".to_sym, v)
|
29
|
+
self.class.class_eval { attr_reader underscore(k).to_sym }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_from_hash(options)
|
34
|
+
options.each do |k,v|
|
35
|
+
k = underscore(k) if k =~ /[A-Z]/
|
36
|
+
@options[k] = v
|
37
|
+
instance_variable_set("@#{k}".to_sym, v)
|
38
|
+
self.class.class_eval { attr_reader k.to_sym }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Dhl::GetQuote::Piece
|
2
|
+
attr_accessor :piece_id
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
[ :width, :height, :depth, :weight ].each do |i|
|
6
|
+
options[i] = options[i].to_i if !!options[i]
|
7
|
+
end
|
8
|
+
|
9
|
+
if options[:weight] && options[:weight] > 0
|
10
|
+
@weight = options[:weight]
|
11
|
+
else
|
12
|
+
raise Dhl::GetQuote::OptionsError, required_option_error_message(:weight)
|
13
|
+
end
|
14
|
+
|
15
|
+
if options[:width] || options[:height] || options[:depth]
|
16
|
+
[ :width, :height, :depth ].each do |req|
|
17
|
+
if options[req].to_i > 0
|
18
|
+
instance_variable_set("@#{req}", options[req].to_i)
|
19
|
+
else
|
20
|
+
raise Dhl::GetQuote::OptionsError, required_option_error_message(req)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@piece_id = options[:piece_id] || 1
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_h
|
30
|
+
h = {}
|
31
|
+
[ :width, :height, :depth, :weight ].each do |req|
|
32
|
+
if x = instance_variable_get("@#{req}")
|
33
|
+
h[req.to_s.capitalize] = x
|
34
|
+
end
|
35
|
+
end
|
36
|
+
h
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_xml
|
40
|
+
xml_str = <<eos
|
41
|
+
<Piece>
|
42
|
+
<PieceID>#{@piece_id}</PieceID>
|
43
|
+
eos
|
44
|
+
|
45
|
+
xml_str << " <Height>#{@height}</Height>\n" if @height
|
46
|
+
xml_str << " <Depth>#{@depth}</Depth>\n" if @depth
|
47
|
+
xml_str << " <Width>#{@width}</Width>\n" if @width
|
48
|
+
xml_str << " <Weight>#{@weight}</Weight>\n" if @weight
|
49
|
+
|
50
|
+
xml_str += "</Piece>\n"
|
51
|
+
xml_str
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def required_option_error_message(field)
|
57
|
+
":#{field} is a required for Dhl::GetQuote::Piece. Must be nonzero integer."
|
58
|
+
end
|
59
|
+
end
|