omniship 0.3.2.2 → 0.4.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 +7 -0
- data/lib/omniship.rb +13 -12
- data/lib/omniship/address.rb +36 -36
- data/lib/omniship/carriers/fedex.rb +343 -188
- data/lib/omniship/carriers/ups.rb +156 -95
- data/lib/omniship/notification.rb +18 -0
- data/lib/omniship/response.rb +7 -7
- data/lib/omniship/ship_response.rb +12 -0
- data/lib/omniship/version.rb +2 -2
- data/lib/rails/generators/omniship/setup/setup_generator.rb +19 -0
- data/lib/rails/generators/omniship/setup/templates/initializer.rb +2 -0
- data/lib/rails/generators/omniship/setup/templates/omniship.yml +33 -0
- metadata +58 -73
@@ -15,7 +15,8 @@ module Omniship
|
|
15
15
|
:shipconfirm => 'ups.app/xml/ShipConfirm',
|
16
16
|
:shipaccept => 'ups.app/xml/ShipAccept',
|
17
17
|
:shipvoid => 'ups.app/xml/Void',
|
18
|
-
:valid_address => 'ups.app/xml/
|
18
|
+
:valid_address => 'ups.app/xml/AV',
|
19
|
+
:valid_address_street => 'ups.app/xml/XAV'
|
19
20
|
}
|
20
21
|
|
21
22
|
PICKUP_CODES = HashWithIndifferentAccess.new({
|
@@ -100,63 +101,71 @@ module Omniship
|
|
100
101
|
|
101
102
|
def find_rates(origin, destination, packages, options={})
|
102
103
|
origin, destination = upsified_location(origin), upsified_location(destination)
|
103
|
-
options
|
104
|
-
options[:test]
|
105
|
-
packages
|
106
|
-
access_request
|
107
|
-
rate_request
|
108
|
-
response
|
104
|
+
options = @options.merge(options)
|
105
|
+
options[:test] = options[:test].nil? ? false : options[:test]
|
106
|
+
packages = Array(packages)
|
107
|
+
access_request = build_access_request
|
108
|
+
rate_request = build_rate_request(origin, destination, packages, options)
|
109
|
+
response = commit(:rates, save_request(access_request.gsub("\n", "") + rate_request.gsub("\n", "")), options[:test])
|
109
110
|
parse_rate_response(origin, destination, packages, response, options)
|
110
111
|
end
|
111
112
|
|
112
113
|
def find_tracking_info(tracking_number, options={})
|
113
|
-
options
|
114
|
-
options[:test]
|
115
|
-
access_request
|
114
|
+
options = @options.update(options)
|
115
|
+
options[:test] = options[:test].nil? ? false : options[:test]
|
116
|
+
access_request = build_access_request
|
116
117
|
tracking_request = build_tracking_request(tracking_number, options)
|
117
|
-
response
|
118
|
-
parse_tracking_response(response, options)
|
118
|
+
response = commit(:track, save_request(access_request.gsub("\n", "") + tracking_request.gsub("\n", "")), options[:test])
|
119
|
+
# parse_tracking_response(response, options)
|
119
120
|
end
|
120
121
|
|
121
122
|
# Creating shipping functionality for UPS
|
122
123
|
def create_shipment(origin, destination, packages, options={})
|
123
|
-
@options
|
124
|
-
origin, destination
|
125
|
-
options
|
126
|
-
options[:test]
|
127
|
-
packages
|
128
|
-
access_request
|
124
|
+
@options = @options.merge(options)
|
125
|
+
origin, destination = upsified_location(origin), upsified_location(destination)
|
126
|
+
options = @options.merge(options)
|
127
|
+
options[:test] = options[:test].nil? ? true : options[:test]
|
128
|
+
packages = Array(packages)
|
129
|
+
access_request = build_access_request
|
129
130
|
ship_confirm_request = build_ship_confirm(origin, destination, packages, options)
|
130
|
-
response
|
131
|
+
response = commit(:shipconfirm, save_request(access_request.gsub("\n", "") + ship_confirm_request.gsub("\n", "")), options[:test])
|
131
132
|
parse_ship_confirm_response(origin, destination, packages, response, options)
|
132
133
|
end
|
133
134
|
|
134
135
|
def accept_shipment(digest, options={})
|
135
|
-
options[:test]
|
136
|
-
access_request
|
136
|
+
options[:test] = options[:test].nil? ? true : options[:test]
|
137
|
+
access_request = build_access_request
|
137
138
|
ship_accept_request = build_ship_accept(digest)
|
138
|
-
response
|
139
|
+
response = commit(:shipaccept, save_request(access_request.gsub("\n", "") + ship_accept_request.gsub("\n", "")), options[:test])
|
139
140
|
parse_ship_accept_response(response, options)
|
140
141
|
end
|
141
142
|
|
142
|
-
def void_shipment(ups_shipment_id,tracking_number, options={})
|
143
|
-
@options
|
144
|
-
options
|
145
|
-
options[:test]
|
146
|
-
access_request
|
143
|
+
def void_shipment(ups_shipment_id, tracking_number, options={})
|
144
|
+
@options = @options.merge(options)
|
145
|
+
options = @options.merge(options)
|
146
|
+
options[:test] = options[:test].nil? ? true : options[:test]
|
147
|
+
access_request = build_access_request
|
147
148
|
ship_void_request = build_void_request(ups_shipment_id,tracking_number)
|
148
|
-
response
|
149
|
+
response = commit(:shipvoid, save_request(access_request.gsub("\n", "") + ship_void_request.gsub("\n", "")), options[:test])
|
149
150
|
parse_ship_void_response(response, options)
|
150
151
|
end
|
151
|
-
|
152
|
-
def validate_address(
|
152
|
+
|
153
|
+
def validate_address(city, state, zip_code, country_code, options={})
|
154
|
+
@options = @options.merge(options)
|
155
|
+
access_request = build_access_request
|
156
|
+
validate_address_request = build_valid_address_request(city,state,zip_code,country_code)
|
157
|
+
options[:test] = options[:test].nil? ? true : options[:test]
|
158
|
+
response = commit(:valid_address, save_request(access_request.gsub("\n", "") + validate_address_request.gsub("\n", "")), options[:test])
|
159
|
+
parse_ship_valid_address(response)
|
160
|
+
end
|
161
|
+
|
162
|
+
def validate_address_street(address, city, state, zip_code, country_code, options={})
|
153
163
|
@options = @options.merge(options)
|
154
164
|
access_request = build_access_request
|
155
|
-
|
165
|
+
validate_address_street_request = build_valid_address_street_request(address,city,state,zip_code,country_code)
|
156
166
|
options[:test] = options[:test].nil? ? true : options[:test]
|
157
|
-
response = commit(:
|
158
|
-
|
159
|
-
parse_response
|
167
|
+
response = commit(:valid_address_street, save_request(access_request.gsub("\n", "") + validate_address_street_request.gsub("\n", "")), options[:test])
|
168
|
+
parse_ship_valid_address_street(response)
|
160
169
|
end
|
161
170
|
|
162
171
|
protected
|
@@ -172,7 +181,7 @@ module Omniship
|
|
172
181
|
location
|
173
182
|
end
|
174
183
|
end
|
175
|
-
|
184
|
+
|
176
185
|
|
177
186
|
def build_access_request
|
178
187
|
builder = Nokogiri::XML::Builder.new do |xml|
|
@@ -180,17 +189,12 @@ module Omniship
|
|
180
189
|
xml.AccessLicenseNumber @options[:key].nil? ? @config['ups']['key'] : @options[:key]
|
181
190
|
xml.UserId @options[:login].nil? ? @config['ups']['username'] : @options[:login]
|
182
191
|
xml.Password @options[:password].nil? ? @config['ups']['password'] : @options[:password]
|
183
|
-
|
184
|
-
|
185
|
-
xml.AccessLicenseNumber @config['ups']['key'] unless @options[:key]
|
186
|
-
xml.UserId @config['ups']['username'] unless @options[:login]
|
187
|
-
xml.Password @config['ups']['password'] unless @options[:password]
|
188
192
|
}
|
189
193
|
end
|
190
194
|
builder.to_xml
|
191
195
|
end
|
192
196
|
|
193
|
-
# Build the ship_confirm XML request
|
197
|
+
# Build the ship_confirm XML request
|
194
198
|
def build_ship_confirm(origin, destination, packages, options={})
|
195
199
|
|
196
200
|
#Return Service types:
|
@@ -206,7 +210,7 @@ module Omniship
|
|
206
210
|
xml.ShipmentConfirmRequest {
|
207
211
|
xml.Request {
|
208
212
|
xml.RequestAction 'ShipConfirm'
|
209
|
-
xml.RequestOption 'validate'
|
213
|
+
xml.RequestOption options[:nonvalidate] ? 'nonvalidate' : 'validate'
|
210
214
|
}
|
211
215
|
xml.Shipment {
|
212
216
|
build_location_node(['Shipper'], (options[:shipper] || origin), options, xml)
|
@@ -270,6 +274,17 @@ module Omniship
|
|
270
274
|
}
|
271
275
|
end
|
272
276
|
}
|
277
|
+
if package.options[:references].present?
|
278
|
+
package.options[:references].each do |reference|
|
279
|
+
xml.ReferenceNumber {
|
280
|
+
xml.Code reference[:code]
|
281
|
+
xml.Value reference[:value]
|
282
|
+
if reference[:barcode]
|
283
|
+
xml.BarCodeIndicator
|
284
|
+
end
|
285
|
+
}
|
286
|
+
end
|
287
|
+
end
|
273
288
|
}
|
274
289
|
end
|
275
290
|
xml.LabelSpecification {
|
@@ -312,23 +327,40 @@ module Omniship
|
|
312
327
|
end
|
313
328
|
builder.to_xml
|
314
329
|
end
|
315
|
-
|
316
|
-
def
|
330
|
+
|
331
|
+
def build_valid_address_street_request(address,city,state,zip_code,country_code)
|
317
332
|
builder = Nokogiri::XML::Builder.new do |xml|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
xml.
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
333
|
+
xml.AddressValidationRequest {
|
334
|
+
xml.Request {
|
335
|
+
xml.RequestAction "XAV"
|
336
|
+
}
|
337
|
+
|
338
|
+
xml.AddressKeyFormat {
|
339
|
+
xml.AddressLine address
|
340
|
+
xml.PoliticalDivision2 city
|
341
|
+
xml.PoliticalDivision1 state
|
342
|
+
xml.PostcodePrimaryLow zip_code
|
343
|
+
xml.CountryCode country_code
|
344
|
+
}
|
345
|
+
}
|
346
|
+
end
|
347
|
+
builder.to_xml
|
348
|
+
end
|
349
|
+
|
350
|
+
def build_valid_address_request(city,state,zip_code,country_code)
|
351
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
352
|
+
xml.AddressValidationRequest {
|
353
|
+
xml.Request{
|
354
|
+
xml.RequestAction 'AV'
|
355
|
+
}
|
356
|
+
|
357
|
+
xml.Address{
|
358
|
+
xml.City city
|
359
|
+
xml.StateProvinceCode state
|
360
|
+
xml.CountryCode country_code
|
361
|
+
xml.PostalCode zip_code
|
331
362
|
}
|
363
|
+
}
|
332
364
|
end
|
333
365
|
builder.to_xml
|
334
366
|
end
|
@@ -414,11 +446,14 @@ module Omniship
|
|
414
446
|
builder = Nokogiri::XML::Builder.new do |xml|
|
415
447
|
xml.TrackRequest {
|
416
448
|
xml.Request {
|
417
|
-
xml.
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
xml.
|
449
|
+
xml.TransactionReference {
|
450
|
+
}
|
451
|
+
xml.RequestAction "Track"
|
452
|
+
}
|
453
|
+
xml.TrackingNumber tracking_number.to_s
|
454
|
+
xml.ShipmentType {
|
455
|
+
xml.Code "01"
|
456
|
+
}
|
422
457
|
}
|
423
458
|
end
|
424
459
|
builder.to_xml
|
@@ -480,47 +515,47 @@ module Omniship
|
|
480
515
|
RateResponse.new(success, message, Hash.from_xml(response).values.first, :rates => rate_estimates, :xml => response, :request => last_request)
|
481
516
|
end
|
482
517
|
|
483
|
-
def parse_tracking_response(response, options={})
|
518
|
+
def parse_tracking_response(response, options={})
|
484
519
|
xml = Nokogiri::XML(response)
|
485
520
|
success = response_success?(xml)
|
486
521
|
message = response_message(xml)
|
487
|
-
|
522
|
+
|
488
523
|
puts "response :" + xml.to_s
|
489
|
-
|
524
|
+
|
490
525
|
if success
|
491
526
|
tracking_number, origin, destination = nil
|
492
527
|
shipment_details = Hash.new
|
493
|
-
|
494
|
-
tracking_number = xml.xpath('/*/Shipment/Package/TrackingNumber').text
|
528
|
+
|
529
|
+
tracking_number = xml.xpath('/*/Shipment/Package/TrackingNumber').text
|
495
530
|
shipment_details[:tracking_number] = tracking_number
|
496
|
-
|
497
|
-
estimated_delivery_date = xml.xpath('/*/Shipment/ScheduledDeliveryDate').text
|
498
|
-
if !estimated_delivery_date.blank?
|
531
|
+
|
532
|
+
estimated_delivery_date = xml.xpath('/*/Shipment/ScheduledDeliveryDate').text
|
533
|
+
if !estimated_delivery_date.blank?
|
499
534
|
estimated_delivery_date = Date.strptime(estimated_delivery_date,'%Y%m%d')
|
500
535
|
shipment_details[:estimated_delivery_date] = estimated_delivery_date
|
501
536
|
else
|
502
|
-
reschedule_delivery_date = xml.xpath('/*/Shipment/Package/RescheduledDeliveryDate').text
|
503
|
-
if !reschedule_delivery_date.blank?
|
537
|
+
reschedule_delivery_date = xml.xpath('/*/Shipment/Package/RescheduledDeliveryDate').text
|
538
|
+
if !reschedule_delivery_date.blank?
|
504
539
|
reschedule_delivery_date = Date.strptime(reschedule_delivery_date,'%Y%m%d')
|
505
540
|
shipment_details[:estimated_delivery_date] = reschedule_delivery_date
|
506
541
|
end
|
507
542
|
end
|
508
|
-
|
543
|
+
|
509
544
|
puts 'tracking_number: ' + tracking_number
|
510
|
-
puts 'estimated_delivery_date: ' + estimated_delivery_date.to_s
|
511
|
-
|
545
|
+
puts 'estimated_delivery_date: ' + estimated_delivery_date.to_s
|
546
|
+
|
512
547
|
activities = []
|
513
548
|
xml.xpath('/*/Shipment/Package/Activity').each do |activity|
|
514
|
-
status_code = activity.xpath('Status/StatusCode').text
|
515
|
-
status_dsc = activity.xpath('Status/StatusType/Description').text
|
516
|
-
date = activity.xpath('Date').text
|
517
|
-
time = activity.xpath('Time').text
|
549
|
+
status_code = activity.xpath('Status/StatusCode').text
|
550
|
+
status_dsc = activity.xpath('Status/StatusType/Description').text
|
551
|
+
date = activity.xpath('Date').text
|
552
|
+
time = activity.xpath('Time').text
|
518
553
|
hour, minute, second = time.scan(/\d{2}/)
|
519
554
|
year, month, day = date[0..3], date[4..5], date[6..7]
|
520
|
-
date_time = Time.utc(year, month, day, hour, minute, second)
|
521
|
-
location = activity.xpath('ActivityLocation/Address/City').text + ' ' + activity.xpath('ActivityLocation/Address/StateProvinceCode').text + ' ' + activity.xpath('ActivityLocation/Address/CountryCode').text
|
555
|
+
date_time = Time.utc(year, month, day, hour, minute, second)
|
556
|
+
location = activity.xpath('ActivityLocation/Address/City').text + ' ' + activity.xpath('ActivityLocation/Address/StateProvinceCode').text + ' ' + activity.xpath('ActivityLocation/Address/CountryCode').text
|
522
557
|
activities << {:status_code => status_code, :status_dsc => status_dsc, :date => date_time, :location => location}
|
523
|
-
end
|
558
|
+
end
|
524
559
|
shipment_details[:activities] = activities
|
525
560
|
|
526
561
|
#first_shipment = xml.gelements['/*/Shipment']
|
@@ -545,9 +580,9 @@ module Omniship
|
|
545
580
|
# location = location_from_address_node(activity.elements['ActivityLocation/Address'])
|
546
581
|
# ShipmentEvent.new(description, zoneless_time, location)
|
547
582
|
# end
|
548
|
-
#
|
583
|
+
#
|
549
584
|
# shipment_events = shipment_events.sort_by(&:time)
|
550
|
-
#
|
585
|
+
#
|
551
586
|
# if origin
|
552
587
|
# first_event = shipment_events[0]
|
553
588
|
# same_country = origin.country_code(:alpha2) == first_event.location.country_code(:alpha2)
|
@@ -633,26 +668,52 @@ module Omniship
|
|
633
668
|
|
634
669
|
return @void
|
635
670
|
end
|
636
|
-
|
671
|
+
|
637
672
|
def parse_ship_valid_address(response, options={})
|
638
673
|
xml = Nokogiri::XML(response)
|
674
|
+
puts xml
|
639
675
|
success = response_success?(xml)
|
640
|
-
|
676
|
+
response_text = Array.new
|
641
677
|
if success
|
642
|
-
addresses = xml.xpath('/*/
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
678
|
+
addresses = xml.xpath('/*/AddressValidationResult').each do |address_data|
|
679
|
+
response_text = Hash.new
|
680
|
+
response_text[:rank] = address_data.xpath('Rank').text
|
681
|
+
response_text[:quality] = address_data.xpath('Quality').text
|
682
|
+
response_text[:city] = address_data.xpath('Address/City').text
|
683
|
+
response_text[:state] = address_data.xpath('Address/StateProvinceCode').text
|
684
|
+
response_text[:postal_code_low] = address_data.xpath('PostalCodeLowEnd').text
|
685
|
+
response_text[:postal_code_high] = address_data.xpath('PostalCodeHighEnd').text
|
650
686
|
end
|
651
687
|
else
|
652
688
|
return "Address validation failed!"
|
653
689
|
end
|
690
|
+
return response_text
|
691
|
+
end
|
654
692
|
|
655
|
-
|
693
|
+
def parse_ship_valid_address_street(response, options={})
|
694
|
+
n = 1
|
695
|
+
xml = Nokogiri::XML(response)
|
696
|
+
puts xml
|
697
|
+
success = response_success?(xml)
|
698
|
+
response_text = Array.new
|
699
|
+
if success
|
700
|
+
addresses = xml.xpath('/*/AddressKeyFormat').each do |address_data|
|
701
|
+
response_text = Hash.new
|
702
|
+
address_data.xpath('AddressLine').each do |address_line|
|
703
|
+
response_text["address_#{n}".to_sym] = address_line.text
|
704
|
+
n += 1
|
705
|
+
end
|
706
|
+
response_text[:region] = address_data.xpath('Region').text
|
707
|
+
response_text[:city] = address_data.xpath('PoliticalDivision2').text
|
708
|
+
response_text[:state] = address_data.xpath('PoliticalDivision1').text
|
709
|
+
response_text[:postal_code] = address_data.xpath('PostcodePrimaryLow').text
|
710
|
+
response_text[:postal_code_extended] = address_data.xpath('PostcodeExtendedLow').text
|
711
|
+
response_text[:country_code] = address_data.xpath("CountryCode").text
|
712
|
+
end
|
713
|
+
else
|
714
|
+
return "Address validation failed!"
|
715
|
+
end
|
716
|
+
return response_text
|
656
717
|
end
|
657
718
|
|
658
719
|
def location_from_address_node(address)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Omniship #:nodoc:
|
2
|
+
class Notification
|
3
|
+
attr_reader :options
|
4
|
+
attr_reader :email
|
5
|
+
attr_reader :format
|
6
|
+
attr_reader :language
|
7
|
+
attr_reader :locale_code
|
8
|
+
|
9
|
+
alias_method :email_address, :email
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@email = options[:email]
|
13
|
+
@format = options[:format]
|
14
|
+
@language = options[:language]
|
15
|
+
@locale_code = options[:locale_code]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/omniship/response.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Omniship #:nodoc:
|
2
2
|
class Error < StandardError
|
3
3
|
end
|
4
|
-
|
4
|
+
|
5
5
|
class ResponseError < Error
|
6
6
|
attr_reader :response
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(response = nil)
|
9
9
|
if response.is_a? Response
|
10
10
|
super(response.message)
|
@@ -12,17 +12,17 @@ module Omniship #:nodoc:
|
|
12
12
|
else
|
13
13
|
super(response)
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
class Response
|
19
|
-
|
19
|
+
|
20
20
|
attr_reader :params
|
21
21
|
attr_reader :message
|
22
22
|
attr_reader :test
|
23
23
|
attr_reader :xml
|
24
24
|
attr_reader :request
|
25
|
-
|
25
|
+
|
26
26
|
def initialize(success, message, params = {}, options = {})
|
27
27
|
@success, @message, @params = success, message, params.stringify_keys
|
28
28
|
@test = options[:test] || false
|
@@ -30,7 +30,7 @@ module Omniship #:nodoc:
|
|
30
30
|
@request = options[:request]
|
31
31
|
raise ResponseError.new(self) unless success
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def success?
|
35
35
|
@success ? true : false
|
36
36
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Omniship #:nodoc:
|
2
|
+
class ShipResponse < Response
|
3
|
+
attr_reader :tracking_number
|
4
|
+
attr_reader :label_encoded
|
5
|
+
|
6
|
+
def initialize(success, message, params = {}, options = {})
|
7
|
+
@tracking_number = params[:tracking_number]
|
8
|
+
@label_encoded = params[:label_encoded]
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|