simple_shipping 0.4.6
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/.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
|