simple_shipping 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.metrics +6 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.simplecov +43 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +201 -0
- data/LICENSE.txt +21 -0
- data/README.markdown +207 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/coverage/.resultset.json +1579 -0
- data/lib/colorized_text.rb +34 -0
- data/lib/simple_shipping.rb +27 -0
- data/lib/simple_shipping/abstract.rb +11 -0
- data/lib/simple_shipping/abstract/builder.rb +47 -0
- data/lib/simple_shipping/abstract/client.rb +111 -0
- data/lib/simple_shipping/abstract/model.rb +40 -0
- data/lib/simple_shipping/abstract/request.rb +27 -0
- data/lib/simple_shipping/abstract/response.rb +26 -0
- data/lib/simple_shipping/address.rb +22 -0
- data/lib/simple_shipping/contact.rb +24 -0
- data/lib/simple_shipping/demo.rb +9 -0
- data/lib/simple_shipping/demo/base.rb +71 -0
- data/lib/simple_shipping/demo/fedex.rb +46 -0
- data/lib/simple_shipping/demo/ups.rb +68 -0
- data/lib/simple_shipping/exceptions.rb +40 -0
- data/lib/simple_shipping/fedex.rb +14 -0
- data/lib/simple_shipping/fedex/client.rb +41 -0
- data/lib/simple_shipping/fedex/package_builder.rb +24 -0
- data/lib/simple_shipping/fedex/party_builder.rb +50 -0
- data/lib/simple_shipping/fedex/request.rb +54 -0
- data/lib/simple_shipping/fedex/response.rb +5 -0
- data/lib/simple_shipping/fedex/shipment_builder.rb +123 -0
- data/lib/simple_shipping/fedex/shipment_request.rb +14 -0
- data/lib/simple_shipping/fedex/shipment_response.rb +12 -0
- data/lib/simple_shipping/package.rb +43 -0
- data/lib/simple_shipping/party.rb +21 -0
- data/lib/simple_shipping/shipment.rb +42 -0
- data/lib/simple_shipping/ups.rb +24 -0
- data/lib/simple_shipping/ups/client.rb +46 -0
- data/lib/simple_shipping/ups/package_builder.rb +101 -0
- data/lib/simple_shipping/ups/party_builder.rb +38 -0
- data/lib/simple_shipping/ups/request.rb +27 -0
- data/lib/simple_shipping/ups/response.rb +63 -0
- data/lib/simple_shipping/ups/ship_accept_request.rb +21 -0
- data/lib/simple_shipping/ups/ship_accept_response.rb +6 -0
- data/lib/simple_shipping/ups/ship_client.rb +70 -0
- data/lib/simple_shipping/ups/ship_confirm_request.rb +22 -0
- data/lib/simple_shipping/ups/ship_confirm_response.rb +6 -0
- data/lib/simple_shipping/ups/shipment_builder.rb +66 -0
- data/lib/simple_shipping/ups/shipment_request.rb +22 -0
- data/lib/simple_shipping/ups/shipment_response.rb +6 -0
- data/lib/simple_shipping/ups/void_client.rb +50 -0
- data/lib/simple_shipping/ups/void_request.rb +42 -0
- data/lib/simple_shipping/ups/void_response.rb +6 -0
- data/lib/tasks/demo.rake +58 -0
- data/script/ups_certification.rb +140 -0
- data/simple_shipping.gemspec +168 -0
- data/spec/fixtures/fedex_shipment_request.soap.xml.erb +85 -0
- data/spec/fixtures/fedex_shipment_response.soap.xml.erb +182 -0
- data/spec/fixtures/ups_shipment_request.soap.xml.erb +88 -0
- data/spec/fixtures/ups_shipment_response.soap.xml.erb +58 -0
- data/spec/fixtures/ups_shipment_response_with_faked_label_data.soap.xml.erb +54 -0
- data/spec/fixtures/ups_void_request.soap.xml.erb +29 -0
- data/spec/fixtures/ups_void_response.soap.xml.erb +21 -0
- data/spec/lib/simple_shipping/address_spec.rb +19 -0
- data/spec/lib/simple_shipping/contact_spec.rb +28 -0
- data/spec/lib/simple_shipping/exceptions_spec.rb +58 -0
- data/spec/lib/simple_shipping/fedex/package_builder_spec.rb +5 -0
- data/spec/lib/simple_shipping/fedex/party_builder_spec.rb +5 -0
- data/spec/lib/simple_shipping/fedex/response/shipment_reponse_spec.rb +5 -0
- data/spec/lib/simple_shipping/fedex/response_spec.rb +5 -0
- data/spec/lib/simple_shipping/fedex/shipment_builder_spec.rb +23 -0
- data/spec/lib/simple_shipping/package_spec.rb +32 -0
- data/spec/lib/simple_shipping/party_spec.rb +18 -0
- data/spec/lib/simple_shipping/shipment_spec.rb +35 -0
- data/spec/lib/simple_shipping/ups/package_builder_spec.rb +26 -0
- data/spec/lib/simple_shipping/ups/party_builder_spec.rb +47 -0
- data/spec/lib/simple_shipping/ups/response/shipment_response_spec.rb +5 -0
- data/spec/lib/simple_shipping/ups/response_spec.rb +33 -0
- data/spec/lib/simple_shipping/ups/shipment_builder_spec.rb +19 -0
- data/spec/requests/fedex_spec.rb +47 -0
- data/spec/requests/ups_spec.rb +75 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/support/custom_matchers/basic_matcher.rb +13 -0
- data/spec/support/custom_matchers/have_attribute_matcher.rb +22 -0
- data/spec/support/custom_matchers/have_default_value_matcher.rb +26 -0
- data/spec/support/custom_matchers/have_errors_on_matcher.rb +23 -0
- data/spec/support/custom_matchers/validate_inclusion_of_matcher.rb +37 -0
- data/spec/support/custom_matchers/validate_presence_of_matcher.rb +24 -0
- data/spec/support/custom_matchers/validate_submodel_matcher.rb +44 -0
- data/spec/support/shared_behaviours/builders_behaviour.rb +9 -0
- data/spec/support/shared_behaviours/responses_behaviour.rb +10 -0
- data/tmp/metric_fu/_data/20131210.yml +9964 -0
- data/wsdl/fedex/ship_service_v10.wsdl +5566 -0
- data/wsdl/ups/Ship.wsdl +120 -0
- data/wsdl/ups/Void.wsdl +58 -0
- metadata +308 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Shipping accept request.
|
3
|
+
class ShipAcceptRequest < Request
|
4
|
+
def initialize(credentials, shipment_digest, options = {})
|
5
|
+
@credentials = credentials
|
6
|
+
@shipment_digest = shipment_digest
|
7
|
+
@options = options
|
8
|
+
@type = :prcoess_ship_accept
|
9
|
+
end
|
10
|
+
|
11
|
+
# :nodoc:
|
12
|
+
def body
|
13
|
+
{ 'common:Request' => {
|
14
|
+
'common:RequestOption' => REQUEST_OPTION
|
15
|
+
},
|
16
|
+
'ShipmentDigest' => @shipment_digest,
|
17
|
+
:order! => ['common:Request', 'ShipmentDigest']
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Required credentials:
|
3
|
+
# * _username_
|
4
|
+
# * _password_
|
5
|
+
# * _access_license_number_
|
6
|
+
#
|
7
|
+
# = Usage
|
8
|
+
# client = SimpleShipping::Ups::ShipClient.new(:username => "USER NAME",
|
9
|
+
# :password => "PASSWORD",
|
10
|
+
# :access_license_number => "LICENSE NUMBER")
|
11
|
+
# client.request(shipper, recipient, package) # => #<SimpleShipping::Ups::Response ...>
|
12
|
+
class ShipClient < Client
|
13
|
+
set_required_credentials :username, :password, :access_license_number
|
14
|
+
|
15
|
+
set_wsdl_document File.join(SimpleShipping::WSDL_DIR, "ups/Ship.wsdl")
|
16
|
+
set_production_address "https://onlinetools.ups.com/webservices/Ship"
|
17
|
+
set_testing_address "https://wwwcie.ups.com/webservices/Ship"
|
18
|
+
|
19
|
+
# @param shipper [::SimpleShipping::Party]
|
20
|
+
# @param recipient [::SimpleShipping::Party]
|
21
|
+
# @param package [::SimpleShipping::Package]
|
22
|
+
# @param options [Hash] ({})
|
23
|
+
#
|
24
|
+
# @return [::SimpleShipping::ShipmentResponse]
|
25
|
+
#
|
26
|
+
# @raise [::SimpleShipping::RequestError] in case of SOAP errors
|
27
|
+
def shipment_request(shipper, recipient, package, options = {})
|
28
|
+
shipment = create_shipment(shipper, recipient, package, options)
|
29
|
+
request = ShipmentRequest.new(@credentials, shipment, options)
|
30
|
+
execute(request)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Send shipment confirmation request.
|
34
|
+
def ship_confirm_request(shipper, recipient, package, options = {})
|
35
|
+
shipment = create_shipment(shipper, recipient, package, options)
|
36
|
+
request = ShipConfirmRequest.new(@credentials, shipment, options)
|
37
|
+
execute(request)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Perform shipping accept request.
|
42
|
+
def ship_accept_request(shipment_digest, options = {})
|
43
|
+
request = ShipAcceptRequest.new(@credentials, shipment_digest, options)
|
44
|
+
execute(request)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param [Hash] options Savon client options
|
48
|
+
def client_options(options = {})
|
49
|
+
super.deep_merge(
|
50
|
+
:namespaces => {
|
51
|
+
# Savon parses have WSDL instead of XMLSchema which is not accepted by UPS
|
52
|
+
# So we have to again set namespace explicitly :( -- aignatev 20130204
|
53
|
+
'xmlns:ship' => "http://www.ups.com/XMLSchema/XOLTWS/Ship/v1.0"
|
54
|
+
}
|
55
|
+
)
|
56
|
+
end
|
57
|
+
protected :client_options
|
58
|
+
|
59
|
+
|
60
|
+
# Perform ShipmentRequest to UPS service.
|
61
|
+
def execute(request)
|
62
|
+
savon_response = @client.call(request.type, :message => request.body)
|
63
|
+
log_response(savon_response)
|
64
|
+
request.response(savon_response)
|
65
|
+
rescue Savon::SOAPFault => e
|
66
|
+
raise SimpleShipping::RequestError.new(e)
|
67
|
+
end
|
68
|
+
private :execute
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Request to verify a shipment was delivered.
|
3
|
+
class ShipConfirmRequest < Request
|
4
|
+
def initialize(credentials, shipment, options = {})
|
5
|
+
@credentials = credentials
|
6
|
+
@shipment = shipment
|
7
|
+
@options = options
|
8
|
+
@type = :process_ship_confirm
|
9
|
+
end
|
10
|
+
|
11
|
+
# Builds a request from {Shipment shipment} object.
|
12
|
+
def body
|
13
|
+
{ 'common:Request' => {
|
14
|
+
'common:RequestOption' => REQUEST_OPTION
|
15
|
+
},
|
16
|
+
'Shipment' => ShipmentBuilder.build(@shipment, @options),
|
17
|
+
'LabelSpecification' => label_specification,
|
18
|
+
:order! => ['common:Request', 'Shipment', 'LabelSpecification']
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Builds shipment element for UPS SOAP service.
|
3
|
+
class ShipmentBuilder < SimpleShipping::Abstract::Builder
|
4
|
+
# The type of payment for this shipment.
|
5
|
+
PAYMENT_TYPE = '01' # 01 - Transportation, 02 - Duties and Taxes
|
6
|
+
|
7
|
+
# Service codes in UPS terminology.
|
8
|
+
SERVICE_TYPES = {:next_day_air => '01',
|
9
|
+
:second_day_air => '02',
|
10
|
+
:ground => '03',
|
11
|
+
:express => '07',
|
12
|
+
:expedited => '08',
|
13
|
+
:standard => '11',
|
14
|
+
:three_day_select => '12',
|
15
|
+
:next_day_air_saver => '13',
|
16
|
+
:next_day_air_early_am => '14',
|
17
|
+
:express_plus => '54',
|
18
|
+
:second_day_air_am => '59',
|
19
|
+
:saver => '65',
|
20
|
+
:today_standard => '82',
|
21
|
+
:today_dedicated_courier => '83',
|
22
|
+
:today_intercity => '84',
|
23
|
+
:today_express => '85',
|
24
|
+
:today_express_saver => '86'}
|
25
|
+
|
26
|
+
set_default_opts :service_type => :second_day_air
|
27
|
+
|
28
|
+
# Return a hash for Savon representing a shipment model.
|
29
|
+
def build
|
30
|
+
{ 'Shipper' => PartyBuilder.build(@model.shipper, :shipper => true),
|
31
|
+
'ShipTo' => PartyBuilder.build(@model.recipient),
|
32
|
+
'PaymentInformation' => build_payment_info,
|
33
|
+
'Service' => build_service,
|
34
|
+
'Package' => PackageBuilder.build(@model.package),
|
35
|
+
:order! => ['Shipper', 'ShipTo', 'PaymentInformation', 'Service', 'Package'] }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the PaymentInformation hash.
|
39
|
+
def build_payment_info
|
40
|
+
{'ShipmentCharge' => build_shipment_charge }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the shipment charge for the PaymentInformation hash.
|
44
|
+
def build_shipment_charge
|
45
|
+
result = {'Type' => PAYMENT_TYPE, :order! => ['Type']}
|
46
|
+
if @model.payor == :shipper
|
47
|
+
result['BillShipper'] = {'AccountNumber' => @model.shipper.account_number}
|
48
|
+
result[:order!] << 'BillShipper'
|
49
|
+
else
|
50
|
+
result['BillReceiver'] = {'AccountNumber' => @model.recipient.account_number}
|
51
|
+
result[:order!] << 'BillReceiver'
|
52
|
+
end
|
53
|
+
result
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return the hash representing the Service.
|
57
|
+
def build_service
|
58
|
+
{'Code' => SERVICE_TYPES[@opts[:service_type]]}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Validate that the service type is included.
|
62
|
+
def validate
|
63
|
+
validate_inclusion_of(:service_type, SERVICE_TYPES)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Shipment request model.
|
3
|
+
class ShipmentRequest < Request
|
4
|
+
def initialize(credentials, shipment, options = {})
|
5
|
+
@credentials = credentials
|
6
|
+
@shipment = shipment
|
7
|
+
@options = options
|
8
|
+
@type = :process_shipment
|
9
|
+
end
|
10
|
+
|
11
|
+
# Builds a request from {Shipment shipment} object.
|
12
|
+
def body
|
13
|
+
{ 'common:Request' => {
|
14
|
+
'common:RequestOption' => REQUEST_OPTION
|
15
|
+
},
|
16
|
+
'Shipment' => ShipmentBuilder.build(@shipment, @options),
|
17
|
+
'LabelSpecification' => label_specification,
|
18
|
+
:order! => ['common:Request', 'Shipment', 'LabelSpecification']
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# Required credentials:
|
3
|
+
# * _username_
|
4
|
+
# * _password_
|
5
|
+
# * _access_license_number_
|
6
|
+
#
|
7
|
+
# = Usage
|
8
|
+
# client = SimpleShipping::Ups::VoidClient.new(:username => "USER NAME",
|
9
|
+
# :password => "PASSWORD",
|
10
|
+
# :access_license_number => "LICENSE NUMBER")
|
11
|
+
# client.request(shipper, recipient, package) # => #<SimpleShipping::Ups::Response ...>
|
12
|
+
class VoidClient < Client
|
13
|
+
set_required_credentials :username, :password, :access_license_number
|
14
|
+
|
15
|
+
set_wsdl_document File.join(SimpleShipping::WSDL_DIR, "ups/Void.wsdl")
|
16
|
+
set_production_address "https://onlinetools.ups.com/webservices/Void"
|
17
|
+
set_testing_address "https://wwwcie.ups.com/webservices/Void"
|
18
|
+
|
19
|
+
# Build VoidRequest and perform the request.
|
20
|
+
#
|
21
|
+
# @param shipment_identification_number [String]
|
22
|
+
# @param options [Hash]
|
23
|
+
def void_request(shipment_identification_number, options = {})
|
24
|
+
request = VoidRequest.new(@credentials, shipment_identification_number, options)
|
25
|
+
execute(request)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param [Hash] options Savon client options
|
29
|
+
def client_options(options = {})
|
30
|
+
super.deep_merge(
|
31
|
+
:namespaces => {
|
32
|
+
# Savon parses have WSDL instead of XMLSchema which is not accepted by UPS
|
33
|
+
# So we have to again set namespace explicitly :( -- aignatev 20130204
|
34
|
+
'xmlns:void' => "http://www.ups.com/XMLSchema/XOLTWS/Void/v1.1"
|
35
|
+
}
|
36
|
+
)
|
37
|
+
end
|
38
|
+
protected :client_options
|
39
|
+
|
40
|
+
# Perform ShipmentRequest to UPS service.
|
41
|
+
def execute(request)
|
42
|
+
savon_response = @client.call(request.type, :message => request.body)
|
43
|
+
log_response(savon_response)
|
44
|
+
request.response(savon_response)
|
45
|
+
rescue Savon::SOAPFault => err
|
46
|
+
raise SimpleShipping::RequestError.new(err)
|
47
|
+
end
|
48
|
+
private :execute
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SimpleShipping::Ups
|
2
|
+
# UPS request to void shipment.
|
3
|
+
class VoidRequest < Request
|
4
|
+
|
5
|
+
# @param credentials [Hash]
|
6
|
+
# @param shipment_identification_number [String]
|
7
|
+
# @param options [Hash]
|
8
|
+
def initialize(credentials, shipment_identification_number, options = {})
|
9
|
+
@credentials = credentials
|
10
|
+
@shipment_identification_number = shipment_identification_number
|
11
|
+
@tracking_number = options[:tracking_number]
|
12
|
+
@options = options
|
13
|
+
@type = :process_void
|
14
|
+
end
|
15
|
+
|
16
|
+
# Build a request from a {Shipment shipment} object.
|
17
|
+
def body
|
18
|
+
{
|
19
|
+
'common:Request' => {
|
20
|
+
'common:RequestOption' => REQUEST_OPTION
|
21
|
+
},
|
22
|
+
'VoidShipment' => void_shipment,
|
23
|
+
:order! => ['common:Request', 'VoidShipment']
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Data for VoidShipment.
|
28
|
+
#
|
29
|
+
# @return [Hash]
|
30
|
+
def void_shipment
|
31
|
+
data = { 'ShipmentIdentificationNumber' => @shipment_identification_number }
|
32
|
+
|
33
|
+
if @tracking_number
|
34
|
+
data['TrackingNumber'] = @tracking_number
|
35
|
+
data[:order!] = ['ShipmentIdentificationNumber', 'TrackingNumber']
|
36
|
+
end
|
37
|
+
|
38
|
+
data
|
39
|
+
end
|
40
|
+
private :void_shipment
|
41
|
+
end
|
42
|
+
end
|
data/lib/tasks/demo.rake
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
namespace :demo do
|
2
|
+
task :environment do
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
Bundler.require
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift File.expand_path('../../', __FILE__)
|
8
|
+
|
9
|
+
require 'simple_shipping'
|
10
|
+
require 'RMagick'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
namespace :fedex do
|
15
|
+
desc 'Call real FedEx API with shipment_request'
|
16
|
+
task :shipment_request, [:credentials_file, :output_filename] => :environment do |task, args|
|
17
|
+
args.with_defaults(:output_filename => File.join(Dir.tmpdir, 'fedex_shipment_request_output.png'))
|
18
|
+
|
19
|
+
credentials = YAML.load_file(args[:credentials_file])['fedex'].symbolize_keys!
|
20
|
+
|
21
|
+
demo = SimpleShipping::Demo::Fedex.new(credentials)
|
22
|
+
resp = demo.shipment_request
|
23
|
+
img = Magick::Image.read_inline(resp.label_image_base64).first
|
24
|
+
|
25
|
+
img.write(args[:output_filename])
|
26
|
+
puts "Label received. #{args[:output_filename]} written"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
namespace :ups do
|
31
|
+
desc 'Call real UPS API with shipment_request'
|
32
|
+
task :shipment_request, [:credentials_file, :output_filename] => :environment do |task, args|
|
33
|
+
args.with_defaults(:output_filename => File.join(Dir.tmpdir, 'ups_shipment_request_output.png'))
|
34
|
+
|
35
|
+
credentials = YAML.load_file(args[:credentials_file])['ups'].symbolize_keys!
|
36
|
+
|
37
|
+
demo = SimpleShipping::Demo::Ups.new(credentials)
|
38
|
+
|
39
|
+
resp = demo.shipment_request
|
40
|
+
img = Magick::Image.read_inline(resp.label_image_base64).first
|
41
|
+
|
42
|
+
img.write(args[:output_filename])
|
43
|
+
puts "Label received. #{args[:output_filename]} written"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Call real UPS API with void_request'
|
47
|
+
task :void_request, [:credentials_file] => :environment do |task, args|
|
48
|
+
credentials = YAML.load_file(args[:credentials_file])['ups'].symbolize_keys!
|
49
|
+
demo = SimpleShipping::Demo::Ups.new(credentials)
|
50
|
+
|
51
|
+
begin
|
52
|
+
resp = demo.void_request
|
53
|
+
rescue SimpleShipping::RequestError => exc
|
54
|
+
raise exc unless exc.message =~ /No shipment found within the allowed void period/
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'simple_shipping'
|
7
|
+
require 'simple_shipping/ups'
|
8
|
+
require 'RMagick'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'forgery'
|
11
|
+
require 'yaml'
|
12
|
+
|
13
|
+
package_path_base = File.expand_path('../ups_certification_package/', __FILE__)
|
14
|
+
FileUtils.rm_rf(package_path_base) if File.directory?(package_path_base)
|
15
|
+
|
16
|
+
# YAML file with credentials
|
17
|
+
unless credentials_file = ARGV.pop
|
18
|
+
abort "Usage:\n #{$0} <PATH_TO_CREDENTIALS.yml>"
|
19
|
+
end
|
20
|
+
|
21
|
+
CREDENTIALS = YAML.load_file(credentials_file )['ups'].symbolize_keys!
|
22
|
+
ACCOUNT_NUMBER = CREDENTIALS.delete(:account_number)
|
23
|
+
|
24
|
+
5.times do |iteration|
|
25
|
+
package_path = File.join(package_path_base, iteration.to_s)
|
26
|
+
FileUtils.mkdir_p(package_path)
|
27
|
+
|
28
|
+
shipper_address = SimpleShipping::Address.new(
|
29
|
+
:country_code => 'US',
|
30
|
+
:state_code => 'IL',
|
31
|
+
:postal_code => '60201',
|
32
|
+
:city => Forgery::Address.city,
|
33
|
+
:street_line => Forgery::Address.street_address
|
34
|
+
)
|
35
|
+
shipper_contact = SimpleShipping::Contact.new(
|
36
|
+
:person_name => Forgery::Name.full_name,
|
37
|
+
:phone_number => Forgery::Address.phone
|
38
|
+
)
|
39
|
+
shipper = SimpleShipping::Party.new(
|
40
|
+
:address => shipper_address,
|
41
|
+
:contact => shipper_contact,
|
42
|
+
:account_number => ACCOUNT_NUMBER
|
43
|
+
)
|
44
|
+
recipient_address = SimpleShipping::Address.new(
|
45
|
+
:country_code => 'US',
|
46
|
+
:state_code => 'SC',
|
47
|
+
:postal_code => '29072',
|
48
|
+
:city => Forgery::Address.city,
|
49
|
+
:street_line => Forgery::Address.street_address
|
50
|
+
)
|
51
|
+
recipient_contact = SimpleShipping::Contact.new(
|
52
|
+
:person_name => Forgery::Name.full_name,
|
53
|
+
:phone_number => Forgery::Address.phone
|
54
|
+
)
|
55
|
+
recipient = SimpleShipping::Party.new(
|
56
|
+
:address => recipient_address,
|
57
|
+
:contact => recipient_contact
|
58
|
+
)
|
59
|
+
package = SimpleShipping::Package.new(
|
60
|
+
:weight => 0.5,
|
61
|
+
:packaging_type => :envelope,
|
62
|
+
:insured_value => iteration * 250.0,
|
63
|
+
:declared_value => iteration * 250.0
|
64
|
+
)
|
65
|
+
|
66
|
+
confirm_path = File.join(package_path, "confirm")
|
67
|
+
FileUtils.mkdir_p(confirm_path)
|
68
|
+
|
69
|
+
confirm_client = SimpleShipping::Ups::ShipClient.new(
|
70
|
+
:debug => true,
|
71
|
+
:debug_path => confirm_path,
|
72
|
+
:credentials => CREDENTIALS
|
73
|
+
)
|
74
|
+
|
75
|
+
puts "CONFIRM REQUEST #{iteration}"
|
76
|
+
confirm = confirm_client.ship_confirm_request(shipper, recipient, package)
|
77
|
+
|
78
|
+
accept_path = File.join(package_path, "accept")
|
79
|
+
FileUtils.mkdir_p(accept_path)
|
80
|
+
accept_client = SimpleShipping::Ups::ShipClient.new(
|
81
|
+
:debug => true,
|
82
|
+
:debug_path => accept_path,
|
83
|
+
:credentials => CREDENTIALS
|
84
|
+
)
|
85
|
+
|
86
|
+
puts "ACCEPT REQUEST #{iteration}"
|
87
|
+
accept = accept_client.ship_accept_request(confirm.digest)
|
88
|
+
|
89
|
+
puts "SAVING LABEL HTML"
|
90
|
+
File.open(File.join(package_path, "label.html"), "w") {|f| f.write accept.label_html}
|
91
|
+
|
92
|
+
puts "SAVING LABEL GIF"
|
93
|
+
image_name = "label#{accept.tracking_number}.gif"
|
94
|
+
img = Magick::Image.read_inline(accept.label_image_base64).first
|
95
|
+
img.write(File.join(package_path, image_name))
|
96
|
+
|
97
|
+
|
98
|
+
# Apparently, the HTML version is OK:
|
99
|
+
# http://www.corecommerce.com/kb/328/ups_label_certification_requiring_39th_file
|
100
|
+
if accept.receipt_html
|
101
|
+
puts "SAVING HIGH VALUE REPORT HTML"
|
102
|
+
File.open(File.join(package_path, "high_value_report.html"), "w") {|f| f.write accept.receipt_html}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
VOID_NUMBERS = [
|
107
|
+
# A successful XML response will be returned for a shipment level void request.
|
108
|
+
['1ZISDE016691676846'],
|
109
|
+
# A successful XML response will be returned for a shipment level void request.
|
110
|
+
['1Z2220060290602143'],
|
111
|
+
# A successful XML response will be returned for a package level void request. The request will void the package in the shipment.
|
112
|
+
['1Z2220060294314162', '1Z2220060291994175'],
|
113
|
+
# A successful XML response will be returned for a package level void request. The request will void the package in the shipment. .
|
114
|
+
['1Z2220060292690189', '1Z2220060292002190'],
|
115
|
+
|
116
|
+
# Multiple tracking numbers for each shipment identifier. These don't seem to
|
117
|
+
# work, but implementing them is unnecessary.
|
118
|
+
|
119
|
+
# A successful XML response will be returned for a package level void request. The request will void all the packages.
|
120
|
+
# ['1ZISDE016691609089', '1ZISDE016694068891'],
|
121
|
+
# A successful XML response will be returned for a package level void request. The request will void all the packages.
|
122
|
+
# ['1ZISDE016691609089', '1ZISDE016690889305'],
|
123
|
+
# A successful XML response will be returned with a partial void for a package level void request. The request will void package 1Z2220060293874210 but package 1Z2220060292634221 cannot be voided.
|
124
|
+
# ['1Z2220060290530202', '1Z2220060293874210'],
|
125
|
+
# A successful XML response will be returned with a partial void for a package level void request. The request will void package 1Z2220060293874210 but package 1Z2220060292634221 cannot be voided.
|
126
|
+
# ['1Z2220060290530202', '1Z2220060292634221']
|
127
|
+
]
|
128
|
+
|
129
|
+
VOID_NUMBERS.each do |identifier, tracking_number|
|
130
|
+
package_path = File.join(package_path_base, "void/#{identifier}")
|
131
|
+
FileUtils.mkdir_p(package_path)
|
132
|
+
|
133
|
+
void_client = SimpleShipping::Ups::VoidClient.new(
|
134
|
+
:debug => true,
|
135
|
+
:debug_path => package_path,
|
136
|
+
:credentials => CREDENTIALS
|
137
|
+
)
|
138
|
+
puts "VOID REQUEST: #{identifier}"
|
139
|
+
void_client.void_request(identifier, :tracking_number => tracking_number)
|
140
|
+
end
|