awesome_usps 0.6.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,13 @@
1
- == 0.0.1 2008-08-12
2
-
3
- * 1 major enhancement:
4
- * Initial release
5
-
6
- == 0.6.0 18/8/2008
1
+ **== 0.6.0 18/8/2008
7
2
 
8
3
  * 2 major improvement
9
4
  * Shipping parse fixed
10
5
  * Documentation added
11
6
  * 1 bug fixes
12
7
  * Shipping canned tests fixed
13
-
8
+
9
+
10
+ **== 0.9.0 18/9/2008
11
+
12
+ * 1 major improvement
13
+ * Code Re-factored
@@ -12,6 +12,7 @@ lib/awesome_usps/address_verification.rb
12
12
  lib/awesome_usps/delivery_and_signature_confirmation.rb
13
13
  lib/awesome_usps/electric_merchandis_return.rb
14
14
  lib/awesome_usps/express_mail.rb
15
+ lib/awesome_usps/gateway.rb
15
16
  lib/awesome_usps/international_item.rb
16
17
  lib/awesome_usps/international_mail_labels.rb
17
18
  lib/awesome_usps/location.rb
@@ -67,7 +67,7 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
67
67
  end
68
68
 
69
69
  CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
- PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}"
71
71
  $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
72
  $hoe.rsync_args = '-av --delete --ignore-errors'
73
73
  $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -34,5 +34,6 @@ module AwesomeUsps
34
34
  include ExpressMail
35
35
  include AddressVerification
36
36
  include InternationalMailLabels
37
+ include Gateway
37
38
  end
38
39
  end
@@ -1,82 +1,65 @@
1
1
  module AwesomeUsps
2
2
  module AddressVerification
3
- MAX_RETRIES = 3
4
-
5
- LIVE_DOMAIN = 'production.shippingapis.com'
6
- LIVE_RESOURCE = '/ShippingAPI.dll'
7
-
8
- TEST_DOMAIN ='testing.shippingapis.com'
9
- TEST_RESOURCE = '/ShippingAPITest.dll'
10
-
11
- API_CODES ={
12
- :verify_address => 'Verify',
13
- :zip_lookup => 'ZipCodeLookup',
14
- :city_state_lookup =>"CityStateLookup"}
15
-
3
+
16
4
  # Examines address and fills in missing information. Address must include city & state or the zip to be processed.
17
5
  # Can do up to an array of five
18
6
  def veryify_address(locations)
19
- @locations = locations
20
- @locations.to_a if not @locations.is_a? Array
21
- @api = "AddressValidateRequest"
22
- request = xml_for_verify_address
23
- commit_address_information_request(:verify_address, request ,false)
7
+ locations = Array(locations) if not locations.is_a? Array
8
+ api_request = "AddressValidateRequest"
9
+ request = xml_for_verify_address(api_request, locations)
10
+ gateway_commit(:verify_address, 'Verify', request, :live)
24
11
  end
25
12
 
26
13
  def zip_lookup(locations)
27
- @locations = locations
28
- @locations = Array(@locations) if not @locations.is_a? Array
29
- @api = "ZipCodeLookupRequest"
30
- request = xml_for_address_information_api
31
- commit_address_information_request(:zip_lookup, request ,false)
14
+ locations = Array(locations) if not locations.is_a? Array
15
+ api_request = "ZipCodeLookupRequest"
16
+ request = xml_for_address_information_api(api_request, locations)
17
+ gateway_commit(:zip_lookup, 'ZipCodeLookup',request, :live)
32
18
  end
33
19
 
34
20
  def city_state_lookup(locations)
35
- @locations = locations
36
- @locations = Array(@locations) if not @locations.is_a? Array
37
- @api = "CityStateLookupRequest"
38
- request = xml_for_address_information_api
39
- commit_address_information_request(:zip_lookup, request ,false)
21
+ locations = Array(locations) if not locations.is_a? Array
22
+ api_request = "CityStateLookupRequest"
23
+ request = xml_for_address_information_api(api_request, locations)
24
+ gateway_commit(:zip_lookup, 'CityStateLookup', request, :live)
40
25
  end
41
26
 
42
-
43
27
  def canned_verify_address_test
44
- @locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371" )]
45
- @api = "AddressValidateRequest"
46
- request = xml_for_address_information_api
47
- commit_address_information_request(:verify_address, request ,true)
28
+ locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371" )]
29
+ api_request = "AddressValidateRequest"
30
+ request = xml_for_address_information_api(api_request, locations)
31
+ gateway_commit(:verify_address, 'Verify', request, :test)
48
32
  end
49
33
 
50
34
  def canned_zip_lookup_test
51
- @locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371" )]
52
- @api = "ZipCodeLookupRequest"
53
- request = xml_for_address_information_api
54
- commit_address_information_request(:zip_lookup, request ,true)
35
+ locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371" )]
36
+ api_request = "ZipCodeLookupRequest"
37
+ request = xml_for_address_information_api(api_request, locations)
38
+ gateway_commit(:zip_lookup, 'ZipCodeLookup', request, :test)
55
39
  end
56
40
 
57
41
  def canned_city_state_lookup_test
58
- @locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371" )]
59
- @api = "CityStateLookupRequest"
60
- request = xml_for_address_information_api
61
- commit_address_information_request(:zip_lookup, request ,true)
42
+ locations = [Location.new(:address2 => "6406 Ivy Lane", :city =>"Greenbelt", :state => "MD"), Location.new(:address2=>"8 Wildwood Drive", :city => "Old Lyme",:state => "CT", :zip5 => "06371")]
43
+ api_request = "CityStateLookupRequest"
44
+ request = xml_for_address_information_api(api_request, locations)
45
+ gateway_commit(:zip_lookup, 'CityStateLookup', request, :test)
62
46
  end
63
47
 
64
- private
65
48
  # XML from Builder::XmlMarkup.new
66
- def xml_for_address_information_api
49
+ def xml_for_address_information_api(api_request, locations)
67
50
  xm = Builder::XmlMarkup.new
68
- xm.tag!("#{@api}", "USERID"=>"#{@username}") do
69
- @locations.each_index do |id|
70
- l=@locations[id]
51
+ xm.tag!("#{api_request}", "USERID"=>"#{@username}") do
52
+ locations.each_index do |id|
53
+ l=locations[id]
71
54
  xm.Address("ID" => "#{id}") do
72
55
  xm.FirmName(l.firm_name)
73
56
  xm.Address1(l.address1)
74
57
  xm.Address2(l.address2)
75
- if @api !="CityStateLookupRequest"
58
+ if api_request !="CityStateLookupRequest"
76
59
  xm.City(l.city)
77
60
  xm.State(l.state)
78
61
  end
79
- if @api != "ZipCodeLookupRequest"
62
+ if api_request != "ZipCodeLookupRequest"
80
63
  xm.Zip5(l.zip5)
81
64
  xm.Zip4(l.zip4)
82
65
  end
@@ -85,10 +68,8 @@ module AwesomeUsps
85
68
  end
86
69
  end
87
70
 
88
-
89
71
  # Parses the XML into an array broken up by each address.
90
72
  # For verify_address :verified will be false if multiple address were found.
91
-
92
73
  def parse_address_information(xml)
93
74
  i = 0
94
75
  list_of_verified_addresses = []
@@ -117,40 +98,5 @@ module AwesomeUsps
117
98
  return list_of_verified_addresses
118
99
  end
119
100
 
120
-
121
-
122
- def commit_address_information_request(action, request, test = false)
123
- retries = MAX_RETRIES
124
- begin
125
- url = URI.parse(test ? "http://#{TEST_DOMAIN}#{TEST_RESOURCE}" : "http://#{LIVE_DOMAIN}#{LIVE_RESOURCE}")
126
- req = Net::HTTP::Post.new(url.path)
127
- req.set_form_data({'API' => API_CODES[action], 'XML' => request})
128
- response = Net::HTTP.new(url.host, url.port)
129
- response.open_timeout = 5
130
- response.read_timeout = 5
131
- response.start
132
- rescue Timeout::Error
133
- if retries > 0
134
- retries -= 1
135
- retry
136
- else
137
- RAILS_DEFAULT_LOGGER.warn "The connection to the remote server timed out"
138
- return "We appoligize for the inconvience but our USPS service is busy at the moment. To retry please refresh the browser"
139
-
140
- end
141
- rescue SocketError
142
- RAILS_DEFAULT_LOGGER.error "There is a socket error with USPS plugin"
143
- return "We appoligize for the inconvience but there is a problem with our server. To retry please refresh the browser"
144
- end
145
-
146
- response = response.request(req)
147
- case response
148
- when Net::HTTPSuccess
149
- parse_address_information(response.body)
150
- else
151
- RAILS_DEFAULT_LOGGER.warn("USPS plugin settings are wrong #{response}")
152
- end
153
- end
154
-
155
101
  end
156
102
  end
@@ -1,160 +1,99 @@
1
1
  module AwesomeUsps
2
2
  module DeliveryAndSignatureConfirmation
3
+ def delivery_confirmation_label(origin, destination, service_type, image_type, label_type=1, api_request = "DeliveryConfirmationV3.0Request", options={})
4
+ request = confirmation_xml(api_request, origin, destination, service_type, image_type, label_type, options)
5
+ #YES THE API IS THAT STUPID THAT WE MUST PASS WHAT TYPE OF MIME TYPE!
6
+ commit_confirmation_xml(:delivery, 'DeliveryConfirmationV3', request,:ssl, image_type)
7
+ end
3
8
 
4
- MAX_RETRIES = 3
5
-
6
- LIVE_DOMAIN = 'secure.shippingapis.com'
7
- LIVE_RESOURCE = '/ShippingAPI.dll'
8
-
9
- API_CODES = {:delivery =>'DeliveryConfirmationV3',
10
- :delivery_confirmation_certify => "DelivConfirmCertifyV3",
11
- :signature => "SignatureConfirmationV3",
12
- :signature_confirmation_certify => "SignatureConfirmCertifyV3"}
13
-
14
- def delivery_confirmation_label(origin, destination, service_type, image_type, label_type=1, options={})
15
- @origin = origin
16
- @destination = destination
17
- @service_type = service_type
18
- @image_type =image_type
19
- @label_type = label_type
20
- @options = options
21
- @api = "DeliveryConfirmationV3.0Request"
22
- request = confirmation_xml
23
- #YES THE API IS THAT STUPID THAT WE MUST PASS WHAT TYPE OF MIME TYPE!
24
- commit_confirmation_xml(:delivery, request, image_type, false)
25
- end
26
-
27
- def signature_confirmation_label(origin, destination, service_type, image_type, label_type=1, options={})
28
- @origin = origin
29
- @destination = destination
30
- @service_type = service_type
31
- @image_type =image_type
32
- @label_type = label_type
33
- @options = options
34
- @api = "SignatureConfirmationV3.0Request"
35
- request = confirmation_xml
36
- #YES THE API IS THAT STUPID THAT WE MUST PASS WHAT TYPE OF MIME TYPE!
37
- commit_confirmation_xml(:signature, request, image_type, false)
38
- end
39
-
40
-
41
-
42
- def canned_delivery_confirmation_label_test
43
- @origin = Location.new( :name=> "John Smith", :address2 => "6406 Ivy Lane", :state => 'MD', :city => 'Greenbelt', :zip5 => '20770')
44
- @destination =Location.new( :name=> "Joe Customer", :address2 =>"136 Linwood Plz", :state => 'NJ', :city => 'Fort Lee', :zip5 => "07024")
45
- @service_type = "Priority"
46
- @image_type ="PDF"
47
- @label_type = 1
48
- @options = {:weight => 2}
49
- @api = "DelivConfirmCertifyV3.0Request"
50
- request = confirmation_xml
51
- commit_confirmation_xml(:delivery_confirmation_certify, request, @image_type, true)
52
- end
53
-
54
-
9
+ def signature_confirmation_label(origin, destination, service_type, image_type, label_type=1,
10
+ api_request = "SignatureConfirmationV3.0Request", options={})
11
+ request = confirmation_xml(api_request, origin, destination, service_type, image_type, label_type, options)
12
+ #YES THE API IS THAT STUPID THAT WE MUST PASS WHAT TYPE OF MIME TYPE!
13
+ commit_confirmation_xml(:signature, 'SignatureConfirmationV3', request, :ssl, image_type)
14
+ end
55
15
 
56
- def canned_signature_confirmation_label_test
57
- @origin = Location.new( :name=> "John Smith", :address2 => "6406 Ivy Lane", :state => 'MD', :city => 'Greenbelt', :zip5 => '20770')
58
- @destination =Location.new( :name=> "Joe Customer", :address2 =>"136 Linwood Plz", :state => 'NJ', :city => 'Fort Lee', :zip5 => "07024")
59
- @service_type = "Priority"
60
- @image_type ="PDF"
61
- @label_type = 1
62
- @options = {:weight => 2}
63
- @api = "SignatureConfirmCertifyV3.0Request"
64
- request = confirmation_xml
65
- commit_confirmation_xml(:signature_confirmation_certify, request, @image_type, true)
66
- end
67
16
 
68
- private
69
- def confirmation_xml
70
- xm = Builder::XmlMarkup.new
71
- xm.tag!(@api, "USERID"=>"#{@username}") do
72
- xm.Option(@label_type)
73
- xm.ImageParameters #Will be used in the future. Is a required tag.
74
- xm.FromName(@origin.name)
75
- xm.FromFirm(@origin.firm_name)
76
- xm.FromAddress1(@origin.address1) #Used for an apartment or suite number. Yes the API is a bit fucked.
77
- xm.FromAddress2(@origin.address2)
78
- xm.FromCity(@origin.city)
79
- xm.FromState(@origin.state)
80
- xm.FromZip5(@origin.zip5)
81
- xm.FromZip4(@origin.zip4)
82
- xm.ToName(@destination.name)
83
- xm.ToFirm(@destination.firm_name)
84
- xm.ToAddress1(@destination.address1)
85
- xm.ToAddress2(@destination.address2)
86
- xm.ToCity(@destination.city)
87
- xm.ToState(@destination.state)
88
- xm.ToZip5(@destination.zip5)
89
- xm.ToZip4(@destination.zip4)
90
- xm.WeightInOunces(@options[:weight_in_ounces])
91
- xm.ServiceType(@service_type)
92
- xm.SeparateReceiptPage(@options[:seperate])
93
- xm.POZipCode(@options[:po_zip_code])
94
- xm.ImageType(@image_type)
95
- xm.LabelDate(@options[:label_date])
96
- xm.CustomerRefNo(@options[:customer_reference_number])
97
- xm.AddressServiceRequested(@options[:address_service])
98
- xm.SenderName(@options[:sender_name])
99
- xm.SenderEMail(@options[:sender_email])
100
- xm.RecipientName(@options[:recipient_name])
101
- xm.RecipientEmail(@options[:recipient_email])
17
+ def canned_delivery_confirmation_label_test
18
+ origin = Location.new( :name=> "John Smith", :address2 => "6406 Ivy Lane", :state => 'MD', :city => 'Greenbelt', :zip5 => '20770')
19
+ destination =Location.new( :name=> "Joe Customer", :address2 =>"136 Linwood Plz", :state => 'NJ', :city => 'Fort Lee', :zip5 => "07024")
20
+ service_type = "Priority"
21
+ image_type ="PDF"
22
+ label_type = 1
23
+ options = {:weight => 2}
24
+ api_request = "DelivConfirmCertifyV3.0Request"
25
+ request = confirmation_xml(api_request, origin, destination, service_type, image_type, label_type, options)
26
+ gateway_commit(:delivery_confirmation_certify,'DelivConfirmCertifyV3', request, :ssl, image_type)
102
27
  end
103
- end
104
28
 
105
- def parse_confirmation_label(xml, image_type)
106
- if image_type == "TIF"
107
- image_type = "image/tif"
108
- else
109
- image_type = "application/pdf"
110
- end
111
- parse = Hpricot.parse(xml)/:error
112
- if parse != []
113
- RAILS_DEFAULT_LOGGER.info "#{xml}"
114
- return (Hpricot.parse(xml)/:description).inner_html
115
- else
116
- number = Hpricot.parse(xml)/:deliveryconfirmationnumber
117
- label = Hpricot.parse(xml)/:deliveryconfirmationlabel
118
- return {:image_type => image_type, :number => number.inner_html, :label => label.inner_html}
29
+ def canned_signature_confirmation_label_test
30
+ origin = Location.new( :name=> "John Smith", :address2 => "6406 Ivy Lane", :state => 'MD', :city => 'Greenbelt', :zip5 => '20770')
31
+ destination =Location.new( :name=> "Joe Customer", :address2 =>"136 Linwood Plz", :state => 'NJ', :city => 'Fort Lee', :zip5 => "07024")
32
+ service_type = "Priority"
33
+ image_type ="PDF"
34
+ label_type = 1
35
+ options = {:weight => 2}
36
+ api_request = "SigConfirmCertifyV3.0Request"
37
+ request = confirmation_xml(api_request, origin, destination, service_type, image_type, label_type, options)
38
+ gateway_commit(:signature_confirmation_certify, 'SignatureConfirmationCertifyV3', request, :ssl, image_type)
119
39
  end
120
- end
121
-
122
40
 
123
- def commit_confirmation_xml(action, request, image_type, test=false)
124
- retries = MAX_RETRIES
125
- begin
126
- #If and when their testing resource works again this will be useful tertiary command
127
- url = URI.parse("https://#{LIVE_DOMAIN}#{LIVE_RESOURCE}")
128
- req = Net::HTTP::Post.new(url.path)
129
- req.set_form_data({'API' => API_CODES[action], 'XML' => request})
130
- response = Net::HTTP.new(url.host, 443)
131
- response.use_ssl
132
- response.open_timeout = 5
133
- response.read_timeout = 5
134
- response.use_ssl = true
135
- response.start
136
-
137
- rescue Timeout::Error
138
- if retries > 0
139
- retries -= 1
140
- retry
141
- else
142
- RAILS_DEFAULT_LOGGER.warn "The connection to the remote server timed out"
143
- return "We appoligize for the inconvience but our USPS service is busy at the moment. To retry please refresh the browser"
41
+ private
42
+ def confirmation_xml(api_request, origin, destination, service_type, image_type, label_type, options)
43
+ xm = Builder::XmlMarkup.new
44
+ xm.tag!(api_request, "USERID"=>"#{@username}") do
45
+ xm.Option(label_type)
46
+ xm.ImageParameters #Will be used in the future. Is a required tag.
47
+ xm.FromName(origin.name)
48
+ xm.FromFirm(origin.firm_name)
49
+ xm.FromAddress1(origin.address1) #Used for an apartment or suite number. Yes the API is a bit fucked.
50
+ xm.FromAddress2(origin.address2)
51
+ xm.FromCity(origin.city)
52
+ xm.FromState(origin.state)
53
+ xm.FromZip5(origin.zip5)
54
+ xm.FromZip4(origin.zip4)
55
+ xm.ToName(destination.name)
56
+ xm.ToFirm(destination.firm_name)
57
+ xm.ToAddress1(destination.address1)
58
+ xm.ToAddress2(destination.address2)
59
+ xm.ToCity(destination.city)
60
+ xm.ToState(destination.state)
61
+ xm.ToZip5(destination.zip5)
62
+ xm.ToZip4(destination.zip4)
63
+ xm.WeightInOunces(options[:weight_in_ounces])
64
+ xm.ServiceType(service_type)
65
+ xm.SeparateReceiptPage(options[:seperate])
66
+ xm.POZipCode(options[:po_zip_code])
67
+ xm.ImageType(image_type)
68
+ xm.LabelDate(options[:label_date])
69
+ xm.CustomerRefNo(options[:customer_reference_number])
70
+ xm.AddressServiceRequested(options[:address_service])
71
+ xm.SenderName(options[:sender_name])
72
+ xm.SenderEMail(options[:sender_email])
73
+ xm.RecipientName(options[:recipient_name])
74
+ xm.RecipientEMail(options[:recipient_email])
144
75
  end
145
- rescue SocketError
146
- RAILS_DEFAULT_LOGGER.error "There is a socket error with USPS plugin"
147
- return "We appoligize for the inconvience but there is a problem with our server. To retry please refresh the browser"
148
76
  end
149
77
 
150
- response = response.request(req)
151
- case response
152
- when Net::HTTPSuccess
153
- parse_confirmation_label(response.body, image_type)
154
- else
155
- RAILS_DEFAULT_LOGGER.warn("USPS plugin settings are wrong #{response}")
156
- return "USPS plugin settings are wrong #{response}"
78
+ def parse_confirmation_label(action, xml, image_type)
79
+ if image_type == "TIF"
80
+ image_type = "image/tif"
81
+ else
82
+ image_type = "application/pdf"
83
+ end
84
+ parse = Hpricot.parse(xml)/:error
85
+ if parse != []
86
+ RAILS_DEFAULT_LOGGER.info "#{xml}"
87
+ return (Hpricot.parse(xml)/:description).inner_html
88
+ elsif action == :signature_confirmation_certify || :signature
89
+ number = Hpricot.parse(xml)/:signatureconfirmationnumber
90
+ label = Hpricot.parse(xml)/:signatureconfirmationlabel
91
+ return {:image_type => image_type, :number => number.inner_html, :label => label.inner_html}
92
+ else
93
+ number = Hpricot.parse(xml)/:deliveryconfirmationnumber
94
+ label = Hpricot.parse(xml)/:deliveryconfirmationlabel
95
+ return {:image_type => image_type, :number => number.inner_html, :label => label.inner_html}
96
+ end
157
97
  end
158
- end
159
98
  end
160
99
  end