fedex 3.6.1 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +155 -2
- data/fedex.gemspec +4 -4
- data/lib/fedex/ground_manifest.rb +25 -0
- data/lib/fedex/label.rb +21 -6
- data/lib/fedex/rate.rb +3 -2
- data/lib/fedex/request/base.rb +41 -5
- data/lib/fedex/request/delete.rb +62 -0
- data/lib/fedex/request/ground_close.rb +73 -0
- data/lib/fedex/request/pickup.rb +121 -0
- data/lib/fedex/request/pickup_availability.rb +89 -0
- data/lib/fedex/request/rate.rb +7 -0
- data/lib/fedex/request/service_availability.rb +86 -0
- data/lib/fedex/request/shipment.rb +31 -7
- data/lib/fedex/request/tracking_information.rb +11 -2
- data/lib/fedex/shipment.rb +47 -5
- data/lib/fedex/tracking_information.rb +2 -1
- data/lib/fedex/tracking_information/event.rb +5 -2
- data/lib/fedex/version.rb +3 -1
- data/spec/lib/fedex/address_spec.rb +4 -4
- data/spec/lib/fedex/delete_spec.rb +26 -0
- data/spec/lib/fedex/document_spec.rb +9 -9
- data/spec/lib/fedex/ground_close_spec.rb +42 -0
- data/spec/lib/fedex/label_spec.rb +4 -4
- data/spec/lib/fedex/pickup_availability_spec.rb +19 -0
- data/spec/lib/fedex/pickup_spec.rb +32 -0
- data/spec/lib/fedex/rate_spec.rb +14 -10
- data/spec/lib/fedex/service_availability_spec.rb +20 -0
- data/spec/lib/fedex/shipment_spec.rb +7 -2
- data/spec/lib/fedex/track_spec.rb +21 -6
- data/spec/spec_helper.rb +3 -0
- data/spec/support/vcr.rb +0 -1
- metadata +46 -19
data/Readme.md
CHANGED
@@ -70,6 +70,21 @@ shipping_options = {
|
|
70
70
|
}
|
71
71
|
```
|
72
72
|
|
73
|
+
If you pass a non-nil `:return_reason` as part of the shipping options, you will create
|
74
|
+
a return shipment. The request to fedex will include the following additional XML.
|
75
|
+
|
76
|
+
```xml
|
77
|
+
<SpecialServicesRequested>
|
78
|
+
<SpecialServiceTypes>RETURN_SHIPMENT</SpecialServiceTypes>
|
79
|
+
<ReturnShipmentDetail>
|
80
|
+
<ReturnType>PRINT_RETURN_LABEL</ReturnType>
|
81
|
+
<Rma>
|
82
|
+
<Reason>YOUR RETURN REASON HERE</Reason>
|
83
|
+
</Rma>
|
84
|
+
</ReturnShipmentDetail>
|
85
|
+
</SpecialServicesRequested>
|
86
|
+
```
|
87
|
+
|
73
88
|
By default the shipping charges will be assigned to the sender. If you may
|
74
89
|
change this by passing an extra hash of payment options.
|
75
90
|
|
@@ -131,7 +146,7 @@ ship = fedex.ship(:shipper=>shipper,
|
|
131
146
|
:packages => packages,
|
132
147
|
:service_type => "FEDEX_GROUND",
|
133
148
|
:shipping_options => shipping_options)
|
134
|
-
puts ship[:completed_shipment_detail][:operational_detail]
|
149
|
+
puts ship[:completed_shipment_detail][:operational_detail][:transit_time]
|
135
150
|
```
|
136
151
|
Above code will give you the transit time.
|
137
152
|
|
@@ -189,6 +204,97 @@ shipment.save!
|
|
189
204
|
|
190
205
|
Documentation for setting up Paperclip with Amazon S3 can be found in the Paperclip [README](https://github.com/thoughtbot/paperclip/#storage).
|
191
206
|
|
207
|
+
### ** Generate shipping labels for multi-package shipments (MPS) **
|
208
|
+
|
209
|
+
Multiple packages for a single pick-up, destination and payer can be combined into a single MPS shipment. The first label will provide a master tracking number which must be used in the subsequent calls for the remaining packages in the shipment.
|
210
|
+
|
211
|
+
Parameters for the first label:
|
212
|
+
```ruby
|
213
|
+
label = fedex.label(
|
214
|
+
:filename => file_name,
|
215
|
+
:shipper => shipper,
|
216
|
+
:recipient => recipient,
|
217
|
+
:packages => packages,
|
218
|
+
:service_type => service_type,
|
219
|
+
:shipping_details => shipping_details,
|
220
|
+
:shipping_charges_payment => shipping_charges_payment,
|
221
|
+
:customs_clearance_detail => customs_clearance_detail,
|
222
|
+
:mps => {:package_count => package_count, :total_weight => total_weight, :sequence_number => '1'}
|
223
|
+
)
|
224
|
+
```
|
225
|
+
|
226
|
+
Parameters for labels 2 through 'n':
|
227
|
+
```ruby
|
228
|
+
fedex.label(
|
229
|
+
:filename => file_name,
|
230
|
+
:shipper => shipper,
|
231
|
+
:recipient => recipient,
|
232
|
+
:packages => packages,
|
233
|
+
:service_type => service_type,
|
234
|
+
:shipping_details => shipping_details,
|
235
|
+
:shipping_charges_payment => shipping_charges_payment,
|
236
|
+
:customs_clearance_detail => customs_clearance_detail,
|
237
|
+
:mps => {
|
238
|
+
:master_tracking_id => {:tracking_id_type => 'FEDEX', :tracking_number =>tracking_number},
|
239
|
+
:package_count => package_count,
|
240
|
+
:total_weight => {
|
241
|
+
:value => total_weight,
|
242
|
+
:units => 'KG'
|
243
|
+
}
|
244
|
+
:sequence_number => 'n'
|
245
|
+
}
|
246
|
+
)
|
247
|
+
```
|
248
|
+
|
249
|
+
### ** Create COD Shipment **
|
250
|
+
|
251
|
+
To create a Cash On Delivery label for a shipment:
|
252
|
+
|
253
|
+
change "commerical_invoice = {:purpose => 'SOLD'}" in customs_clearance_detail
|
254
|
+
|
255
|
+
add shipping_options with {:cod => {:currency => "currency", :amount => "amount", :collection_type => 'PAYMENT COLLECTION TYPE'}
|
256
|
+
|
257
|
+
PAYMENT COLLECTION TYPE - CASH, CHEQUE, DEMAND DRAFT
|
258
|
+
|
259
|
+
### ** To add multiple commodities in customs_clearance_detail
|
260
|
+
|
261
|
+
use this format commodities_1 .... commodities_N
|
262
|
+
|
263
|
+
example
|
264
|
+
|
265
|
+
```
|
266
|
+
|
267
|
+
customs_clearance_detail['commodites_1']
|
268
|
+
customs_clearance_detail['commodites_2']
|
269
|
+
|
270
|
+
```
|
271
|
+
|
272
|
+
### ** Masking shipper details in label **
|
273
|
+
|
274
|
+
this allows you hide shipper details on the label
|
275
|
+
|
276
|
+
Add customer_specified_detail = {:masked_data_1 => 'SOMETHING', :masked_data_2 => 'SOMETHING'} in :label_specification key
|
277
|
+
|
278
|
+
Example
|
279
|
+
|
280
|
+
```
|
281
|
+
customer_specified_detail = {
|
282
|
+
:masked_data_1 => "SHIPPER_ACCOUNT_NUMBER",
|
283
|
+
:masked_data_2 => "TRANSPORTATION_CHARGES_PAYOR_ACCOUNT_NUMBER",
|
284
|
+
:masked_data_3 => "DUTIES_AND_TAXES_PAYOR_ACCOUNT_NUMBER"
|
285
|
+
}
|
286
|
+
|
287
|
+
```
|
288
|
+
|
289
|
+
### ** Delete a shipment **
|
290
|
+
|
291
|
+
If you do not intend to use a label you should delete it. This will notify FedEx that you will not be using the label and they won't charge you.
|
292
|
+
|
293
|
+
To delete a shipment:
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
fedex.delete(:tracking_number => "1234567890123")
|
297
|
+
```
|
192
298
|
|
193
299
|
### ** Tracking a shipment **
|
194
300
|
|
@@ -219,7 +325,7 @@ To verify an address is valid and deliverable:
|
|
219
325
|
```ruby
|
220
326
|
|
221
327
|
address = {
|
222
|
-
:
|
328
|
+
:street => "5 Elm Street",
|
223
329
|
:city => "Norwalk",
|
224
330
|
:state => "CT",
|
225
331
|
:postal_code => "06850",
|
@@ -238,12 +344,58 @@ address_result.postal_code
|
|
238
344
|
# => "06850-3901"
|
239
345
|
```
|
240
346
|
|
347
|
+
### ** Requesting a Pickup **
|
348
|
+
|
349
|
+
To request a pickup:
|
350
|
+
|
351
|
+
```ruby
|
352
|
+
|
353
|
+
pickup = fedex.pickup(:carrier_code => 'FDXE',
|
354
|
+
:packages => {:weight => {:units => "LB", :value => 10}, :count => 2},
|
355
|
+
:ready_timestamp => Date.today.to_datetime + 1.375,
|
356
|
+
:close_time => Date.today.to_time + 60 * 60 * 17)
|
357
|
+
puts pickup[:pickup_confirmation_number]
|
358
|
+
```
|
359
|
+
|
360
|
+
### ** Getting pickup availability details **
|
361
|
+
|
362
|
+
To check for pickup availability:
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
|
366
|
+
dispatch = Date.tomorrow.strftime('%Y-%m-%d')
|
367
|
+
|
368
|
+
pickup_availability = fedex.pickup_availability(:country_code => 'IN',
|
369
|
+
:postal_code => '400061',
|
370
|
+
:request_type => 'FUTURE_DAY',
|
371
|
+
:dispatch_date => dispatch_date,
|
372
|
+
:carrier_code => 'FDXE')
|
373
|
+
|
374
|
+
puts pickup_availability[:options]
|
375
|
+
```
|
376
|
+
|
377
|
+
### ** Getting service availability **
|
378
|
+
|
379
|
+
To check service availability:
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
|
383
|
+
origin = {:postal_code => '400012', :country_code => 'IN'}
|
384
|
+
destination = { :postal_code => '400020', :country_code => 'IN'}
|
385
|
+
fedex_service_hash = {:origin => origin, :destination => destination, :ship_date => '2014-06-28', :carrier_code => 'FDXE'}
|
386
|
+
|
387
|
+
service = fedex.service_availability(fedex_service_hash)
|
388
|
+
|
389
|
+
puts service[:options]
|
390
|
+
```
|
391
|
+
|
241
392
|
# Services/Options Available
|
242
393
|
|
243
394
|
```ruby
|
244
395
|
Fedex::Shipment::SERVICE_TYPES
|
245
396
|
Fedex::Shipment::PACKAGING_TYPES
|
246
397
|
Fedex::Shipment::DROP_OFF_TYPES
|
398
|
+
Fedex::Shipment::CARRIER_CODES
|
247
399
|
````
|
248
400
|
|
249
401
|
# Contributors:
|
@@ -259,6 +411,7 @@ Fedex::Shipment::DROP_OFF_TYPES
|
|
259
411
|
- [yevgenko] (https://github.com/yevgenko) (Yevgeniy Viktorov)
|
260
412
|
- [smartacus] (https://github.com/smartacus) (Michael Lippold)
|
261
413
|
- [jonathandean] (https://github.com/jonathandean) (Jonathan Dean)
|
414
|
+
- [chirag7jain] (https://github.com/chirag7jain) (Chirag Jain)
|
262
415
|
- and more... (https://github.com/jazminschroeder/fedex/graphs/contributors)
|
263
416
|
|
264
417
|
# Copyright/License:
|
data/fedex.gemspec
CHANGED
@@ -16,14 +16,14 @@ Gem::Specification.new do |s|
|
|
16
16
|
|
17
17
|
s.license = 'MIT'
|
18
18
|
|
19
|
-
s.add_dependency 'httparty', '
|
20
|
-
s.add_dependency 'nokogiri', '
|
19
|
+
s.add_dependency 'httparty', '>= 0.8.3'
|
20
|
+
s.add_dependency 'nokogiri', '>= 1.5.6'
|
21
21
|
|
22
|
-
s.add_development_dependency "rspec", '~>
|
22
|
+
s.add_development_dependency "rspec", '~> 3.0.0'
|
23
23
|
s.add_development_dependency 'vcr', '~> 2.0.0'
|
24
24
|
s.add_development_dependency 'webmock', '~> 1.8.0'
|
25
25
|
s.add_development_dependency 'pry'
|
26
|
-
|
26
|
+
s.add_development_dependency 'rake'
|
27
27
|
|
28
28
|
s.files = `git ls-files`.split("\n")
|
29
29
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Fedex
|
5
|
+
class GroundManifest
|
6
|
+
attr_reader :manifest_data, :filename
|
7
|
+
|
8
|
+
# Initialize Fedex::GroundManifest Object
|
9
|
+
# @param [Hash] options
|
10
|
+
def initialize(options = {})
|
11
|
+
puts options
|
12
|
+
@filename = options[:filename]
|
13
|
+
@manifest_data = Base64.decode64(options[:manifest][:file])
|
14
|
+
save
|
15
|
+
end
|
16
|
+
|
17
|
+
def save
|
18
|
+
return if manifest_data.nil? || filename.nil?
|
19
|
+
full_path = Pathname.new(filename)
|
20
|
+
File.open(full_path, 'wb') do |f|
|
21
|
+
f.write(manifest_data)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/fedex/label.rb
CHANGED
@@ -7,14 +7,19 @@ module Fedex
|
|
7
7
|
|
8
8
|
# Initialize Fedex::Label Object
|
9
9
|
# @param [Hash] options
|
10
|
-
def initialize(label_details = {})
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def initialize(label_details = {}, associated_shipments = false)
|
11
|
+
if associated_shipments
|
12
|
+
package_details = label_details
|
13
|
+
@options = package_details[:label]
|
14
|
+
@options[:tracking_number] = package_details[:tracking_id]
|
15
|
+
else
|
16
|
+
@response_details = label_details[:process_shipment_reply]
|
17
|
+
package_details = label_details[:process_shipment_reply][:completed_shipment_detail][:completed_package_details]
|
18
|
+
@options = package_details[:label]
|
19
|
+
@options[:tracking_number] = package_details[:tracking_ids][:tracking_number]
|
20
|
+
end
|
14
21
|
@options[:format] = label_details[:format]
|
15
|
-
@options[:tracking_number] = package_details[:tracking_ids][:tracking_number]
|
16
22
|
@options[:file_name] = label_details[:file_name]
|
17
|
-
|
18
23
|
@image = Base64.decode64(options[:parts][:image]) if has_image?
|
19
24
|
|
20
25
|
if file_name = @options[:file_name]
|
@@ -52,5 +57,15 @@ module Fedex
|
|
52
57
|
f.write(@image)
|
53
58
|
end
|
54
59
|
end
|
60
|
+
|
61
|
+
def associated_shipments
|
62
|
+
if (label_details = @response_details[:completed_shipment_detail][:associated_shipments])
|
63
|
+
label_details[:format] = format
|
64
|
+
label_details[:file_name] = file_name
|
65
|
+
Label.new(label_details, true)
|
66
|
+
else
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
55
70
|
end
|
56
71
|
end
|
data/lib/fedex/rate.rb
CHANGED
@@ -18,9 +18,10 @@ module Fedex
|
|
18
18
|
# @total_net_freight #The freight charge minus dicounts
|
19
19
|
# @total_surcharges #The total amount of all surcharges applied to this shipment
|
20
20
|
# @total_base_charge #The total base charge
|
21
|
-
attr_accessor :service_type, :rate_type, :rate_zone, :total_billing_weight, :total_freight_discounts, :total_net_charge, :total_taxes, :total_net_freight, :total_surcharges, :total_base_charge
|
21
|
+
attr_accessor :service_type, :transit_time, :rate_type, :rate_zone, :total_billing_weight, :total_freight_discounts, :total_net_charge, :total_taxes, :total_net_freight, :total_surcharges, :total_base_charge
|
22
22
|
def initialize(options = {})
|
23
23
|
@service_type = options[:service_type]
|
24
|
+
@transit_time = options[:transit_time]
|
24
25
|
@rate_type = options[:rate_type]
|
25
26
|
@rate_zone = options[:rate_zone]
|
26
27
|
@total_billing_weight = "#{options[:total_billing_weight][:value]} #{options[:total_billing_weight][:units]}"
|
@@ -34,4 +35,4 @@ module Fedex
|
|
34
35
|
@total_rebates = (options[:total_rebates]||{})[:amount]
|
35
36
|
end
|
36
37
|
end
|
37
|
-
end
|
38
|
+
end
|
data/lib/fedex/request/base.rb
CHANGED
@@ -12,10 +12,10 @@ module Fedex
|
|
12
12
|
# If true the rate method will return the complete response from the Fedex Web Service
|
13
13
|
attr_accessor :debug
|
14
14
|
# Fedex Text URL
|
15
|
-
TEST_URL = "https://
|
15
|
+
TEST_URL = "https://wsbeta.fedex.com:443/xml/"
|
16
16
|
|
17
17
|
# Fedex Production URL
|
18
|
-
PRODUCTION_URL = "https://
|
18
|
+
PRODUCTION_URL = "https://ws.fedex.com:443/xml/"
|
19
19
|
|
20
20
|
# List of available Service Types
|
21
21
|
SERVICE_TYPES = %w(EUROPE_FIRST_INTERNATIONAL_PRIORITY FEDEX_1_DAY_FREIGHT FEDEX_2_DAY FEDEX_2_DAY_AM FEDEX_2_DAY_FREIGHT FEDEX_3_DAY_FREIGHT FEDEX_EXPRESS_SAVER FEDEX_FIRST_FREIGHT FEDEX_FREIGHT_ECONOMY FEDEX_FREIGHT_PRIORITY FEDEX_GROUND FIRST_OVERNIGHT GROUND_HOME_DELIVERY INTERNATIONAL_ECONOMY INTERNATIONAL_ECONOMY_FREIGHT INTERNATIONAL_FIRST INTERNATIONAL_PRIORITY INTERNATIONAL_PRIORITY_FREIGHT PRIORITY_OVERNIGHT SMART_POST STANDARD_OVERNIGHT)
|
@@ -35,6 +35,9 @@ module Fedex
|
|
35
35
|
# List of available Payment Types
|
36
36
|
PAYMENT_TYPE = %w(RECIPIENT SENDER THIRD_PARTY)
|
37
37
|
|
38
|
+
# List of available Carrier Codes
|
39
|
+
CARRIER_CODES = %w(FDXC FDXE FDXG FDCC FXFR FXSP)
|
40
|
+
|
38
41
|
# In order to use Fedex rates API you must first apply for a developer(and later production keys),
|
39
42
|
# Visit {http://www.fedex.com/us/developer/ Fedex Developer Center} for more information about how to obtain your keys.
|
40
43
|
# @param [String] key - Fedex web service key
|
@@ -52,6 +55,13 @@ module Fedex
|
|
52
55
|
@shipping_options = options[:shipping_options] ||={}
|
53
56
|
@payment_options = options[:payment_options] ||={}
|
54
57
|
requires!(@payment_options, :type, :account_number, :name, :company, :phone_number, :country_code) if @payment_options.length > 0
|
58
|
+
if options.has_key?(:mps)
|
59
|
+
@mps = options[:mps]
|
60
|
+
requires!(@mps, :package_count, :total_weight, :sequence_number)
|
61
|
+
requires!(@mps, :master_tracking_id) if @mps.has_key?(:sequence_number) && @mps[:sequence_number].to_i >= 2
|
62
|
+
else
|
63
|
+
@mps = {}
|
64
|
+
end
|
55
65
|
# Expects hash with addr and port
|
56
66
|
if options[:http_proxy]
|
57
67
|
self.class.http_proxy options[:http_proxy][:host], options[:http_proxy][:port]
|
@@ -175,13 +185,32 @@ module Fedex
|
|
175
185
|
}
|
176
186
|
end
|
177
187
|
|
188
|
+
# Add Master Tracking Id (for MPS Shipping Labels, this is required when requesting labels 2 through n)
|
189
|
+
def add_master_tracking_id(xml)
|
190
|
+
if @mps.has_key? :master_tracking_id
|
191
|
+
xml.MasterTrackingId{
|
192
|
+
xml.TrackingIdType @mps[:master_tracking_id][:tracking_id_type]
|
193
|
+
xml.TrackingNumber @mps[:master_tracking_id][:tracking_number]
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
178
198
|
# Add packages to xml request
|
179
199
|
def add_packages(xml)
|
200
|
+
add_master_tracking_id(xml) if @mps.has_key? :master_tracking_id
|
180
201
|
package_count = @packages.size
|
181
|
-
|
202
|
+
if @mps.has_key? :package_count
|
203
|
+
xml.PackageCount @mps[:package_count]
|
204
|
+
else
|
205
|
+
xml.PackageCount package_count
|
206
|
+
end
|
182
207
|
@packages.each do |package|
|
183
208
|
xml.RequestedPackageLineItems{
|
184
|
-
|
209
|
+
if @mps.has_key? :sequence_number
|
210
|
+
xml.SequenceNumber @mps[:sequence_number]
|
211
|
+
else
|
212
|
+
xml.GroupPackageCount 1
|
213
|
+
end
|
185
214
|
if package[:insured_value]
|
186
215
|
xml.InsuredValue{
|
187
216
|
xml.Currency package[:insured_value][:currency]
|
@@ -294,7 +323,14 @@ module Fedex
|
|
294
323
|
# Build xml nodes dynamically from the hash keys and values
|
295
324
|
def hash_to_xml(xml, hash)
|
296
325
|
hash.each do |key, value|
|
297
|
-
|
326
|
+
key_s_down = key.to_s.downcase
|
327
|
+
if key_s_down.match(/^commodities_\d{1,}$/)
|
328
|
+
element = 'Commodities'
|
329
|
+
elsif key_s_down.match(/^masked_data_\d{1,}$/)
|
330
|
+
element = 'MaskedData'
|
331
|
+
else
|
332
|
+
element = camelize(key)
|
333
|
+
end
|
298
334
|
if value.is_a?(Hash)
|
299
335
|
xml.send element do |x|
|
300
336
|
hash_to_xml(x, value)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'fedex/request/base'
|
2
|
+
|
3
|
+
module Fedex
|
4
|
+
module Request
|
5
|
+
class Delete < Base
|
6
|
+
|
7
|
+
attr_reader :tracking_number
|
8
|
+
|
9
|
+
def initialize(credentials, options={})
|
10
|
+
requires!(options, :tracking_number)
|
11
|
+
|
12
|
+
@tracking_number = options[:tracking_number]
|
13
|
+
@deletion_control = options[:deletion_control] || 'DELETE_ALL_PACKAGES'
|
14
|
+
@credentials = credentials
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_request
|
18
|
+
api_response = self.class.post(api_url, :body => build_xml)
|
19
|
+
puts api_response if @debug == true
|
20
|
+
response = parse_response(api_response)
|
21
|
+
unless success?(response)
|
22
|
+
error_message = if response[:shipment_reply]
|
23
|
+
[response[:shipment_reply][:notifications]].flatten.first[:message]
|
24
|
+
else
|
25
|
+
"#{api_response["Fault"]["detail"]["fault"]["reason"]}\n
|
26
|
+
--#{api_response["Fault"]["detail"]["fault"]["details"]["ValidationFailureDetail"]["message"].join("\n--")}"
|
27
|
+
end rescue $1
|
28
|
+
raise RateError, error_message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Build xml Fedex Web Service request
|
35
|
+
def build_xml
|
36
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
37
|
+
xml.DeleteShipmentRequest(:xmlns => "http://fedex.com/ws/ship/v#{service[:version]}"){
|
38
|
+
add_web_authentication_detail(xml)
|
39
|
+
add_client_detail(xml)
|
40
|
+
add_version(xml)
|
41
|
+
xml.TrackingId {
|
42
|
+
xml.TrackingIdType 'FEDEX'
|
43
|
+
xml.TrackingNumber @tracking_number
|
44
|
+
}
|
45
|
+
xml.DeletionControl @deletion_control
|
46
|
+
}
|
47
|
+
end
|
48
|
+
builder.doc.root.to_xml
|
49
|
+
end
|
50
|
+
|
51
|
+
def service
|
52
|
+
{ :id => 'ship', :version => Fedex::API_VERSION }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Successful request
|
56
|
+
def success?(response)
|
57
|
+
response[:shipment_reply] &&
|
58
|
+
%w{SUCCESS WARNING NOTE}.include?(response[:shipment_reply][:highest_severity])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|