ups_shipping 1.0.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.
@@ -0,0 +1,190 @@
1
+ require "nokogiri"
2
+ require "httparty"
3
+ require 'ups_shipping/address'
4
+ require 'ups_shipping/organization'
5
+ require 'ups_shipping/package'
6
+ require 'ups_shipping/pickup'
7
+
8
+ module Shipping
9
+
10
+ VERSION = '1.0.0'
11
+
12
+ class UPS
13
+
14
+ TEST_URL = "https://wwwcie.ups.com"
15
+ LIVE_URL = "https://onlinetools.ups.com"
16
+
17
+ class Http
18
+ include HTTParty
19
+ base_uri LIVE_URL
20
+
21
+ def initialize(access_request, options={})
22
+ @access_request = access_request
23
+
24
+ if (options[:test])
25
+ self.class.base_uri TEST_URL
26
+ end
27
+ end
28
+
29
+ def commit(url, request)
30
+ request = @access_request + request
31
+ self.class.post(url, :body => request).parsed_response
32
+ end
33
+ end
34
+
35
+ def initialize(user, password, license, options={})
36
+ @options = options
37
+ @shipper = options[:shipper]
38
+ @access_request = access_request(user, password, license)
39
+ @http = Http.new(@access_request, :test => @options[:test])
40
+
41
+ @services = {
42
+ "01" => "Next Day Air",
43
+ "02" => "2nd Day Air",
44
+ "03" => "Ground",
45
+ "07" => "Express",
46
+ "08" => "Expedited",
47
+ "11" => "UPS Standard",
48
+ "12" => "3 Day Select",
49
+ "13" => "Next Day Air Saver",
50
+ "14" => "Next Day Air Early AM",
51
+ "54" => "Express Plus",
52
+ "59" => "2nd Day Air A.M.",
53
+ "65" => "UPS Saver",
54
+ "82" => "UPS Today Standard",
55
+ "83" => "UPS Today Dedicated Courier",
56
+ "84" => "UPS Today Intercity",
57
+ "85" => "UPS Today Express",
58
+ "86" => "UPS Today Express Saver"
59
+ }
60
+
61
+ end
62
+
63
+ def validate_address(address)
64
+ validate_request = Nokogiri::XML::Builder.new do |xml|
65
+ xml.AddressValidationRequest {
66
+ xml.Request {
67
+ xml.RequestAction "XAV"
68
+ xml.RequestOption "3"
69
+ }
70
+ xml.AddressKeyFormat {
71
+ xml.AddressLine address.address_line[0]
72
+ xml.PoliticalDivision2 address.city
73
+ xml.PoliticalDivision1 address.state
74
+ xml.PostcodePrimaryLow address.zip
75
+ xml.CountryCode address.country
76
+ }
77
+ }
78
+ end
79
+ @http.commit("/ups.app/xml/XAV", validate_request.to_xml)
80
+ end
81
+
82
+ def find_rates(package, origin, destination, options={})
83
+ rate_request = Nokogiri::XML::Builder.new do |xml|
84
+ xml.RatingServiceSelectionRequest {
85
+ xml.Request {
86
+ xml.RequestAction "Rate"
87
+ xml.RequestOption "Rate"
88
+ }
89
+ if options[:pickup]
90
+ @options[:pickup].build_type(xml)
91
+ end
92
+ @shipper.build(xml, "Shipper")
93
+ destination.build(xml, "ShipTo")
94
+ origin.build(xml, "ShipFrom")
95
+ xml.PaymentInformation {
96
+ xml.Prepaid {
97
+ xml.BillShipper {
98
+ xml.AccountNumber "Ship Number"
99
+ }
100
+ }
101
+ }
102
+ package.build(xml)
103
+ }
104
+ end
105
+ @http.commit("/ups.app/xml/Rate", rate_request.to_xml)
106
+ end
107
+
108
+ def request_shipment(package, origin, destination, service, options={})
109
+ shipment_request = Nokogiri::XML::Builder.new do |xml|
110
+ xml.ShipmentConfirmRequest {
111
+ xml.Request {
112
+ xml.RequestAction "ShipConfirm"
113
+ xml.RequestOptions "validate"
114
+ }
115
+ if options[:label]
116
+ xml.LabelSpecification {
117
+ xml.LabelPrintMethod {
118
+ xml.Code "GIF"
119
+ xml.Description "gif file"
120
+ }
121
+ xml.HTTPUserAgent "Mozilla/4.5"
122
+ xml.LabelImageFormat {
123
+ xml.Code "GIF"
124
+ xml.Description "gif"
125
+ }
126
+ }
127
+ end
128
+ @shipper.build(xml, "Shipper")
129
+ destination.build(xml, "ShipTo")
130
+ origin.build(xml, "ShipFrom")
131
+ xml.PaymentInformation {
132
+ xml.Prepaid {
133
+ xml.BillShipper {
134
+ xml.AccountNumber "Ship Number"
135
+ }
136
+ }
137
+ }
138
+ xml.Service {
139
+ xml.Code service
140
+ xml.Description @services[service]
141
+ }
142
+ package.build(xml)
143
+ }
144
+ end
145
+ @http.commit("/ups.app/xml/ShipConfirm", shipment_request.to_xml)
146
+ end
147
+
148
+ def cancel_shipment(shipment_id)
149
+ cancel_request = Nokogiri::XML::Builder.new do |xml|
150
+ xml.VoidShipmentRequest {
151
+ xml.Request {
152
+ xml.RequestAction "1"
153
+ xml.RequestOption "1"
154
+ }
155
+ xml.ShipmentIdentificationNumber shipment_id
156
+ }
157
+ end
158
+ @http.commit("/ups.app/xml/Void", cancel_request.to_xml)
159
+ end
160
+
161
+ def track_shipment(tracking_number)
162
+ track_request = Nokogiri::XML::Builder.new do
163
+ TrackRequest {
164
+ Request {
165
+ RequestAction "Track"
166
+ RequestOption "activity"
167
+ }
168
+ TrackingNumber tracking_number
169
+ }
170
+ end
171
+
172
+ @http.commit("/ups.app/xml/Track", track_request.to_xml)
173
+ end
174
+
175
+
176
+ private
177
+ def access_request(user, password, license)
178
+ access_request = Nokogiri::XML::Builder.new do
179
+ AccessRequest {
180
+ AccessLicenseNumber license
181
+ UserId user
182
+ Password password
183
+ }
184
+ end
185
+
186
+ access_request.to_xml
187
+ end
188
+
189
+ end
190
+ end
@@ -0,0 +1,39 @@
1
+ require "nokogiri"
2
+
3
+ module Shipping
4
+ class Address
5
+ ADDRESS_TYPES = %w{residential commercial po_box}
6
+ attr_accessor :address_lines
7
+ :city
8
+ :state
9
+ :zip
10
+ :country
11
+ :type
12
+
13
+ def initialize(options={})
14
+ @address_lines = options[:address_lines]
15
+ @city = options[:city]
16
+ @state = options[:state]
17
+ @zip = options[:zip]
18
+ @country = options[:country]
19
+ @type = options[:type]
20
+ end
21
+
22
+ def build(xml)
23
+ xml.Address {
24
+ xml.AddressLine1 @address_lines[0]
25
+ xml.City @city
26
+ xml.StateProvinceCode @state
27
+ xml.PostalCode @zip
28
+ xml.CountryCode @country
29
+ }
30
+ end
31
+
32
+ def to_xml()
33
+ builder = Nokogiri::XML::Builder.new do |xml|
34
+ build(xml)
35
+ end
36
+ builder.to_xml
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require "nokogiri"
2
+
3
+ module Shipping
4
+ class Organization
5
+ attr_accessor :name
6
+ :phone
7
+ :email
8
+ :address
9
+ :shipper_number
10
+
11
+
12
+ def initialize(options={})
13
+ @name = options[:name]
14
+ @phone = options[:phone]
15
+ @address = options[:address]
16
+ if options[:shipper_number]
17
+ @shipper_number = options[:shipper_number]
18
+ end
19
+ end
20
+
21
+ def build(xml, rootname)
22
+ xml.send(rootname) {
23
+ xml.CompanyName @name
24
+ xml.PhoneNumber @phone
25
+ if @shipper_number
26
+ xml.ShipperNumber @shipper_number
27
+ end
28
+ @address.build(xml)
29
+ }
30
+ end
31
+
32
+ def to_xml(rootname)
33
+ builder = Nokogiri::XML::Builder.new do |xml|
34
+ build(xml, rootname)
35
+ end
36
+ builder.to_xml
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,45 @@
1
+ require "nokogiri"
2
+
3
+ module Shipping
4
+ class Package
5
+ attr_accessor :large
6
+ :weight
7
+ :description
8
+ :monetary_value
9
+
10
+ def initialize(options={})
11
+ @large = options[:large]
12
+ @weight = options[:weight]
13
+ @description = options[:description]
14
+ @monetary_value = options[:monetary_value]
15
+ end
16
+
17
+ def build(xml)
18
+ xml.Package {
19
+ xml.PackagingType {
20
+ xml.Code "02"
21
+ xml.Description "Customer Supplied"
22
+ }
23
+ xml.Description @description
24
+ xml.ReferenceNumber {
25
+ xml.Code "00"
26
+ xml.Value "Package"
27
+ }
28
+ xml.PackageWeight {
29
+ xml.UnitOfMeasurement
30
+ xml.Weight @weight
31
+ }
32
+ if @large
33
+ xml.LargePackageIndicator
34
+ end
35
+ }
36
+ end
37
+
38
+ def to_xml()
39
+ builder = Nokogiri::XML::Builder.new do |xml|
40
+ build(xml)
41
+ end
42
+ builder.to_xml
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ require "nokogiri"
2
+
3
+ module Shipping
4
+ class Pickup
5
+ attr_accessor :address_lines
6
+ :pickup_day
7
+ :contact_method
8
+ :type
9
+
10
+ def initialize(options={})
11
+ @type = options[:type]
12
+ if options[:pickup_day]
13
+ @pickup_day = options[:pickup_day]
14
+ end
15
+ if options[:contact_method]
16
+ @contact_method = options[:contact_method]
17
+ end
18
+
19
+ @pickupTypes = {
20
+ "01" => "Daily Pickup",
21
+ "03" => "Customer Counter",
22
+ "06" => "One Time Pickup",
23
+ "07" => "On Call Air",
24
+ "19" => "Letter Center",
25
+ "20" => "Air Service Center"
26
+ }
27
+ end
28
+
29
+ def build_schedule(xml)
30
+ xml.OnCallAir {
31
+ xml.Schedule {
32
+ if @pickup_day
33
+ xml.PickupDay @pickup_day
34
+ end
35
+ if @contact_method
36
+ xml.Method @contact_method
37
+ end
38
+ }
39
+ }
40
+ end
41
+
42
+ def build_type(xml)
43
+ xml.PickupType {
44
+ xml.Code type
45
+ xml.Description @pickupTypes[type]
46
+ }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ require "rspec"
2
+ require "ups_shipping"
3
+ require "address"
4
+ require "organization"
5
+
6
+ describe Shipping::UPS do
7
+ before(:all) do
8
+ @ups = Shipping::UPS.new("deanchen", "Transcriptic#1", "EC96D31A8D672E28", :test => true)
9
+ @address = Shipping::Address.new(
10
+ :address_lines => ["1402 Faber St."],
11
+ :city => "Durham",
12
+ :state => "NC",
13
+ :zip => "27705",
14
+ :country => "US"
15
+ )
16
+ end
17
+ it "address object" do
18
+ @address.to_xml.gsub(/^\s+/, "").gsub(/\s+$/, $/).should == '
19
+ <?xml version="1.0"?>
20
+ <Address>
21
+ <AddressLine1>1402 Faber St.</AddressLine1>
22
+ <City>Durham</City>
23
+ <StateProvinceCode>NC</StateProvinceCode>
24
+ <PostalCode>27705</PostalCode>
25
+ <CountryCode>US</CountryCode>
26
+ </Address>
27
+ '.gsub(/^\s+/, "").gsub(/\s+$/, $/)
28
+ end
29
+ it "organization object" do
30
+ @organization = Shipping::Organization.new(
31
+ :name => "Transcriptic",
32
+ :phone => "1233455678",
33
+ :address => @address
34
+ )
35
+ puts @organization.to_xml("Shipper")
36
+ end
37
+ it "#track_shipment" do
38
+ tracking_result = @ups.track_shipment("1ZXX31290231000092")
39
+ tracking_result.should have_key("TrackResponse")
40
+ tracking_result["TrackResponse"]["Response"]["ResponseStatusCode"].should == "1"
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ups_shipping
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Transcriptic, Inc
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-04 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &70314021897160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70314021897160
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70314021896740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70314021896740
36
+ - !ruby/object:Gem::Dependency
37
+ name: httparty
38
+ requirement: &70314021896320 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70314021896320
47
+ description: UPS shipping gem for integrating UPS's API into a Ruby script.
48
+ email: team@transcriptic.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/ups_shipping.rb
54
+ - lib/ups_shipping/address.rb
55
+ - lib/ups_shipping/organization.rb
56
+ - lib/ups_shipping/package.rb
57
+ - lib/ups_shipping/pickup.rb
58
+ - spec/ups_shipping_spec.rb
59
+ homepage: http://www.github.com/transcriptic/ups-shipping
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 1.8.6
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: UPS shipping API integration.
83
+ test_files: []
84
+ has_rdoc: