fedex 3.6.1 → 3.8.0
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/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
|