active_shipping 1.1.3 → 1.2.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.
- 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
|