fedex_ship 0.1.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/.gitignore +15 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/fedex_ship-0.1.0.iml +22 -0
- data/.idea/misc.xml +7 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.idea/workspace.xml +56 -0
- data/.rspec +2 -0
- data/Gemfile +5 -0
- data/Rakefile +7 -0
- data/Readme.md +496 -0
- data/fedex_ship.gemspec +28 -0
- data/lib/fedex_ship.rb +55 -0
- data/lib/fedex_ship/address.rb +31 -0
- data/lib/fedex_ship/credentials.rb +26 -0
- data/lib/fedex_ship/document.rb +51 -0
- data/lib/fedex_ship/ground_manifest.rb +25 -0
- data/lib/fedex_ship/helpers.rb +20 -0
- data/lib/fedex_ship/label.rb +71 -0
- data/lib/fedex_ship/rate.rb +38 -0
- data/lib/fedex_ship/request/address.rb +97 -0
- data/lib/fedex_ship/request/base.rb +443 -0
- data/lib/fedex_ship/request/delete.rb +76 -0
- data/lib/fedex_ship/request/document.rb +45 -0
- data/lib/fedex_ship/request/ground_close.rb +73 -0
- data/lib/fedex_ship/request/label.rb +29 -0
- data/lib/fedex_ship/request/logs_fedex.rb +74 -0
- data/lib/fedex_ship/request/pickup.rb +135 -0
- data/lib/fedex_ship/request/pickup_availability.rb +102 -0
- data/lib/fedex_ship/request/rate.rb +94 -0
- data/lib/fedex_ship/request/service_availability.rb +86 -0
- data/lib/fedex_ship/request/shipment.rb +249 -0
- data/lib/fedex_ship/request/tracking_information.rb +119 -0
- data/lib/fedex_ship/shipment.rb +115 -0
- data/lib/fedex_ship/tracking_information.rb +54 -0
- data/lib/fedex_ship/tracking_information/event.rb +24 -0
- data/lib/fedex_ship/version.rb +6 -0
- data/spec/config/fedex_credentials.example.yml +13 -0
- data/spec/lib/fedex_ship/address_spec.rb +59 -0
- data/spec/lib/fedex_ship/delete_spec.rb +26 -0
- data/spec/lib/fedex_ship/document_spec.rb +177 -0
- data/spec/lib/fedex_ship/ground_close_spec.rb +42 -0
- data/spec/lib/fedex_ship/label_spec.rb +73 -0
- data/spec/lib/fedex_ship/pickup_availability_spec.rb +19 -0
- data/spec/lib/fedex_ship/pickup_spec.rb +32 -0
- data/spec/lib/fedex_ship/rate_spec.rb +216 -0
- data/spec/lib/fedex_ship/service_availability_spec.rb +20 -0
- data/spec/lib/fedex_ship/shipment_spec.rb +86 -0
- data/spec/lib/fedex_ship/track_spec.rb +67 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/credentials.rb +15 -0
- data/spec/support/vcr.rb +14 -0
- metadata +193 -0
data/fedex_ship.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'fedex_ship/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'fedex_ship'
|
7
|
+
s.version = FedexShip::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['Jazmin Schroeder','Shubham Sharma']
|
10
|
+
s.email = ['shubhamsharma4587@gmail.com']
|
11
|
+
s.homepage = 'https://github.com/shubhamsharma4587/fedex_ship'
|
12
|
+
s.summary = %q{Fedex Web Services}
|
13
|
+
s.description = %q{Provides an interface to Upgraded Fedex Web Services}
|
14
|
+
|
15
|
+
s.add_dependency 'httparty', '>= 0.13.7'
|
16
|
+
s.add_dependency 'nokogiri', '>= 1.5.6'
|
17
|
+
|
18
|
+
s.add_development_dependency "rspec", '~> 3.1'
|
19
|
+
s.add_development_dependency 'vcr', '~> 2.0'
|
20
|
+
s.add_development_dependency 'webmock', '~> 1.8.0'
|
21
|
+
s.add_development_dependency 'pry'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ['lib']
|
28
|
+
end
|
data/lib/fedex_ship.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'fedex_ship/shipment'
|
2
|
+
|
3
|
+
# Get shipping rates trough Fedex Web Services
|
4
|
+
#
|
5
|
+
# In order to use the API you will need to apply for developer/production credentials,
|
6
|
+
# Visit {http://www.fedex.com/us/developer/ Fedex Developer Center} for more information about how to obtain your keys.
|
7
|
+
#
|
8
|
+
# ===Usage example
|
9
|
+
# #Use your own Fedex Keys
|
10
|
+
# fedex = FedexShip::Shipment.new(:key => 'xxx',
|
11
|
+
# :password => 'xxxx',
|
12
|
+
# :account_number => 'xxxx',
|
13
|
+
# :meter => 'xxx',
|
14
|
+
# :mode=>['production'|'development'])
|
15
|
+
# shipper = {:name => "Sender",
|
16
|
+
# :company => "Company",
|
17
|
+
# :phone_number => "555-555-5555",
|
18
|
+
# :address => "Main Street",
|
19
|
+
# :city => "Harrison",
|
20
|
+
# :state => "AR",
|
21
|
+
# :postal_code => "72601",
|
22
|
+
# :country_code => "US" }
|
23
|
+
#
|
24
|
+
# recipient = { :name => "Recipient",
|
25
|
+
# :company => "Company",
|
26
|
+
# :phone_number => "555-555-5555",
|
27
|
+
# :address => "Main Street",
|
28
|
+
# :city => "City",
|
29
|
+
# :state => "ST",
|
30
|
+
# :postal_code => "55555",
|
31
|
+
# :country_code => "US",
|
32
|
+
# :residential => "false" }
|
33
|
+
# packages = []
|
34
|
+
# packages << { :weight => {:units => "LB", :value => 2},
|
35
|
+
# :dimensions => {:length => 10, :width => 5, :height => 4, :units => "IN" } }
|
36
|
+
# packages << { :weight => {:units => "LB", :value => 6},
|
37
|
+
# :dimensions => {:length => 5, :width => 5, :height => 4, :units => "IN" } }
|
38
|
+
# # "YOUR PACKAGING" and "REGULAR PICKUP" are the default options for all shipments but you can easily change them by passing an extra hash for # shipping_options
|
39
|
+
# shipping_options = { :packaging_type => "YOUR_PACKAGING", :drop_off_type => "REGULAR_PICKUP" }
|
40
|
+
# rate = fedex.rate({:shipper=>shipper, :recipient => recipient, :packages => packages, :service_type => "FEDEX_GROUND", :shipping_options => #shipping_options})
|
41
|
+
#
|
42
|
+
# $ <FedexShip::Rate:0x1019ba5f8 @total_net_charge="34.03",
|
43
|
+
# @total_surcharges="1.93",
|
44
|
+
# @total_billing_weight="8.0 LB",
|
45
|
+
# @total_taxes="0.0",
|
46
|
+
# @rate_type="PAYOR_ACCOUNT_PACKAGE",
|
47
|
+
# @total_base_charge="32.1",
|
48
|
+
# @total_freight_discounts=nil,
|
49
|
+
# @total_net_freight="32.1",
|
50
|
+
# @rate_zone="51">
|
51
|
+
module FedexShip
|
52
|
+
require 'fedex_ship/version'
|
53
|
+
#Exceptions: FedexShip::RateError
|
54
|
+
class RateError < StandardError; end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FedexShip
|
2
|
+
class Address
|
3
|
+
|
4
|
+
attr_reader :changes, :score, :confirmed, :available, :status, :residential,
|
5
|
+
:business, :company, :street_lines, :city, :state,
|
6
|
+
:province_code, :postal_code, :country_code
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@changes = options[:changes]
|
10
|
+
@score = options[:score].to_i
|
11
|
+
@confirmed = options[:delivery_point_validation] == "CONFIRMED"
|
12
|
+
@available = options[:delivery_point_validation] != "UNAVAILABLE"
|
13
|
+
|
14
|
+
@status = options[:residential_status]
|
15
|
+
@residential = status == "RESIDENTIAL"
|
16
|
+
@business = status == "BUSINESS"
|
17
|
+
|
18
|
+
address = options[:address]
|
19
|
+
|
20
|
+
@company = options[:company_name]
|
21
|
+
@street_lines = address[:street_lines]
|
22
|
+
@city = address[:city]
|
23
|
+
@state = address[:state_or_province_code]
|
24
|
+
@province_code = address[:state_or_province_code]
|
25
|
+
@postal_code = address[:postal_code]
|
26
|
+
@country_code = address[:country_code]
|
27
|
+
|
28
|
+
@options = options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fedex_ship/helpers'
|
2
|
+
|
3
|
+
module FedexShip
|
4
|
+
class Credentials
|
5
|
+
include Helpers
|
6
|
+
attr_reader :key, :password, :account_number, :meter, :mode
|
7
|
+
|
8
|
+
# In order to use Fedex rates API you must first apply for a developer(and later production keys),
|
9
|
+
# Visit {http://www.fedex.com/us/developer/ Fedex Developer Center} for more information about how to obtain your keys.
|
10
|
+
# @param [String] key - Fedex web service key
|
11
|
+
# @param [String] password - Fedex password
|
12
|
+
# @param [String] account_number - Fedex account_number
|
13
|
+
# @param [String] meter - Fedex meter number
|
14
|
+
# @param [String] mode - [development/production]
|
15
|
+
#
|
16
|
+
# return a FedexShip::Credentials object
|
17
|
+
def initialize(options={})
|
18
|
+
requires!(options, :key, :password, :account_number, :meter, :mode)
|
19
|
+
@key = options[:key]
|
20
|
+
@password = options[:password]
|
21
|
+
@account_number = options[:account_number]
|
22
|
+
@meter = options[:meter]
|
23
|
+
@mode = options[:mode]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module FedexShip
|
2
|
+
class Document
|
3
|
+
attr_reader :tracking_number, :filenames, :response_details
|
4
|
+
|
5
|
+
# Initialize FedexShip::Document Object
|
6
|
+
# @param [Hash] options
|
7
|
+
def initialize(shipment_details = {})
|
8
|
+
@response_details = shipment_details[:process_shipment_reply]
|
9
|
+
@filenames = shipment_details[:filenames]
|
10
|
+
|
11
|
+
# extract label and tracking number
|
12
|
+
package_details = @response_details[:completed_shipment_detail][:completed_package_details]
|
13
|
+
label = package_details[:label]
|
14
|
+
@tracking_number = package_details[:tracking_ids][:tracking_number]
|
15
|
+
|
16
|
+
# extract shipment documents
|
17
|
+
shipment_documents = @response_details[:completed_shipment_detail][:shipment_documents] || []
|
18
|
+
|
19
|
+
# unify iteration interface
|
20
|
+
unless shipment_documents.kind_of?(Array)
|
21
|
+
shipment_documents = [shipment_documents]
|
22
|
+
end
|
23
|
+
|
24
|
+
# keeps the filenames which actually saved
|
25
|
+
save(@filenames[:label], label)
|
26
|
+
|
27
|
+
# save shipment documents
|
28
|
+
shipment_documents.each do |doc|
|
29
|
+
doc_type = doc[:type].downcase.to_sym
|
30
|
+
save(@filenames[doc_type], doc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def save(path, content)
|
35
|
+
return unless path && has_image?(content)
|
36
|
+
|
37
|
+
image = Base64.decode64(content[:parts][:image])
|
38
|
+
full_path = Pathname.new(path)
|
39
|
+
File.open(full_path, 'wb') do|f|
|
40
|
+
f.write(image)
|
41
|
+
end
|
42
|
+
|
43
|
+
full_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_image?(content)
|
47
|
+
content[:parts] && content[:parts][:image]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module FedexShip
|
5
|
+
class GroundManifest
|
6
|
+
attr_reader :manifest_data, :filename
|
7
|
+
|
8
|
+
# Initialize FedexShip::GroundManifest Object
|
9
|
+
# @param [Hash] options
|
10
|
+
def initialize(options = {})
|
11
|
+
puts options
|
12
|
+
@filename = options[:filename]
|
13
|
+
@manifest_data = Base64.decode64(options[:manifest][:file])
|
14
|
+
save
|
15
|
+
end
|
16
|
+
|
17
|
+
def save
|
18
|
+
return if manifest_data.nil? || filename.nil?
|
19
|
+
full_path = Pathname.new(filename)
|
20
|
+
File.open(full_path, 'wb') do |f|
|
21
|
+
f.write(manifest_data)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module FedexShip
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
private
|
5
|
+
# String or :symbol to CamelCase
|
6
|
+
def camelize(s)
|
7
|
+
# s.to_s.split('_').map { |e| e.capitalize }.join('')
|
8
|
+
s.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Helper method to validate required fields
|
12
|
+
def requires!(hash, *params)
|
13
|
+
params.each { |param| raise RateError, "Missing Required Parameter #{param}" if hash[param].nil? }
|
14
|
+
end
|
15
|
+
|
16
|
+
def underscorize(key) #:nodoc:
|
17
|
+
key.to_s.sub(/^(v[0-9]+|ns):/, "").gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module FedexShip
|
5
|
+
class Label
|
6
|
+
attr_accessor :options, :image, :response_details
|
7
|
+
|
8
|
+
# Initialize FedexShip::Label Object
|
9
|
+
# @param [Hash] options
|
10
|
+
def initialize(label_details = {}, associated_shipments = false)
|
11
|
+
if associated_shipments
|
12
|
+
package_details = label_details
|
13
|
+
@options = package_details[:label]
|
14
|
+
@options[:tracking_number] = package_details[:tracking_id]
|
15
|
+
else
|
16
|
+
@response_details = label_details[:process_shipment_reply]
|
17
|
+
package_details = label_details[:process_shipment_reply][:completed_shipment_detail][:completed_package_details]
|
18
|
+
@options = package_details[:label]
|
19
|
+
@options[:tracking_number] = package_details[:tracking_ids][:tracking_number]
|
20
|
+
end
|
21
|
+
@options[:format] = label_details[:format]
|
22
|
+
@options[:file_name] = label_details[:file_name]
|
23
|
+
@image = Base64.decode64(options[:parts][:image]) if has_image?
|
24
|
+
|
25
|
+
if file_name = @options[:file_name]
|
26
|
+
save(file_name, false)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
[tracking_number, format].join('.')
|
32
|
+
end
|
33
|
+
|
34
|
+
def format
|
35
|
+
options[:format]
|
36
|
+
end
|
37
|
+
|
38
|
+
def file_name
|
39
|
+
options[:file_name]
|
40
|
+
end
|
41
|
+
|
42
|
+
def tracking_number
|
43
|
+
options[:tracking_number]
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_image?
|
47
|
+
options[:parts] && options[:parts][:image]
|
48
|
+
end
|
49
|
+
|
50
|
+
def save(path, append_name = true)
|
51
|
+
return unless has_image?
|
52
|
+
|
53
|
+
full_path = Pathname.new(path)
|
54
|
+
full_path = full_path.join(name) if append_name
|
55
|
+
|
56
|
+
File.open(full_path, 'wb') do|f|
|
57
|
+
f.write(@image)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def associated_shipments
|
62
|
+
if (label_details = @response_details[:completed_shipment_detail][:associated_shipments])
|
63
|
+
label_details[:format] = format
|
64
|
+
label_details[:file_name] = file_name
|
65
|
+
Label.new(label_details, true)
|
66
|
+
else
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module FedexShip
|
2
|
+
# Visit {http://www.fedex.com/us/developer/ Fedex Developer Center} for a complete list of values returned from the API
|
3
|
+
#
|
4
|
+
# Rate totals are contained in the node
|
5
|
+
# response[:rate_reply][:rate_reply_details][:rated_shipment_details]
|
6
|
+
class Rate
|
7
|
+
# Initialize FedexShip::Rate Object
|
8
|
+
# @param [Hash] options
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# return [FedexShip::Rate Object]
|
12
|
+
# @rate_type #Type used for this specific set of rate data
|
13
|
+
# @rate_zone #Indicates the rate zone used(based on origin and destination)
|
14
|
+
# @total_billing_weight #The weight used to calculate these rates
|
15
|
+
# @total_freight_discounts #The toal discounts used in the rate calculation
|
16
|
+
# @total_net_charge #The net charge after applying all discounts and surcharges
|
17
|
+
# @total_taxes #Total of the transportation-based taxes
|
18
|
+
# @total_net_freight #The freight charge minus dicounts
|
19
|
+
# @total_surcharges #The total amount of all surcharges applied to this shipment
|
20
|
+
# @total_base_charge #The total base charge
|
21
|
+
attr_accessor :service_type, :transit_time, :rate_type, :rate_zone, :total_billing_weight, :total_freight_discounts, :total_net_charge, :total_taxes, :total_net_freight, :total_surcharges, :total_base_charge
|
22
|
+
def initialize(options = {})
|
23
|
+
@service_type = options[:service_type]
|
24
|
+
@transit_time = options[:transit_time]
|
25
|
+
@rate_type = options[:rate_type]
|
26
|
+
@rate_zone = options[:rate_zone]
|
27
|
+
@total_billing_weight = "#{options[:total_billing_weight][:value]} #{options[:total_billing_weight][:units]}"
|
28
|
+
@total_freight_discounts = options[:total_freight_discounts]
|
29
|
+
@total_net_charge = options[:total_net_charge][:amount]
|
30
|
+
@total_taxes = options[:total_taxes][:amount]
|
31
|
+
@total_net_freight = options[:total_net_freight][:amount]
|
32
|
+
@total_surcharges = options[:total_surcharges][:amount]
|
33
|
+
@total_base_charge = options[:total_base_charge][:amount]
|
34
|
+
@total_net_fedex_charge = (options[:total_net_fe_dex_charge]||{})[:amount]
|
35
|
+
@total_rebates = (options[:total_rebates]||{})[:amount]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'fedex_ship/request/base'
|
2
|
+
require 'fedex_ship/address'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module FedexShip
|
6
|
+
module Request
|
7
|
+
class Address < Base
|
8
|
+
def initialize(credentials, options={})
|
9
|
+
requires!(options, :address)
|
10
|
+
@credentials = credentials
|
11
|
+
@address = options[:address]
|
12
|
+
|
13
|
+
@address[:address] ||= @address[:street]
|
14
|
+
end
|
15
|
+
|
16
|
+
def process_request
|
17
|
+
api_response = self.class.post(api_url, :body => build_xml)
|
18
|
+
puts api_response if @debug == true
|
19
|
+
response = parse_response(api_response)
|
20
|
+
if success?(response)
|
21
|
+
options = response[:address_validation_reply][:address_results][:proposed_address_details]
|
22
|
+
options = options.first if options.is_a? Array
|
23
|
+
FedexShip::Address.new(options)
|
24
|
+
else
|
25
|
+
error_message = if response[:address_validation_reply]
|
26
|
+
[response[:address_validation_reply][:notifications]].flatten.first[:message]
|
27
|
+
else
|
28
|
+
"#{api_response["Fault"]["detail"]["fault"]["reason"]}\n--#{api_response["Fault"]["detail"]["fault"]["details"]["ValidationFailureDetail"]["message"].join("\n--")}"
|
29
|
+
end rescue $1
|
30
|
+
raise RateError, error_message
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Build xml Fedex Web Service request
|
37
|
+
def build_xml
|
38
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
39
|
+
xml.AddressValidationRequest(:xmlns => "http://fedex.com/ws/addressvalidation/v#{service[:version]}"){
|
40
|
+
add_web_authentication_detail(xml)
|
41
|
+
add_client_detail(xml)
|
42
|
+
add_version(xml)
|
43
|
+
add_request_timestamp(xml)
|
44
|
+
add_address_validation_options(xml)
|
45
|
+
add_address_to_validate(xml)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
builder.doc.root.to_xml
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_request_timestamp(xml)
|
52
|
+
timestamp = Time.now
|
53
|
+
|
54
|
+
# Calculate current timezone offset manually.
|
55
|
+
# Ruby <= 1.9.2 does not support this in Time#strftime
|
56
|
+
#
|
57
|
+
utc_offest = "#{timestamp.gmt_offset < 0 ? "-" : "+"}%02d:%02d" %
|
58
|
+
(timestamp.gmt_offset / 60).abs.divmod(60)
|
59
|
+
timestamp = timestamp.strftime("%Y-%m-%dT%H:%M:%S") + utc_offest
|
60
|
+
|
61
|
+
xml.RequestTimestamp timestamp
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_address_validation_options(xml)
|
65
|
+
xml.Options{
|
66
|
+
xml.CheckResidentialStatus true
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_address_to_validate(xml)
|
71
|
+
xml.AddressesToValidate{
|
72
|
+
xml.CompanyName @address[:company] unless @address[:company].nil? or @address[:company].empty?
|
73
|
+
xml.Address{
|
74
|
+
Array(@address[:address]).take(2).each do |address_line|
|
75
|
+
xml.StreetLines address_line
|
76
|
+
end
|
77
|
+
xml.City @address[:city]
|
78
|
+
xml.StateOrProvinceCode @address[:state]
|
79
|
+
xml.PostalCode @address[:postal_code]
|
80
|
+
xml.CountryCode @address[:country]
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def service
|
86
|
+
{ :id => 'aval', :version => 2 }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Successful request
|
90
|
+
def success?(response)
|
91
|
+
response[:address_validation_reply] &&
|
92
|
+
%w{SUCCESS WARNING NOTE}.include?(response[:address_validation_reply][:highest_severity])
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|