active_shipping 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +1 -0
- data/lib/active_shipping.rb +1 -0
- data/lib/active_shipping/carriers/fedex.rb +171 -25
- data/lib/active_shipping/carriers/ups.rb +29 -29
- data/lib/active_shipping/carriers/usps.rb +64 -38
- data/lib/active_shipping/label.rb +10 -0
- data/lib/active_shipping/label_response.rb +2 -15
- data/lib/active_shipping/version.rb +1 -1
- data/test/fixtures/xml/fedex/create_shipment_response.xml +2 -0
- data/test/fixtures/xml/usps/tracking_request_batch.xml +12 -0
- data/test/fixtures/xml/usps/tracking_response_batch.xml +223 -0
- data/test/remote/fedex_test.rb +64 -0
- data/test/test_helper.rb +10 -0
- data/test/unit/carriers/fedex_test.rb +41 -0
- data/test/unit/carriers/ups_test.rb +4 -4
- data/test/unit/carriers/usps_test.rb +45 -0
- metadata +9 -4
- data/test/unit/label_response_test.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 167a59476f3013546de9f351d4d62b045ce18695
|
4
|
+
data.tar.gz: 5a8d406aad880b511e8102fe462a3e344a1660d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a21b4a2467b1ead50736c57cd9b3da5494090e6f4866e78d9f91a8cbeff1e89ac1dd7ff82187677ee6f897f718cc4fabd48fb7f8e49b998b5e6e7e51f045fab
|
7
|
+
data.tar.gz: fce0b6be9e67015c62b6ed7651243ad7e09791ca20502509e29c72138a47c400dfca855f4f6203a5f27796916d09467b2931690f5d6440652913d5b13068c019
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# ActiveShipping CHANGELOG
|
2
2
|
|
3
|
+
### v1.2.0
|
4
|
+
|
5
|
+
- Added support for buying labels with FedEx
|
6
|
+
- Added support for batched tracking requests with USPS
|
7
|
+
|
8
|
+
### v1.1.3
|
9
|
+
|
10
|
+
- Handle ZIP+4 numbers in USPS tracking
|
11
|
+
- Add a field for rate estimate references
|
12
|
+
- Add support for UPS mail innovations tracking option
|
13
|
+
|
14
|
+
### v1.1.2
|
15
|
+
|
16
|
+
- Fix finding of error descriptions for USPS tracking
|
17
|
+
|
3
18
|
### v1.1.1
|
4
19
|
|
5
20
|
- Fix bug with USPS tracking not handling optional fields being absent.
|
data/README.md
CHANGED
@@ -5,6 +5,7 @@ This library interfaces with the web services of various shipping carriers. The
|
|
5
5
|
- Finding shipping rates
|
6
6
|
- Registering shipments
|
7
7
|
- Tracking shipments
|
8
|
+
- Purchasing shipping labels
|
8
9
|
|
9
10
|
Active Shipping is currently being used and improved in a production environment for [Shopify][]. Development is being done by the Shopify integrations team (<integrations-team@shopify.com>). Discussion is welcome in the [Active Merchant Google Group][discuss].
|
10
11
|
|
data/lib/active_shipping.rb
CHANGED
@@ -36,6 +36,7 @@ require 'active_shipping/tracking_response'
|
|
36
36
|
require 'active_shipping/delivery_date_estimates_response'
|
37
37
|
require 'active_shipping/shipping_response'
|
38
38
|
require 'active_shipping/label_response'
|
39
|
+
require 'active_shipping/label'
|
39
40
|
require 'active_shipping/package'
|
40
41
|
require 'active_shipping/location'
|
41
42
|
require 'active_shipping/rate_estimate'
|
@@ -68,6 +68,14 @@ module ActiveShipping
|
|
68
68
|
'station' => 'STATION'
|
69
69
|
}
|
70
70
|
|
71
|
+
SIGNATURE_OPTION_CODES = {
|
72
|
+
adult: 'ADULT', # 21 years plus
|
73
|
+
direct: 'DIRECT', # A person at the delivery address
|
74
|
+
indirect: 'INDIRECT', # A person at the delivery address, or a neighbor, or a signed note for fedex on the door
|
75
|
+
none_required: 'NO_SIGNATURE_REQUIRED',
|
76
|
+
default_for_service: 'SERVICE_DEFAULT'
|
77
|
+
}
|
78
|
+
|
71
79
|
PAYMENT_TYPES = {
|
72
80
|
'sender' => 'SENDER',
|
73
81
|
'recipient' => 'RECIPIENT',
|
@@ -153,10 +161,127 @@ module ActiveShipping
|
|
153
161
|
parse_tracking_response(xml, options)
|
154
162
|
end
|
155
163
|
|
164
|
+
|
165
|
+
# Get Shipping labels
|
166
|
+
def create_shipment(origin, destination, packages, options = {})
|
167
|
+
options = @options.update(options)
|
168
|
+
packages = Array(packages)
|
169
|
+
raise Error, "Multiple packages are not supported yet." if packages.length > 1
|
170
|
+
|
171
|
+
request = build_shipment_request(origin, destination, packages, options)
|
172
|
+
logger.debug(request) if logger
|
173
|
+
|
174
|
+
logger.debug(confirm_response) if logger
|
175
|
+
|
176
|
+
response = commit(save_request(request), (options[:test] || false))
|
177
|
+
parse_ship_response(response)
|
178
|
+
end
|
179
|
+
|
156
180
|
protected
|
157
181
|
|
182
|
+
def build_shipment_request(origin, destination, packages, options = {})
|
183
|
+
imperial = location_uses_imperial(origin)
|
184
|
+
|
185
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
186
|
+
xml.ProcessShipmentRequest(xmlns: 'http://fedex.com/ws/ship/v13') do
|
187
|
+
build_request_header(xml)
|
188
|
+
build_version_node(xml, 'ship', 13, 0 ,0)
|
189
|
+
|
190
|
+
xml.RequestedShipment do
|
191
|
+
xml.ShipTimestamp(ship_timestamp(options[:turn_around_time]).iso8601(0))
|
192
|
+
xml.DropoffType('REGULAR_PICKUP')
|
193
|
+
xml.ServiceType(options[:service_type] || 'FEDEX_GROUND')
|
194
|
+
xml.PackagingType('YOUR_PACKAGING')
|
195
|
+
|
196
|
+
xml.Shipper do
|
197
|
+
build_contact_address_nodes(xml, options[:shipper] || origin)
|
198
|
+
end
|
199
|
+
|
200
|
+
xml.Recipient do
|
201
|
+
build_contact_address_nodes(xml, destination)
|
202
|
+
end
|
203
|
+
|
204
|
+
xml.Origin do
|
205
|
+
build_contact_address_nodes(xml, origin)
|
206
|
+
end
|
207
|
+
|
208
|
+
xml.ShippingChargesPayment do
|
209
|
+
xml.PaymentType('SENDER')
|
210
|
+
xml.Payor do
|
211
|
+
build_shipment_responsible_party_node(xml, options[:shipper] || origin)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
xml.LabelSpecification do
|
216
|
+
xml.LabelFormatType('COMMON2D')
|
217
|
+
xml.ImageType('PNG')
|
218
|
+
xml.LabelStockType('PAPER_7X4.75')
|
219
|
+
end
|
220
|
+
|
221
|
+
xml.RateRequestTypes('ACCOUNT')
|
222
|
+
|
223
|
+
xml.PackageCount(packages.size)
|
224
|
+
packages.each do |package|
|
225
|
+
xml.RequestedPackageLineItems do
|
226
|
+
xml.GroupPackageCount(1)
|
227
|
+
build_package_weight_node(xml, package, imperial)
|
228
|
+
build_package_dimensions_node(xml, package, imperial)
|
229
|
+
|
230
|
+
# Reference Numbers
|
231
|
+
reference_numbers = Array(package.options[:reference_numbers])
|
232
|
+
if reference_numbers.size > 0
|
233
|
+
xml.CustomerReferences do
|
234
|
+
reference_numbers.each do |reference_number_info|
|
235
|
+
xml.CustomerReferenceType(reference_number_info[:type] || "CUSTOMER_REFERENCE")
|
236
|
+
xml.Value(reference_number_info[:value])
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
xml.SpecialServicesRequested do
|
242
|
+
xml.SpecialServiceTypes("SIGNATURE_OPTION")
|
243
|
+
xml.SignatureOptionDetail do
|
244
|
+
xml.OptionType(SIGNATURE_OPTION_CODES[package.options[:signature_option] || :default_for_service])
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
xml_builder.to_xml
|
253
|
+
end
|
254
|
+
|
255
|
+
def build_contact_address_nodes(xml, location)
|
256
|
+
xml.Contact do
|
257
|
+
xml.PersonName(location.name)
|
258
|
+
xml.CompanyName(location.company)
|
259
|
+
xml.PhoneNumber(location.phone)
|
260
|
+
end
|
261
|
+
xml.Address do
|
262
|
+
xml.StreetLines(location.address1) if location.address1
|
263
|
+
xml.StreetLines(location.address2) if location.address2
|
264
|
+
xml.City(location.city) if location.city
|
265
|
+
xml.StateOrProvinceCode(location.state)
|
266
|
+
xml.PostalCode(location.postal_code)
|
267
|
+
xml.CountryCode(location.country_code(:alpha2))
|
268
|
+
xml.Residential('true') if location.residential?
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def build_shipment_responsible_party_node(xml, origin)
|
273
|
+
xml.ResponsibleParty do
|
274
|
+
xml.AccountNumber(@options[:account])
|
275
|
+
xml.Contact do
|
276
|
+
xml.PersonName(origin.name)
|
277
|
+
xml.CompanyName(origin.company)
|
278
|
+
xml.PhoneNumber(origin.phone)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
158
283
|
def build_rate_request(origin, destination, packages, options = {})
|
159
|
-
imperial =
|
284
|
+
imperial = location_uses_imperial(origin)
|
160
285
|
|
161
286
|
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
162
287
|
xml.RateRequest(xmlns: 'http://fedex.com/ws/rate/v13') do
|
@@ -341,31 +466,35 @@ module ActiveShipping
|
|
341
466
|
success = response_success?(xml)
|
342
467
|
message = response_message(xml)
|
343
468
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
469
|
+
if success
|
470
|
+
rate_estimates = xml.root.css('> RateReplyDetails').map do |rated_shipment|
|
471
|
+
service_code = rated_shipment.at('ServiceType').text
|
472
|
+
is_saturday_delivery = rated_shipment.at('AppliedOptions').try(:text) == 'SATURDAY_DELIVERY'
|
473
|
+
service_type = is_saturday_delivery ? "#{service_code}_SATURDAY_DELIVERY" : service_code
|
474
|
+
|
475
|
+
transit_time = rated_shipment.at('TransitTime').text if service_code == "FEDEX_GROUND"
|
476
|
+
max_transit_time = rated_shipment.at('MaximumTransitTime').try(:text) if service_code == "FEDEX_GROUND"
|
477
|
+
|
478
|
+
delivery_timestamp = rated_shipment.at('DeliveryTimestamp').try(:text)
|
479
|
+
|
480
|
+
delivery_range = delivery_range_from(transit_time, max_transit_time, delivery_timestamp, options)
|
481
|
+
|
482
|
+
currency = rated_shipment.at('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Currency').text
|
483
|
+
RateEstimate.new(origin, destination, @@name,
|
484
|
+
self.class.service_name_for_code(service_type),
|
485
|
+
:service_code => service_code,
|
486
|
+
:total_price => rated_shipment.at('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').text.to_f,
|
487
|
+
:currency => currency,
|
488
|
+
:packages => packages,
|
489
|
+
:delivery_range => delivery_range)
|
490
|
+
end
|
365
491
|
|
366
|
-
|
367
|
-
|
368
|
-
|
492
|
+
if rate_estimates.empty?
|
493
|
+
success = false
|
494
|
+
message = "No shipping rates could be found for the destination address" if message.blank?
|
495
|
+
end
|
496
|
+
else
|
497
|
+
rate_estimates = []
|
369
498
|
end
|
370
499
|
|
371
500
|
RateResponse.new(success, message, Hash.from_xml(response), :rates => rate_estimates, :xml => response, :request => last_request, :log_xml => options[:log_xml])
|
@@ -383,6 +512,19 @@ module ActiveShipping
|
|
383
512
|
delivery_range
|
384
513
|
end
|
385
514
|
|
515
|
+
def parse_ship_response(response)
|
516
|
+
xml = build_document(response, 'ProcessShipmentReply')
|
517
|
+
success = response_success?(xml)
|
518
|
+
message = response_message(xml)
|
519
|
+
|
520
|
+
response_info = Hash.from_xml(response)
|
521
|
+
tracking_number = xml.css("CompletedPackageDetails TrackingIds TrackingNumber").text
|
522
|
+
base_64_image = xml.css("Label Image").text
|
523
|
+
|
524
|
+
labels = [Label.new(tracking_number, Base64.decode64(base_64_image))]
|
525
|
+
LabelResponse.new(success, message, response_info, {labels: labels})
|
526
|
+
end
|
527
|
+
|
386
528
|
def business_days_from(date, days)
|
387
529
|
future_date = date
|
388
530
|
count = 0
|
@@ -577,5 +719,9 @@ module ActiveShipping
|
|
577
719
|
rescue Nokogiri::XML::SyntaxError => e
|
578
720
|
raise ActiveShipping::ResponseContentError.new(e, xml)
|
579
721
|
end
|
722
|
+
|
723
|
+
def location_uses_imperial(location)
|
724
|
+
%w(US LR MM).include?(location.country_code(:alpha2))
|
725
|
+
end
|
580
726
|
end
|
581
727
|
end
|
@@ -156,39 +156,32 @@ module ActiveShipping
|
|
156
156
|
packages = Array(packages)
|
157
157
|
access_request = build_access_request
|
158
158
|
|
159
|
-
|
159
|
+
# STEP 1: Confirm. Validation step, important for verifying price.
|
160
|
+
confirm_request = build_shipment_request(origin, destination, packages, options)
|
161
|
+
logger.debug(confirm_request) if logger
|
160
162
|
|
161
|
-
|
162
|
-
|
163
|
-
logger.debug(confirm_request) if logger
|
163
|
+
confirm_response = commit(:ship_confirm, save_request(access_request + confirm_request), (options[:test] || false))
|
164
|
+
logger.debug(confirm_response) if logger
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
message = response_message(xml)
|
174
|
-
raise message unless success
|
175
|
-
digest = response_digest(xml)
|
176
|
-
|
177
|
-
# STEP 2: Accept. Use shipment digest in first response to get the actual label.
|
178
|
-
accept_request = build_accept_request(digest, options)
|
179
|
-
logger.debug(accept_request) if logger
|
180
|
-
|
181
|
-
accept_response = commit(:ship_accept, save_request(access_request + accept_request), (options[:test] || false))
|
182
|
-
logger.debug(accept_response) if logger
|
166
|
+
# ... now, get the digest, it's needed to get the label. In theory,
|
167
|
+
# one could make decisions based on the price or some such to avoid
|
168
|
+
# surprises. This also has *no* error handling yet.
|
169
|
+
xml = parse_ship_confirm(confirm_response)
|
170
|
+
success = response_success?(xml)
|
171
|
+
message = response_message(xml)
|
172
|
+
raise message unless success
|
173
|
+
digest = response_digest(xml)
|
183
174
|
|
184
|
-
|
185
|
-
|
186
|
-
|
175
|
+
# STEP 2: Accept. Use shipment digest in first response to get the actual label.
|
176
|
+
accept_request = build_accept_request(digest, options)
|
177
|
+
logger.debug(accept_request) if logger
|
187
178
|
|
188
|
-
|
189
|
-
|
179
|
+
accept_response = commit(:ship_accept, save_request(access_request + accept_request), (options[:test] || false))
|
180
|
+
logger.debug(accept_response) if logger
|
190
181
|
|
191
|
-
|
182
|
+
# ...finally, build a map from the response that contains
|
183
|
+
# the label data and tracking information.
|
184
|
+
parse_ship_accept(accept_response)
|
192
185
|
end
|
193
186
|
|
194
187
|
def get_delivery_date_estimates(origin, destination, packages, pickup_date=Date.current, options = {})
|
@@ -855,7 +848,14 @@ module ActiveShipping
|
|
855
848
|
success = response_success?(xml)
|
856
849
|
message = response_message(xml)
|
857
850
|
|
858
|
-
|
851
|
+
response_info = Hash.from_xml(response).values.first
|
852
|
+
packages = response_info["ShipmentResults"]["PackageResults"]
|
853
|
+
packages = [packages] if Hash === packages
|
854
|
+
labels = packages.map do |package|
|
855
|
+
Label.new(package["TrackingNumber"], Base64.decode64(package["LabelImage"]["GraphicImage"]))
|
856
|
+
end
|
857
|
+
|
858
|
+
LabelResponse.new(success, message, response_info, {labels: labels})
|
859
859
|
end
|
860
860
|
|
861
861
|
def commit(action, request, test = false)
|
@@ -169,7 +169,14 @@ module ActiveShipping
|
|
169
169
|
options = @options.update(options)
|
170
170
|
tracking_request = build_tracking_request(tracking_number, options)
|
171
171
|
response = commit(:track, tracking_request, options[:test] || false)
|
172
|
-
parse_tracking_response(response
|
172
|
+
parse_tracking_response(response).first
|
173
|
+
end
|
174
|
+
|
175
|
+
def batch_find_tracking_info(tracking_infos, options = {})
|
176
|
+
options = @options.update(options)
|
177
|
+
tracking_request = build_tracking_batch_request(tracking_infos, options)
|
178
|
+
response = commit(:track, tracking_request, options[:test] || false)
|
179
|
+
parse_tracking_response(response, fault_tolerant: true)
|
173
180
|
end
|
174
181
|
|
175
182
|
def self.size_code_for(package)
|
@@ -230,7 +237,7 @@ module ActiveShipping
|
|
230
237
|
if prefix = ONLY_PREFIX_EVENTS.find { |p| description.starts_with?(p) }
|
231
238
|
description = prefix
|
232
239
|
end
|
233
|
-
|
240
|
+
|
234
241
|
timestamp = "#{node.at('EventDate').text}, #{node.at('EventTime').text}"
|
235
242
|
event_code = node.at('EventCode').text
|
236
243
|
city = node.at('EventCity').try(:text)
|
@@ -250,16 +257,26 @@ module ActiveShipping
|
|
250
257
|
protected
|
251
258
|
|
252
259
|
def build_tracking_request(tracking_number, options = {})
|
260
|
+
build_tracking_batch_request([{
|
261
|
+
number: tracking_number,
|
262
|
+
destination_zip: options[:destination_zip],
|
263
|
+
mailing_date: options[:mailing_date]
|
264
|
+
}], options)
|
265
|
+
end
|
266
|
+
|
267
|
+
def build_tracking_batch_request(tracking_infos, options)
|
253
268
|
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
254
|
-
xml.TrackFieldRequest('USERID' =>
|
269
|
+
xml.TrackFieldRequest('USERID' => options[:login]) do
|
255
270
|
xml.Revision { xml.text('1') }
|
256
|
-
xml.ClientIp { xml.text(
|
257
|
-
xml.SourceId { xml.text(
|
258
|
-
|
259
|
-
xml.
|
260
|
-
|
261
|
-
|
262
|
-
|
271
|
+
xml.ClientIp { xml.text(options[:client_ip] || '127.0.0.1') }
|
272
|
+
xml.SourceId { xml.text(options[:source_id] || 'active_shipping') }
|
273
|
+
tracking_infos.each do |info|
|
274
|
+
xml.TrackID('ID' => info[:number]) do
|
275
|
+
xml.DestinationZipCode { xml.text(strip_zip(info[:destination_zip]))} if info[:destination_zip]
|
276
|
+
if info[:mailing_date]
|
277
|
+
formatted_date = info[:mailing_date].strftime('%Y-%m-%d')
|
278
|
+
xml.MailingDate { xml.text(formatted_date)}
|
279
|
+
end
|
263
280
|
end
|
264
281
|
end
|
265
282
|
end
|
@@ -536,21 +553,44 @@ module ActiveShipping
|
|
536
553
|
package.inches(:length) + package.inches(:width) + package.inches(:height)))
|
537
554
|
end
|
538
555
|
|
539
|
-
def parse_tracking_response(response, options)
|
540
|
-
actual_delivery_date, status = nil
|
556
|
+
def parse_tracking_response(response, options = {})
|
541
557
|
xml = Nokogiri.XML(response)
|
542
558
|
|
543
|
-
|
544
|
-
|
559
|
+
if has_error?(xml)
|
560
|
+
message = error_description_node(xml).text
|
561
|
+
# actually raises instead of returning by nature of TrackingResponse#initialize
|
562
|
+
return TrackingResponse.new(false, message, Hash.from_xml(response),
|
563
|
+
carrier: @@name, xml: response, request: last_request)
|
564
|
+
end
|
565
|
+
|
566
|
+
# Responses are always returned in the order originally given.
|
567
|
+
if options[:fault_tolerant]
|
568
|
+
xml.root.xpath('TrackInfo').map do |info|
|
569
|
+
# Don't let one failure wreck the whole batch
|
570
|
+
begin
|
571
|
+
parse_tracking_info(response, info)
|
572
|
+
rescue ResponseError => e
|
573
|
+
e.response
|
574
|
+
end
|
575
|
+
end
|
576
|
+
else
|
577
|
+
xml.root.xpath('TrackInfo').map { |info| parse_tracking_info(response, info) }
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
|
582
|
+
def parse_tracking_info(response, node)
|
583
|
+
success = !has_error?(node)
|
584
|
+
message = response_message(node)
|
545
585
|
|
546
586
|
if success
|
547
587
|
destination = nil
|
548
588
|
shipment_events = []
|
549
|
-
tracking_details =
|
550
|
-
tracking_details <<
|
589
|
+
tracking_details = node.xpath('TrackDetail')
|
590
|
+
tracking_details << node.at('TrackSummary')
|
551
591
|
|
552
|
-
tracking_number =
|
553
|
-
prediction_node =
|
592
|
+
tracking_number = node.attributes['ID'].value
|
593
|
+
prediction_node = node.at('PredictedDeliveryDate') || node.at('ExpectedDeliveryDate')
|
554
594
|
scheduled_delivery = prediction_node ? Time.parse(prediction_node.text) : nil
|
555
595
|
|
556
596
|
tracking_details.each do |event|
|
@@ -582,30 +622,16 @@ module ActiveShipping
|
|
582
622
|
)
|
583
623
|
end
|
584
624
|
|
585
|
-
def
|
586
|
-
|
587
|
-
end
|
588
|
-
|
589
|
-
def error_description_node(document)
|
590
|
-
document.xpath('//Error/Description')
|
591
|
-
end
|
592
|
-
|
593
|
-
def response_status_node(document)
|
594
|
-
summary = track_summary_node(document)
|
595
|
-
return summary unless summary.empty?
|
596
|
-
error_description_node(document)
|
597
|
-
end
|
598
|
-
|
599
|
-
def has_error?(document)
|
600
|
-
!document.at('Error').nil?
|
625
|
+
def error_description_node(node)
|
626
|
+
node.xpath('//Error/Description')
|
601
627
|
end
|
602
628
|
|
603
|
-
def
|
604
|
-
|
629
|
+
def response_status_node(node)
|
630
|
+
node.at('StatusSummary') || error_description_node(node)
|
605
631
|
end
|
606
632
|
|
607
|
-
def
|
608
|
-
|
633
|
+
def has_error?(node)
|
634
|
+
node.xpath('Error').length > 0
|
609
635
|
end
|
610
636
|
|
611
637
|
def response_message(document)
|
@@ -1,23 +1,10 @@
|
|
1
1
|
module ActiveShipping
|
2
|
-
|
3
|
-
# This is UPS specific for now; the hash is not at all generic
|
4
|
-
# or common between carriers.
|
5
2
|
class LabelResponse < Response
|
6
|
-
|
3
|
+
attr_reader :labels
|
7
4
|
|
8
5
|
def initialize(success, message, params = {}, options = {})
|
9
|
-
@
|
6
|
+
@labels = options[:labels]
|
10
7
|
super
|
11
8
|
end
|
12
|
-
|
13
|
-
def labels
|
14
|
-
return @labels if @labels
|
15
|
-
packages = params["ShipmentResults"]["PackageResults"]
|
16
|
-
packages = [packages] if Hash === packages
|
17
|
-
@labels = packages.map do |package|
|
18
|
-
{ :tracking_number => package["TrackingNumber"],
|
19
|
-
:image => package["LabelImage"] }
|
20
|
-
end
|
21
|
-
end
|
22
9
|
end
|
23
10
|
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<v13:ProcessShipmentReply xmlns:v13="http://fedex.com/ws/ship/v13"><v13:HighestSeverity>SUCCESS</v13:HighestSeverity><v13:Notifications><v13:Severity>SUCCESS</v13:Severity><v13:Source>ship</v13:Source><v13:Code>0000</v13:Code><v13:Message>Success</v13:Message><v13:LocalizedMessage>Success</v13:LocalizedMessage></v13:Notifications><v13:TransactionDetail> <v13:CustomerTransactionId>ActiveShipping</v13:CustomerTransactionId> </v13:TransactionDetail><v13:Version> <v13:ServiceId>ship</v13:ServiceId> <v13:Major>13</v13:Major> <v13:Intermediate>0</v13:Intermediate> <v13:Minor>0</v13:Minor> </v13:Version><v13:JobId>2cbe617200571fq127edj036951</v13:JobId><v13:CompletedShipmentDetail><v13:UsDomestic>true</v13:UsDomestic><v13:CarrierCode>FDXG</v13:CarrierCode><v13:PackagingDescription>YOUR_PACKAGING</v13:PackagingDescription><v13:OperationalDetail><v13:OriginLocationNumber>915</v13:OriginLocationNumber><v13:DestinationLocationNumber>100</v13:DestinationLocationNumber><v13:TransitTime>FOUR_DAYS</v13:TransitTime><v13:IneligibleForMoneyBackGuarantee>false</v13:IneligibleForMoneyBackGuarantee><v13:DeliveryEligibilities>SATURDAY_DELIVERY</v13:DeliveryEligibilities><v13:ServiceCode>92</v13:ServiceCode></v13:OperationalDetail><v13:ShipmentRating><v13:ActualRateType>PAYOR_ACCOUNT_PACKAGE</v13:ActualRateType><v13:ShipmentRateDetails><v13:RateType>PAYOR_ACCOUNT_PACKAGE</v13:RateType><v13:RateZone>8</v13:RateZone><v13:RatedWeightMethod>ACTUAL</v13:RatedWeightMethod><v13:DimDivisor>0</v13:DimDivisor><v13:FuelSurchargePercent>4.5</v13:FuelSurchargePercent><v13:TotalBillingWeight><v13:Units>LB</v13:Units><v13:Value>8.0</v13:Value></v13:TotalBillingWeight><v13:TotalBaseCharge><v13:Currency>USD</v13:Currency><v13:Amount>12.79</v13:Amount></v13:TotalBaseCharge><v13:TotalFreightDiscounts><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalFreightDiscounts><v13:TotalNetFreight><v13:Currency>USD</v13:Currency><v13:Amount>12.79</v13:Amount></v13:TotalNetFreight><v13:TotalSurcharges><v13:Currency>USD</v13:Currency><v13:Amount>0.58</v13:Amount></v13:TotalSurcharges><v13:TotalNetFedExCharge><v13:Currency>USD</v13:Currency><v13:Amount>13.37</v13:Amount></v13:TotalNetFedExCharge><v13:TotalTaxes><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalTaxes><v13:TotalNetCharge><v13:Currency>USD</v13:Currency><v13:Amount>13.37</v13:Amount></v13:TotalNetCharge><v13:TotalRebates><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalRebates><v13:Surcharges><v13:SurchargeType>FUEL</v13:SurchargeType><v13:Level>PACKAGE</v13:Level><v13:Description>FedEx Ground Fuel</v13:Description><v13:Amount><v13:Currency>USD</v13:Currency><v13:Amount>0.58</v13:Amount></v13:Amount></v13:Surcharges></v13:ShipmentRateDetails></v13:ShipmentRating><v13:CompletedPackageDetails><v13:SequenceNumber>1</v13:SequenceNumber><v13:TrackingIds><v13:TrackingIdType>FEDEX</v13:TrackingIdType><v13:TrackingNumber>794637052920</v13:TrackingNumber></v13:TrackingIds><v13:GroupNumber>0</v13:GroupNumber><v13:PackageRating><v13:ActualRateType>PAYOR_ACCOUNT_PACKAGE</v13:ActualRateType><v13:PackageRateDetails><v13:RateType>PAYOR_ACCOUNT_PACKAGE</v13:RateType><v13:RatedWeightMethod>ACTUAL</v13:RatedWeightMethod><v13:BillingWeight><v13:Units>LB</v13:Units><v13:Value>8.0</v13:Value></v13:BillingWeight><v13:BaseCharge><v13:Currency>USD</v13:Currency><v13:Amount>12.79</v13:Amount></v13:BaseCharge><v13:TotalFreightDiscounts><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalFreightDiscounts><v13:NetFreight><v13:Currency>USD</v13:Currency><v13:Amount>12.79</v13:Amount></v13:NetFreight><v13:TotalSurcharges><v13:Currency>USD</v13:Currency><v13:Amount>0.58</v13:Amount></v13:TotalSurcharges><v13:NetFedExCharge><v13:Currency>USD</v13:Currency><v13:Amount>13.37</v13:Amount></v13:NetFedExCharge><v13:TotalTaxes><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalTaxes><v13:NetCharge><v13:Currency>USD</v13:Currency><v13:Amount>13.37</v13:Amount></v13:NetCharge><v13:TotalRebates><v13:Currency>USD</v13:Currency><v13:Amount>0.0</v13:Amount></v13:TotalRebates><v13:Surcharges><v13:SurchargeType>FUEL</v13:SurchargeType><v13:Level>PACKAGE</v13:Level><v13:Description>FedEx Ground Fuel</v13:Description><v13:Amount><v13:Currency>USD</v13:Currency><v13:Amount>0.58</v13:Amount></v13:Amount></v13:Surcharges></v13:PackageRateDetails></v13:PackageRating><v13:OperationalDetail><v13:OperationalInstructions><v13:Number>2</v13:Number><v13:Content>TRK#</v13:Content></v13:OperationalInstructions><v13:OperationalInstructions><v13:Number>7</v13:Number><v13:Content>9622001900008000296000794637052920</v13:Content></v13:OperationalInstructions><v13:OperationalInstructions><v13:Number>8</v13:Number><v13:Content>537J1/25E2/EE4B</v13:Content></v13:OperationalInstructions><v13:OperationalInstructions><v13:Number>10</v13:Number><v13:Content>7946 3705 2920</v13:Content></v13:OperationalInstructions><v13:OperationalInstructions><v13:Number>15</v13:Number><v13:Content>10017</v13:Content></v13:OperationalInstructions><v13:OperationalInstructions><v13:Number>18</v13:Number><v13:Content>9622 0019 0 (000 800 0296) 0 00 7946 3705 2920</v13:Content></v13:OperationalInstructions><v13:Barcodes><v13:BinaryBarcodes><v13:Type>COMMON_2D</v13:Type><v13:Value>Wyk+HjAxHTAyMTAwMTcdODQwHTAxOR03OTQ2MzcwNTI5MjAdRkRFRx0wMDA4MDAwMjk2HTEyMB0dMS8xHTcuNTBMQh1OHTc4MCAzcmQgQXZlbnVlHU5ldyBZb3JrHU5ZHUJvYiBCb2JzZW4eMDYdMTBaR0QwMDcdMTJaMTIzMTIzMTIzNB0xNFpTdWl0ZSAgMjYwMR0yMFocHTMxWjk2MjIwMDE5MDAwMDgwMDAyOTYwMDA3OTQ2MzcwNTI5MjAdMzRaMDEdHgQ=</v13:Value></v13:BinaryBarcodes><v13:StringBarcodes><v13:Type>FEDEX_1D</v13:Type><v13:Value>9622001900008000296000794637052920</v13:Value></v13:StringBarcodes></v13:Barcodes><v13:GroundServiceCode>019</v13:GroundServiceCode></v13:OperationalDetail><v13:Label><v13:Type>OUTBOUND_LABEL</v13:Type><v13:ShippingDocumentDisposition>RETURNED</v13:ShippingDocumentDisposition><v13:ImageType>PNG</v13:ImageType><v13:Resolution>200</v13:Resolution><v13:CopiesToPrint>1</v13:CopiesToPrint><v13:Parts><v13:DocumentPartSequenceNumber>1</v13:DocumentPartSequenceNumber><v13:Image>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</v13:Image></v13:Parts></v13:Label><v13:SignatureOption>SERVICE_DEFAULT</v13:SignatureOption></v13:CompletedPackageDetails></v13:CompletedShipmentDetail></v13:ProcessShipmentReply>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<TrackFieldRequest USERID="login">
|
3
|
+
<Revision>1</Revision>
|
4
|
+
<ClientIp>127.0.0.1</ClientIp>
|
5
|
+
<SourceId>active_shipping</SourceId>
|
6
|
+
<TrackID ID="9102901000462189604217">
|
7
|
+
<DestinationZipCode>12345</DestinationZipCode>
|
8
|
+
<MailingDate>2010-01-30</MailingDate>
|
9
|
+
</TrackID>
|
10
|
+
<TrackID ID="5555555555555555555555"/>
|
11
|
+
<TrackID ID="9405510ee200828613653750"/>
|
12
|
+
</TrackFieldRequest>
|
@@ -0,0 +1,223 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<TrackResponse>
|
3
|
+
<TrackInfo ID="9102901000462189604217">
|
4
|
+
<Class>First-Class Package Service</Class>
|
5
|
+
<ClassOfMailCode>FC</ClassOfMailCode>
|
6
|
+
<DestinationCity>HANNA CITY</DestinationCity>
|
7
|
+
<DestinationState>IL</DestinationState>
|
8
|
+
<DestinationZip>61536</DestinationZip>
|
9
|
+
<EmailEnabled>true</EmailEnabled>
|
10
|
+
<ExpectedDeliveryDate>April 28, 2015</ExpectedDeliveryDate>
|
11
|
+
<KahalaIndicator>false</KahalaIndicator>
|
12
|
+
<MailTypeCode>DM</MailTypeCode>
|
13
|
+
<MPDATE>2015-04-24 02:08:04.000000</MPDATE>
|
14
|
+
<MPSUFFIX>495865558</MPSUFFIX>
|
15
|
+
<OriginCity>ARGYLE</OriginCity>
|
16
|
+
<OriginState>TX</OriginState>
|
17
|
+
<OriginZip>76226</OriginZip>
|
18
|
+
<PodEnabled>false</PodEnabled>
|
19
|
+
<PredictedDeliveryDate>April 28, 2015</PredictedDeliveryDate>
|
20
|
+
<RestoreEnabled>false</RestoreEnabled>
|
21
|
+
<RramEnabled>false</RramEnabled>
|
22
|
+
<RreEnabled>false</RreEnabled>
|
23
|
+
<Service>USPS Tracking<SUP>&#153;</SUP></Service>
|
24
|
+
<ServiceTypeCode>001</ServiceTypeCode>
|
25
|
+
<Status>Delivered, In/At Mailbox</Status>
|
26
|
+
<StatusCategory>Delivered</StatusCategory>
|
27
|
+
<StatusSummary>Your item was delivered in or at the mailbox at 9:01 am on April 28, 2015 in HANNA CITY, IL 61536.</StatusSummary>
|
28
|
+
<TABLECODE>T</TABLECODE>
|
29
|
+
<TrackSummary>
|
30
|
+
<EventTime>9:01 am</EventTime>
|
31
|
+
<EventDate>April 28, 2015</EventDate>
|
32
|
+
<Event>Delivered, In/At Mailbox</Event>
|
33
|
+
<EventCity>HANNA CITY</EventCity>
|
34
|
+
<EventState>IL</EventState>
|
35
|
+
<EventZIPCode>61536</EventZIPCode>
|
36
|
+
<EventCountry/>
|
37
|
+
<FirmName/>
|
38
|
+
<Name/>
|
39
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
40
|
+
<EventCode>01</EventCode>
|
41
|
+
<DeliveryAttributeCode>01</DeliveryAttributeCode>
|
42
|
+
</TrackSummary>
|
43
|
+
<TrackDetail>
|
44
|
+
<EventTime>8:29 am</EventTime>
|
45
|
+
<EventDate>April 28, 2015</EventDate>
|
46
|
+
<Event>Out for Delivery</Event>
|
47
|
+
<EventCity>HANNA CITY</EventCity>
|
48
|
+
<EventState>IL</EventState>
|
49
|
+
<EventZIPCode>61536</EventZIPCode>
|
50
|
+
<EventCountry/>
|
51
|
+
<FirmName/>
|
52
|
+
<Name/>
|
53
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
54
|
+
<EventCode>OF</EventCode>
|
55
|
+
</TrackDetail>
|
56
|
+
<TrackDetail>
|
57
|
+
<EventTime>8:19 am</EventTime>
|
58
|
+
<EventDate>April 28, 2015</EventDate>
|
59
|
+
<Event>Sorting Complete</Event>
|
60
|
+
<EventCity>HANNA CITY</EventCity>
|
61
|
+
<EventState>IL</EventState>
|
62
|
+
<EventZIPCode>61536</EventZIPCode>
|
63
|
+
<EventCountry/>
|
64
|
+
<FirmName/>
|
65
|
+
<Name/>
|
66
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
67
|
+
<EventCode>PC</EventCode>
|
68
|
+
</TrackDetail>
|
69
|
+
<TrackDetail>
|
70
|
+
<EventTime>7:03 am</EventTime>
|
71
|
+
<EventDate>April 28, 2015</EventDate>
|
72
|
+
<Event>Arrived at Post Office</Event>
|
73
|
+
<EventCity>HANNA CITY</EventCity>
|
74
|
+
<EventState>IL</EventState>
|
75
|
+
<EventZIPCode>61536</EventZIPCode>
|
76
|
+
<EventCountry/>
|
77
|
+
<FirmName/>
|
78
|
+
<Name/>
|
79
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
80
|
+
<EventCode>07</EventCode>
|
81
|
+
</TrackDetail>
|
82
|
+
<TrackDetail>
|
83
|
+
<EventTime>4:05 am</EventTime>
|
84
|
+
<EventDate>April 28, 2015</EventDate>
|
85
|
+
<Event>Departed USPS Facility</Event>
|
86
|
+
<EventCity>HAZELWOOD</EventCity>
|
87
|
+
<EventState>MO</EventState>
|
88
|
+
<EventZIPCode>63042</EventZIPCode>
|
89
|
+
<EventCountry/>
|
90
|
+
<FirmName/>
|
91
|
+
<Name/>
|
92
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
93
|
+
<EventCode>EF</EventCode>
|
94
|
+
</TrackDetail>
|
95
|
+
<TrackDetail>
|
96
|
+
<EventTime>4:04 pm</EventTime>
|
97
|
+
<EventDate>April 27, 2015</EventDate>
|
98
|
+
<Event>Arrived at USPS Facility</Event>
|
99
|
+
<EventCity>HAZELWOOD</EventCity>
|
100
|
+
<EventState>MO</EventState>
|
101
|
+
<EventZIPCode>63042</EventZIPCode>
|
102
|
+
<EventCountry/>
|
103
|
+
<FirmName/>
|
104
|
+
<Name/>
|
105
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
106
|
+
<EventCode>10</EventCode>
|
107
|
+
</TrackDetail>
|
108
|
+
<TrackDetail>
|
109
|
+
<EventTime>12:18 am</EventTime>
|
110
|
+
<EventDate>April 26, 2015</EventDate>
|
111
|
+
<Event>Departed USPS Facility</Event>
|
112
|
+
<EventCity>COPPELL</EventCity>
|
113
|
+
<EventState>TX</EventState>
|
114
|
+
<EventZIPCode>75099</EventZIPCode>
|
115
|
+
<EventCountry/>
|
116
|
+
<FirmName/>
|
117
|
+
<Name/>
|
118
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
119
|
+
<EventCode>EF</EventCode>
|
120
|
+
</TrackDetail>
|
121
|
+
<TrackDetail>
|
122
|
+
<EventTime>7:19 pm</EventTime>
|
123
|
+
<EventDate>April 25, 2015</EventDate>
|
124
|
+
<Event>Arrived at USPS Origin Facility</Event>
|
125
|
+
<EventCity>COPPELL</EventCity>
|
126
|
+
<EventState>TX</EventState>
|
127
|
+
<EventZIPCode>75099</EventZIPCode>
|
128
|
+
<EventCountry/>
|
129
|
+
<FirmName/>
|
130
|
+
<Name/>
|
131
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
132
|
+
<EventCode>10</EventCode>
|
133
|
+
</TrackDetail>
|
134
|
+
<TrackDetail>
|
135
|
+
<EventTime>6:04 pm</EventTime>
|
136
|
+
<EventDate>April 25, 2015</EventDate>
|
137
|
+
<Event>Accepted at USPS Origin Sort Facility</Event>
|
138
|
+
<EventCity>ARGYLE</EventCity>
|
139
|
+
<EventState>TX</EventState>
|
140
|
+
<EventZIPCode>76226</EventZIPCode>
|
141
|
+
<EventCountry/>
|
142
|
+
<FirmName/>
|
143
|
+
<Name/>
|
144
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
145
|
+
<EventCode>OA</EventCode>
|
146
|
+
</TrackDetail>
|
147
|
+
<TrackDetail>
|
148
|
+
<EventTime>11:36 pm</EventTime>
|
149
|
+
<EventDate>April 23, 2015</EventDate>
|
150
|
+
<Event>Shipping Label Created</Event>
|
151
|
+
<EventCity>ARGYLE</EventCity>
|
152
|
+
<EventState>TX</EventState>
|
153
|
+
<EventZIPCode>76226</EventZIPCode>
|
154
|
+
<EventCountry/>
|
155
|
+
<FirmName/>
|
156
|
+
<Name/>
|
157
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
158
|
+
<EventCode>GX</EventCode>
|
159
|
+
</TrackDetail>
|
160
|
+
</TrackInfo>
|
161
|
+
<TrackInfo ID="5555555555555555555555">
|
162
|
+
<Class>First-Class Package Service</Class>
|
163
|
+
<ClassOfMailCode>FC</ClassOfMailCode>
|
164
|
+
<DestinationCity>HANNA CITY</DestinationCity>
|
165
|
+
<DestinationState>IL</DestinationState>
|
166
|
+
<DestinationZip>61536</DestinationZip>
|
167
|
+
<EmailEnabled>true</EmailEnabled>
|
168
|
+
<ExpectedDeliveryDate>April 28, 2015</ExpectedDeliveryDate>
|
169
|
+
<KahalaIndicator>false</KahalaIndicator>
|
170
|
+
<MailTypeCode>DM</MailTypeCode>
|
171
|
+
<MPDATE>2015-04-24 02:08:04.000000</MPDATE>
|
172
|
+
<MPSUFFIX>495865558</MPSUFFIX>
|
173
|
+
<OriginCity>ARGYLE</OriginCity>
|
174
|
+
<OriginState>TX</OriginState>
|
175
|
+
<OriginZip>76226</OriginZip>
|
176
|
+
<PodEnabled>false</PodEnabled>
|
177
|
+
<PredictedDeliveryDate>April 28, 2015</PredictedDeliveryDate>
|
178
|
+
<RestoreEnabled>false</RestoreEnabled>
|
179
|
+
<RramEnabled>false</RramEnabled>
|
180
|
+
<RreEnabled>false</RreEnabled>
|
181
|
+
<Service>USPS Tracking<SUP>&#153;</SUP></Service>
|
182
|
+
<ServiceTypeCode>001</ServiceTypeCode>
|
183
|
+
<Status>Delivered, In/At Mailbox</Status>
|
184
|
+
<StatusCategory>Delivered</StatusCategory>
|
185
|
+
<StatusSummary>Your item was delivered in or at the mailbox at 9:01 am on April 28, 2015 in HANNA CITY, IL 61536.</StatusSummary>
|
186
|
+
<TABLECODE>T</TABLECODE>
|
187
|
+
<TrackSummary>
|
188
|
+
<EventTime>9:01 am</EventTime>
|
189
|
+
<EventDate>April 28, 2015</EventDate>
|
190
|
+
<Event>Delivered, In/At Mailbox</Event>
|
191
|
+
<EventCity>HANNA CITY</EventCity>
|
192
|
+
<EventState>IL</EventState>
|
193
|
+
<EventZIPCode>61536</EventZIPCode>
|
194
|
+
<EventCountry/>
|
195
|
+
<FirmName/>
|
196
|
+
<Name/>
|
197
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
198
|
+
<EventCode>01</EventCode>
|
199
|
+
<DeliveryAttributeCode>01</DeliveryAttributeCode>
|
200
|
+
</TrackSummary>
|
201
|
+
<TrackDetail>
|
202
|
+
<EventTime>11:36 pm</EventTime>
|
203
|
+
<EventDate>April 23, 2015</EventDate>
|
204
|
+
<Event>Shipping Label Created</Event>
|
205
|
+
<EventCity>ARGYLE</EventCity>
|
206
|
+
<EventState>TX</EventState>
|
207
|
+
<EventZIPCode>76226</EventZIPCode>
|
208
|
+
<EventCountry/>
|
209
|
+
<FirmName/>
|
210
|
+
<Name/>
|
211
|
+
<AuthorizedAgent>false</AuthorizedAgent>
|
212
|
+
<EventCode>GX</EventCode>
|
213
|
+
</TrackDetail>
|
214
|
+
</TrackInfo>
|
215
|
+
<TrackInfo ID="9405510ee200828613653750">
|
216
|
+
<Error>
|
217
|
+
<Number>-2147219302</Number>
|
218
|
+
<Description>The Postal Service could not locate the tracking information for your request. Please verify your tracking number and try again later.</Description>
|
219
|
+
<HelpFile/>
|
220
|
+
<HelpContext/>
|
221
|
+
</Error>
|
222
|
+
</TrackInfo>
|
223
|
+
</TrackResponse>
|
data/test/remote/fedex_test.rb
CHANGED
@@ -297,4 +297,68 @@ class RemoteFedExTest < Minitest::Test
|
|
297
297
|
@carrier.find_tracking_info('abc')
|
298
298
|
end
|
299
299
|
end
|
300
|
+
|
301
|
+
def test_cant_obtain_multiple_shipping_labels
|
302
|
+
assert_raises(ActiveShipping::Error,"Multiple packages are not supported yet.") do
|
303
|
+
@carrier.create_shipment(
|
304
|
+
location_fixtures[:beverly_hills_with_name],
|
305
|
+
location_fixtures[:new_york_with_name],
|
306
|
+
[package_fixtures[:wii],package_fixtures[:wii]],
|
307
|
+
:test => true,
|
308
|
+
:reference_number => {
|
309
|
+
:value => "FOO-123",
|
310
|
+
:code => "PO"
|
311
|
+
}
|
312
|
+
)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_obtain_shipping_label_with_single_element_array
|
317
|
+
response = @carrier.create_shipment(
|
318
|
+
location_fixtures[:beverly_hills_with_name],
|
319
|
+
location_fixtures[:new_york_with_name],
|
320
|
+
[package_fixtures[:wii]],
|
321
|
+
:test => true,
|
322
|
+
:reference_number => {
|
323
|
+
:value => "FOO-123",
|
324
|
+
:code => "PO"
|
325
|
+
}
|
326
|
+
)
|
327
|
+
|
328
|
+
assert response.success?
|
329
|
+
refute_empty response.labels
|
330
|
+
refute_empty response.labels.first.img_data
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_obtain_shipping_label
|
334
|
+
response = @carrier.create_shipment(
|
335
|
+
location_fixtures[:beverly_hills_with_name],
|
336
|
+
location_fixtures[:new_york_with_name],
|
337
|
+
package_fixtures[:wii],
|
338
|
+
:test => true,
|
339
|
+
:reference_number => {
|
340
|
+
:value => "FOO-123",
|
341
|
+
:code => "PO"
|
342
|
+
}
|
343
|
+
)
|
344
|
+
|
345
|
+
assert response.success?
|
346
|
+
refute_empty response.labels
|
347
|
+
refute_empty response.labels.first.img_data
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_obtain_shipping_label_with_signature_option
|
351
|
+
packages = package_fixtures.values_at(:wii)
|
352
|
+
packages.each {|p| p.options[:signature_option] = :adult }
|
353
|
+
|
354
|
+
response = @carrier.create_shipment(
|
355
|
+
location_fixtures[:beverly_hills_with_name],
|
356
|
+
location_fixtures[:new_york_with_name],
|
357
|
+
packages,
|
358
|
+
{:test => true}
|
359
|
+
)
|
360
|
+
|
361
|
+
signature_option = response.params["ProcessShipmentReply"]["CompletedShipmentDetail"]["CompletedPackageDetails"]["SignatureOption"]
|
362
|
+
assert_equal FedEx::SIGNATURE_OPTION_CODES[:adult], signature_option
|
363
|
+
end
|
300
364
|
end
|
data/test/test_helper.rb
CHANGED
@@ -112,6 +112,16 @@ module ActiveShipping::Test
|
|
112
112
|
:postal_code => 'K1P 1J1',
|
113
113
|
:phone => '1-613-580-2400',
|
114
114
|
:fax => '1-613-580-2495'),
|
115
|
+
:beverly_hills_with_name => Location.new(
|
116
|
+
:name => 'JP Silvashy',
|
117
|
+
:country => 'US',
|
118
|
+
:state => 'CA',
|
119
|
+
:city => 'Beverly Hills',
|
120
|
+
:address1 => '455 N. Rexford Dr.',
|
121
|
+
:address2 => '3rd Floor',
|
122
|
+
:zip => '90210',
|
123
|
+
:phone => '1-310-285-1013',
|
124
|
+
:fax => '1-310-275-8159'),
|
115
125
|
:beverly_hills => Location.new(
|
116
126
|
:country => 'US',
|
117
127
|
:state => 'CA',
|
@@ -425,4 +425,45 @@ class FedExTest < Minitest::Test
|
|
425
425
|
@carrier.find_tracking_info('abc')
|
426
426
|
end
|
427
427
|
end
|
428
|
+
|
429
|
+
def test_create_shipment
|
430
|
+
confirm_response = xml_fixture('fedex/create_shipment_response')
|
431
|
+
@carrier.stubs(:commit).returns(confirm_response)
|
432
|
+
|
433
|
+
response = @carrier.create_shipment(
|
434
|
+
location_fixtures[:beverly_hills],
|
435
|
+
location_fixtures[:new_york],
|
436
|
+
package_fixtures.values_at(:chocolate_stuff),
|
437
|
+
:test => true
|
438
|
+
)
|
439
|
+
|
440
|
+
# These assertions are to check that the xml fixture is extracted properly.
|
441
|
+
assert_equal 1, response.labels.count
|
442
|
+
assert_equal response.labels.first.tracking_number, "794637052920"
|
443
|
+
assert_equal response.labels.first.img_data.size, 8286
|
444
|
+
end
|
445
|
+
|
446
|
+
def test_create_shipment_signature_option
|
447
|
+
packages = package_fixtures.values_at(:chocolate_stuff)
|
448
|
+
packages.each {|p| p.options[:signature_option] = :indirect }
|
449
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
450
|
+
location_fixtures[:beverly_hills],
|
451
|
+
location_fixtures[:annapolis],
|
452
|
+
packages,
|
453
|
+
:test => true))
|
454
|
+
assert_equal result.search('SpecialServicesRequested/SpecialServiceTypes').text, "SIGNATURE_OPTION"
|
455
|
+
assert_equal result.search('SpecialServicesRequested/SignatureOptionDetail').text.strip, "INDIRECT"
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_create_shipment_reference
|
459
|
+
packages = package_fixtures.values_at(:wii)
|
460
|
+
packages.each {|p| p.options[:reference_numbers] = [{:value => "FOO-123"}] }
|
461
|
+
|
462
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
463
|
+
location_fixtures[:beverly_hills],
|
464
|
+
location_fixtures[:annapolis],
|
465
|
+
packages,
|
466
|
+
:test => true))
|
467
|
+
assert_equal result.search('RequestedPackageLineItems/CustomerReferences/Value').text, "FOO-123"
|
468
|
+
end
|
428
469
|
end
|
@@ -266,12 +266,12 @@ class UPSTest < Minitest::Test
|
|
266
266
|
|
267
267
|
# These tracking numbers are part of the fixture data. What we're trying
|
268
268
|
# to verify is that the data in the XML is extracted properly.
|
269
|
-
tracking = response.labels.map { |label| label
|
269
|
+
tracking = response.labels.map { |label| label.tracking_number }
|
270
270
|
assert_includes tracking, "1ZA03R691594829862"
|
271
271
|
assert_includes tracking, "1ZA03R691592132475"
|
272
272
|
assert_includes tracking, "1ZA03R691590470881"
|
273
273
|
|
274
|
-
pictures = response.labels.map { |label| label
|
274
|
+
pictures = response.labels.map { |label| label.img_data }
|
275
275
|
refute_includes pictures, nil
|
276
276
|
end
|
277
277
|
|
@@ -299,10 +299,10 @@ class UPSTest < Minitest::Test
|
|
299
299
|
|
300
300
|
# These tracking numbers are part of the fixture data. What we're trying
|
301
301
|
# to verify is that the data in the XML is extracted properly.
|
302
|
-
tracking = response.labels.map { |label| label
|
302
|
+
tracking = response.labels.map { |label| label.tracking_number }
|
303
303
|
assert_includes tracking, "1ZA03R691591538440"
|
304
304
|
|
305
|
-
pictures = response.labels.map { |label| label
|
305
|
+
pictures = response.labels.map { |label| label.img_data }
|
306
306
|
refute_includes pictures, nil
|
307
307
|
end
|
308
308
|
|
@@ -6,7 +6,13 @@ class USPSTest < Minitest::Test
|
|
6
6
|
def setup
|
7
7
|
@carrier = USPS.new(:login => 'login')
|
8
8
|
@tracking_response = xml_fixture('usps/tracking_response')
|
9
|
+
@batch_tracking_response = xml_fixture('usps/tracking_response_batch')
|
9
10
|
@tracking_response_failure = xml_fixture('usps/tracking_response_failure')
|
11
|
+
@tracking_infos_array = [
|
12
|
+
{number: '9102901000462189604217', :destination_zip => '12345', :mailing_date => Date.new(2010,1,30)},
|
13
|
+
{number: '5555555555555555555555'},
|
14
|
+
{number: '9405510ee200828613653750'}
|
15
|
+
]
|
10
16
|
end
|
11
17
|
|
12
18
|
def test_tracking_request_should_create_correct_xml
|
@@ -159,6 +165,45 @@ class USPSTest < Minitest::Test
|
|
159
165
|
assert_equal true, response.delivered?
|
160
166
|
end
|
161
167
|
|
168
|
+
def test_tracking_batch_request_should_create_correct_xml
|
169
|
+
@carrier.expects(:commit).with(:track, xml_fixture('usps/tracking_request_batch'),false).returns(@batch_tracking_response)
|
170
|
+
@carrier.batch_find_tracking_info(@tracking_infos_array)
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_batch_find_tracking_info_should_return_a_tracking_response_array
|
174
|
+
@carrier.expects(:commit).returns(@batch_tracking_response)
|
175
|
+
responses = @carrier.batch_find_tracking_info(@tracking_infos_array, :test => true)
|
176
|
+
assert_equal 3, responses.length
|
177
|
+
assert responses.all? { |x| x.instance_of? ActiveShipping::TrackingResponse}
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_batch_find_tracking_info_should_have_correct_data
|
181
|
+
@carrier.expects(:commit).returns(@batch_tracking_response)
|
182
|
+
responses = @carrier.batch_find_tracking_info(@tracking_infos_array, :test => true)
|
183
|
+
response = responses[0]
|
184
|
+
assert_equal ["GX", "OA", "10", "EF", "10", "EF", "07", "PC", "OF", "01"], response.shipment_events.map(&:type_code)
|
185
|
+
assert_equal Time.parse('April 28, 2015'), response.scheduled_delivery_date
|
186
|
+
assert_equal Time.parse('2015-04-28 09:01:00 UTC'), response.actual_delivery_date
|
187
|
+
assert_equal '9102901000462189604217', response.tracking_number
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_batch_find_tracking_info_should_tolerate_failure
|
191
|
+
@carrier.expects(:commit).returns(@batch_tracking_response)
|
192
|
+
responses = @carrier.batch_find_tracking_info(@tracking_infos_array, :test => true)
|
193
|
+
response = responses[2]
|
194
|
+
refute response.success?
|
195
|
+
assert_equal "The Postal Service could not locate the tracking information for your request. Please verify your tracking number and try again later.",
|
196
|
+
response.message
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_batch_find_tracking_info_should_handle_not_found_error
|
200
|
+
@carrier.expects(:commit).returns(xml_fixture('usps/tracking_response_test_error'))
|
201
|
+
e = assert_raises ResponseError do
|
202
|
+
@carrier.find_tracking_info(@batch_tracking_response, :test => true)
|
203
|
+
end
|
204
|
+
assert_equal "This Information has not been included in this Test Server.", e.message
|
205
|
+
end
|
206
|
+
|
162
207
|
def test_size_codes
|
163
208
|
assert_equal 'REGULAR', USPS.size_code_for(Package.new(2, [1, 12, 1], :units => :imperial))
|
164
209
|
assert_equal 'LARGE', USPS.size_code_for(Package.new(2, [12.1, 1, 1], :units => :imperial))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James MacAulay
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-05-
|
14
|
+
date: 2015-05-29 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: quantified
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- lib/active_shipping/delivery_date_estimate.rb
|
186
186
|
- lib/active_shipping/delivery_date_estimates_response.rb
|
187
187
|
- lib/active_shipping/errors.rb
|
188
|
+
- lib/active_shipping/label.rb
|
188
189
|
- lib/active_shipping/label_response.rb
|
189
190
|
- lib/active_shipping/location.rb
|
190
191
|
- lib/active_shipping/package.rb
|
@@ -246,6 +247,7 @@ files:
|
|
246
247
|
- test/fixtures/xml/correios/clothes_response.xml
|
247
248
|
- test/fixtures/xml/correios/poster_response.xml
|
248
249
|
- test/fixtures/xml/correios/shoes_response.xml
|
250
|
+
- test/fixtures/xml/fedex/create_shipment_response.xml
|
249
251
|
- test/fixtures/xml/fedex/freight_rate_request.xml
|
250
252
|
- test/fixtures/xml/fedex/freight_rate_response.xml
|
251
253
|
- test/fixtures/xml/fedex/invalid_fedex_reply.xml
|
@@ -321,8 +323,10 @@ files:
|
|
321
323
|
- test/fixtures/xml/usps/first_class_packages_without_mail_type_response.xml
|
322
324
|
- test/fixtures/xml/usps/invalid_xml_tracking_response_error.xml
|
323
325
|
- test/fixtures/xml/usps/tracking_request.xml
|
326
|
+
- test/fixtures/xml/usps/tracking_request_batch.xml
|
324
327
|
- test/fixtures/xml/usps/tracking_response.xml
|
325
328
|
- test/fixtures/xml/usps/tracking_response_alt.xml
|
329
|
+
- test/fixtures/xml/usps/tracking_response_batch.xml
|
326
330
|
- test/fixtures/xml/usps/tracking_response_failure.xml
|
327
331
|
- test/fixtures/xml/usps/tracking_response_not_available.xml
|
328
332
|
- test/fixtures/xml/usps/tracking_response_test_error.xml
|
@@ -356,7 +360,6 @@ files:
|
|
356
360
|
- test/unit/carriers/ups_test.rb
|
357
361
|
- test/unit/carriers/usps_test.rb
|
358
362
|
- test/unit/carriers_test.rb
|
359
|
-
- test/unit/label_response_test.rb
|
360
363
|
- test/unit/location_test.rb
|
361
364
|
- test/unit/package_test.rb
|
362
365
|
- test/unit/rate_estimate_test.rb
|
@@ -434,6 +437,7 @@ test_files:
|
|
434
437
|
- test/fixtures/xml/correios/clothes_response.xml
|
435
438
|
- test/fixtures/xml/correios/poster_response.xml
|
436
439
|
- test/fixtures/xml/correios/shoes_response.xml
|
440
|
+
- test/fixtures/xml/fedex/create_shipment_response.xml
|
437
441
|
- test/fixtures/xml/fedex/freight_rate_request.xml
|
438
442
|
- test/fixtures/xml/fedex/freight_rate_response.xml
|
439
443
|
- test/fixtures/xml/fedex/invalid_fedex_reply.xml
|
@@ -509,8 +513,10 @@ test_files:
|
|
509
513
|
- test/fixtures/xml/usps/first_class_packages_without_mail_type_response.xml
|
510
514
|
- test/fixtures/xml/usps/invalid_xml_tracking_response_error.xml
|
511
515
|
- test/fixtures/xml/usps/tracking_request.xml
|
516
|
+
- test/fixtures/xml/usps/tracking_request_batch.xml
|
512
517
|
- test/fixtures/xml/usps/tracking_response.xml
|
513
518
|
- test/fixtures/xml/usps/tracking_response_alt.xml
|
519
|
+
- test/fixtures/xml/usps/tracking_response_batch.xml
|
514
520
|
- test/fixtures/xml/usps/tracking_response_failure.xml
|
515
521
|
- test/fixtures/xml/usps/tracking_response_not_available.xml
|
516
522
|
- test/fixtures/xml/usps/tracking_response_test_error.xml
|
@@ -544,7 +550,6 @@ test_files:
|
|
544
550
|
- test/unit/carriers/ups_test.rb
|
545
551
|
- test/unit/carriers/usps_test.rb
|
546
552
|
- test/unit/carriers_test.rb
|
547
|
-
- test/unit/label_response_test.rb
|
548
553
|
- test/unit/location_test.rb
|
549
554
|
- test/unit/package_test.rb
|
550
555
|
- test/unit/rate_estimate_test.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class LabelResponseTest < Minitest::Test
|
4
|
-
include ActiveShipping::Test::Fixtures
|
5
|
-
|
6
|
-
def test_build_label_from_xml_response
|
7
|
-
str = xml_fixture('ups/shipment_accept_response')
|
8
|
-
mapping = Hash.from_xml(str).values.first
|
9
|
-
response = LabelResponse.new(true, nil, mapping)
|
10
|
-
|
11
|
-
assert_equal 1, response.labels.count
|
12
|
-
assert_equal '1ZA03R691591538440', response.labels.first[:tracking_number]
|
13
|
-
assert response.labels.first[:image]
|
14
|
-
end
|
15
|
-
end
|