usps-ruby-client 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/.gitattributes +2 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +41 -0
- data/.rubocop_todo.yml +0 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/data/api/address-information-api.htm +8229 -0
- data/lib/data/api/domestic-mail-service-standards-api.htm +11016 -0
- data/lib/data/api/evs-international-label-api.htm +33291 -0
- data/lib/data/api/evs-label-api.htm +18895 -0
- data/lib/data/api/hold-for-pickup-facilities-lookup-api.htm +5530 -0
- data/lib/data/api/package-pickup-api.htm +19157 -0
- data/lib/data/api/rate-calculator-api.htm +16355 -0
- data/lib/data/api/scan-api.htm +5934 -0
- data/lib/data/api/service-delivery-calculator-get-locations-api.htm +12548 -0
- data/lib/data/api/track-and-confirm-api.htm +21288 -0
- data/lib/data/api/uspsreturnslabel-api.htm +9474 -0
- data/lib/helpers/erubis_helper.rb +10 -0
- data/lib/tasks/api.rake +246 -0
- data/lib/usps-ruby-client.rb +30 -0
- data/lib/usps/api/endpoints.rb +70 -0
- data/lib/usps/api/endpoints/carrier_pickup_schedule.rb +117 -0
- data/lib/usps/api/endpoints/city_state_lookup.rb +50 -0
- data/lib/usps/api/endpoints/e_vs_express_mail_intl.rb +359 -0
- data/lib/usps/api/endpoints/e_vs_first_class_mail_intl.rb +323 -0
- data/lib/usps/api/endpoints/e_vs_priority_mail_intl.rb +366 -0
- data/lib/usps/api/endpoints/e_vsgxg_get_label.rb +366 -0
- data/lib/usps/api/endpoints/e_vsi_cancel.rb +55 -0
- data/lib/usps/api/endpoints/hfp_facility_info.rb +71 -0
- data/lib/usps/api/endpoints/intl_rate_v2.rb +135 -0
- data/lib/usps/api/endpoints/pts_email.rb +73 -0
- data/lib/usps/api/endpoints/pts_pod.rb +86 -0
- data/lib/usps/api/endpoints/pts_rre.rb +72 -0
- data/lib/usps/api/endpoints/ptst_pod.rb +75 -0
- data/lib/usps/api/endpoints/rate_v4.rb +140 -0
- data/lib/usps/api/endpoints/scan.rb +121 -0
- data/lib/usps/api/endpoints/track_v2.rb +62 -0
- data/lib/usps/api/endpoints/usps_returns_label.rb +149 -0
- data/lib/usps/api/endpoints/verify.rb +75 -0
- data/lib/usps/api/endpoints/zip_code_lookup.rb +69 -0
- data/lib/usps/api/error.rb +6 -0
- data/lib/usps/api/errors/too_many_requests_error.rb +22 -0
- data/lib/usps/api/errors/usps_error.rb +30 -0
- data/lib/usps/api/templates/_build_xml.erb +7 -0
- data/lib/usps/api/templates/_options.erb +6 -0
- data/lib/usps/api/templates/_throw_argument_error.erb +3 -0
- data/lib/usps/api/templates/endpoints.erb +22 -0
- data/lib/usps/api/templates/method.erb +49 -0
- data/lib/usps/api/templates/method_spec.erb +22 -0
- data/lib/usps/api/xml.rb +8 -0
- data/lib/usps/client.rb +37 -0
- data/lib/usps/config.rb +50 -0
- data/lib/usps/faraday/connection.rb +34 -0
- data/lib/usps/faraday/request.rb +39 -0
- data/lib/usps/faraday/response/raise_error.rb +16 -0
- data/lib/usps/logger.rb +14 -0
- data/lib/usps/version.rb +4 -0
- data/usps-ruby-client.gemspec +46 -0
- metadata +307 -0
data/lib/tasks/api.rake
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'amazing_print'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'erubis'
|
5
|
+
require 'active_support'
|
6
|
+
require 'active_support/core_ext'
|
7
|
+
require 'pry'
|
8
|
+
require 'helpers/erubis_helper'
|
9
|
+
|
10
|
+
namespace :usps do
|
11
|
+
namespace :api do
|
12
|
+
task :update do
|
13
|
+
def dig_set(obj, keys, value)
|
14
|
+
key = keys.first
|
15
|
+
if keys.length == 1
|
16
|
+
obj[key] = value
|
17
|
+
else
|
18
|
+
obj[key] = {} unless obj[key]
|
19
|
+
dig_set(obj[key], keys.slice(1..-1), value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def table_array_to_hash_array(columns, rows)
|
24
|
+
rows.map do |row|
|
25
|
+
row_data = {}
|
26
|
+
columns.each_with_index do |k, i|
|
27
|
+
row_data[k.to_s.gsub(/[[:space:]]+/, ' ').strip] =
|
28
|
+
row[i].is_a? String ? row[i].to_s.gsub(/[[:space:]]+/, ' ').strip : row[i]
|
29
|
+
end
|
30
|
+
row_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def standardize_table_hash_array(arr)
|
35
|
+
arr.map do |option|
|
36
|
+
next if option['Tag Name'].split('/').pop.strip.casecmp('userid').zero?
|
37
|
+
|
38
|
+
{
|
39
|
+
type: option['Type'],
|
40
|
+
name: option['Tag Name'].split('/').pop.strip,
|
41
|
+
required: option['Occurs'] == 'Required',
|
42
|
+
description: option['Description'],
|
43
|
+
}
|
44
|
+
end.compact
|
45
|
+
end
|
46
|
+
|
47
|
+
def table_hash_array_to_shape(arr)
|
48
|
+
shape = {}
|
49
|
+
|
50
|
+
nesting = []
|
51
|
+
arr[0][:type] = '(Alias)' unless arr[0][:type].casecmp('(alias)').zero?
|
52
|
+
arr.each do |tag|
|
53
|
+
if tag[:type].casecmp('(alias)').zero?
|
54
|
+
if nesting.last == tag[:name]
|
55
|
+
nesting.pop
|
56
|
+
else
|
57
|
+
nesting.push(tag[:name])
|
58
|
+
dig_set(shape, nesting, tag.merge(children: {}))
|
59
|
+
end
|
60
|
+
elsif tag[:type].casecmp('(group)').zero?
|
61
|
+
if nesting.last == tag[:name]
|
62
|
+
nesting.pop(2)
|
63
|
+
else
|
64
|
+
nesting.push(:children)
|
65
|
+
nesting.push(tag[:name])
|
66
|
+
dig_set(shape, nesting, tag.merge(children: {}))
|
67
|
+
end
|
68
|
+
elsif nesting.length.positive?
|
69
|
+
nesting_with_children = nesting + [:children]
|
70
|
+
dig_set(shape, nesting_with_children,
|
71
|
+
shape.dig(*nesting_with_children).merge({ tag[:name] => tag.merge(children: {}) }))
|
72
|
+
else
|
73
|
+
shape[tag[:name]] = tag
|
74
|
+
end
|
75
|
+
end
|
76
|
+
shape
|
77
|
+
end
|
78
|
+
|
79
|
+
def pp_xml(xml = '')
|
80
|
+
doc = Nokogiri.XML(xml) do |config|
|
81
|
+
config.default_xml.noblanks
|
82
|
+
end
|
83
|
+
doc.to_xml(indent: 2)
|
84
|
+
end
|
85
|
+
|
86
|
+
@failed_methods = []
|
87
|
+
|
88
|
+
@endpoint_files = []
|
89
|
+
|
90
|
+
def parse_doc(path)
|
91
|
+
doc = Nokogiri::HTML(File.open(path))
|
92
|
+
|
93
|
+
table_of_contents = {}
|
94
|
+
raw_table_of_contents = doc.search('sdt[docparttype="Table of Contents"] p a').map do |link|
|
95
|
+
full_title = link.content.tr("\n", ' ')
|
96
|
+
next if full_title.blank?
|
97
|
+
|
98
|
+
full_version = full_title.match(/^[\d.]+/)[0]
|
99
|
+
major, minor, tiny = full_version.split('.')
|
100
|
+
|
101
|
+
title = full_title.match(/\s+[A-Za-z\s\t.:]*\s+/)[0].gsub(/[[:space:]]+/,
|
102
|
+
' ').strip.chomp('.')
|
103
|
+
|
104
|
+
data = {
|
105
|
+
# full_title: full_title,
|
106
|
+
# link: link['href'],
|
107
|
+
anchor: link['href'].split('#')[1],
|
108
|
+
version: full_version,
|
109
|
+
major: major,
|
110
|
+
minor: minor,
|
111
|
+
tiny: tiny,
|
112
|
+
title: title,
|
113
|
+
}
|
114
|
+
|
115
|
+
table_of_contents[major] ||= []
|
116
|
+
table_of_contents[major] << data
|
117
|
+
|
118
|
+
data
|
119
|
+
end
|
120
|
+
|
121
|
+
data = table_of_contents.map do |section_number, section|
|
122
|
+
section_data = {}
|
123
|
+
section.each do |subsection|
|
124
|
+
header_node = doc.search("a[name=#{subsection[:anchor]}]")[0].parent
|
125
|
+
header_node = header_node.next_element if header_node.content.blank? && header_node.next_element
|
126
|
+
|
127
|
+
content_node = if header_node.next_element && header_node.next_element.content.present?
|
128
|
+
header_node.next_element
|
129
|
+
elsif header_node.parent.next_element && header_node.parent.next_element.content.present?
|
130
|
+
header_node.parent.next_element
|
131
|
+
else
|
132
|
+
header_node.parent.parent.next_element
|
133
|
+
end
|
134
|
+
next unless content_node # For section 1
|
135
|
+
|
136
|
+
section_data[:link] = subsection[:link]
|
137
|
+
|
138
|
+
if subsection[:version] == "#{section_number}.0"
|
139
|
+
section_data[:title] = subsection[:title]
|
140
|
+
elsif subsection[:title] == 'Overview'
|
141
|
+
section_data[:description] = content_node.content.tr("\n", ' ')
|
142
|
+
elsif subsection[:title] == 'API Signature'
|
143
|
+
columns, *rows = content_node.search('tr').map do |tr|
|
144
|
+
tr.search('td').map do |td|
|
145
|
+
td.content.gsub(/\n\s/, '').strip
|
146
|
+
end
|
147
|
+
end
|
148
|
+
section_data[:signature] = table_array_to_hash_array(columns, rows)
|
149
|
+
section_data[:url] =
|
150
|
+
"#{section_data[:signature][0]['Scheme']}#{section_data[:signature][0]['Host']}#{section_data[:signature][0]['Path'].chomp('?')}"
|
151
|
+
section_data[:group] =
|
152
|
+
section_data[:signature][0]['API'].sub('API=', '').gsub(/[[:space:]]+/,
|
153
|
+
' ').strip
|
154
|
+
# ap section_data[:signature]
|
155
|
+
# ap section_data[:signature].map{|s| s[]}
|
156
|
+
# elsif subsection[:title] == "Request Descriptions"
|
157
|
+
# columns, *rows = content_node.search('tr').map{|tr| tr.search('td').map{|td| td.content.gsub(/\n\s/, '').strip}}
|
158
|
+
# section_data[:request_descriptions] = table_hash_array_to_shape(standardize_table_hash_array(table_array_to_hash_array(columns, rows)))
|
159
|
+
elsif subsection[:title] == 'Sample Request'
|
160
|
+
title, xml = content_node.content.gsub(/[[:space:]]+/, ' ').strip.split('<', 2)
|
161
|
+
xml = pp_xml("<#{xml}")
|
162
|
+
section_data[:sample_request] = <<~XML
|
163
|
+
#{title}
|
164
|
+
#{xml}
|
165
|
+
XML
|
166
|
+
elsif subsection[:title] == 'Response Descriptions' || subsection[:title] == 'Request Descriptions'
|
167
|
+
columns, *rows = content_node.search('tr').map do |tr|
|
168
|
+
next if tr.ancestors('table').length > 1
|
169
|
+
|
170
|
+
tr.search('td').map do |td|
|
171
|
+
has_table = td.search('table').length.positive?
|
172
|
+
if !has_table
|
173
|
+
td.content.gsub(/\n\s/, '').strip
|
174
|
+
else
|
175
|
+
table = td.search('table')[0]
|
176
|
+
c, *r = table.search('tr').map do |tr|
|
177
|
+
tr.search('td').map do |td|
|
178
|
+
td.content.gsub(/\n\s/, '').strip
|
179
|
+
end
|
180
|
+
end
|
181
|
+
table_array_to_hash_array(c, r)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end.compact
|
185
|
+
binding.pry if rows.blank?
|
186
|
+
section_data[subsection[:title].downcase.gsub(/\s+/, '_').to_sym] =
|
187
|
+
table_hash_array_to_shape(standardize_table_hash_array(table_array_to_hash_array(
|
188
|
+
columns, rows
|
189
|
+
)))
|
190
|
+
elsif subsection[:title] == 'Sample Response'
|
191
|
+
title, xml = content_node.content.gsub(/[[:space:]]+/, ' ').strip.split('<', 2)
|
192
|
+
xml = pp_xml("<#{xml}")
|
193
|
+
section_data[:sample_response] = <<~XML
|
194
|
+
#{title}
|
195
|
+
#{xml}
|
196
|
+
XML
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
section_data
|
201
|
+
end
|
202
|
+
|
203
|
+
method_template = Erubis::Eruby.new(File.read('lib/usps/api/templates/method.erb'))
|
204
|
+
method_spec_template = Erubis::Eruby.new(File.read('lib/usps/api/templates/method_spec.erb'))
|
205
|
+
data.each do |api|
|
206
|
+
next if api[:group].nil? || api[:group].empty?
|
207
|
+
|
208
|
+
# begin
|
209
|
+
rendered_method = method_template.result(group: api[:group], data: api)
|
210
|
+
File.write("lib/usps/api/endpoints/#{api[:group].underscore}.rb", rendered_method)
|
211
|
+
|
212
|
+
rendered_method_spec = method_spec_template.result(group: api[:group], data: api)
|
213
|
+
File.write("spec/usps/api/endpoints/#{api[:group].underscore}_spec.rb",
|
214
|
+
rendered_method_spec)
|
215
|
+
|
216
|
+
@endpoint_files << {
|
217
|
+
file: api[:group].underscore,
|
218
|
+
module: api[:group].camelize,
|
219
|
+
}
|
220
|
+
# rescue => e
|
221
|
+
# @failed_methods << {
|
222
|
+
# file: path,
|
223
|
+
# api: api[:group],
|
224
|
+
# }
|
225
|
+
# end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
failed_docs = []
|
230
|
+
Dir.glob('lib/data/api/*.htm').each do |f|
|
231
|
+
ap f
|
232
|
+
# begin
|
233
|
+
parse_doc(f)
|
234
|
+
# rescue => e
|
235
|
+
# failed_docs << f
|
236
|
+
# end
|
237
|
+
end
|
238
|
+
|
239
|
+
endpoints_template = Erubis::Eruby.new(File.read('lib/usps/api/templates/endpoints.erb'))
|
240
|
+
File.write(
|
241
|
+
'lib/usps/api/endpoints.rb',
|
242
|
+
endpoints_template.result(files: @endpoint_files.sort_by { |f| f[:file] })
|
243
|
+
)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'usps/version'
|
3
|
+
require 'usps/logger'
|
4
|
+
require 'usps/config'
|
5
|
+
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_support/core_ext'
|
8
|
+
require 'builder'
|
9
|
+
require 'faraday'
|
10
|
+
require 'faraday_middleware'
|
11
|
+
require 'json'
|
12
|
+
require 'logger'
|
13
|
+
|
14
|
+
require_relative 'usps/api/errors/usps_error'
|
15
|
+
require_relative 'usps/api/errors/too_many_requests_error'
|
16
|
+
# require_relative 'usps/api/error'
|
17
|
+
# require_relative 'usps/api/errors'
|
18
|
+
require_relative 'usps/faraday/response/raise_error'
|
19
|
+
require_relative 'usps/faraday/connection'
|
20
|
+
require_relative 'usps/faraday/request'
|
21
|
+
# require_relative 'usps/api/mixins'
|
22
|
+
require_relative 'usps/api/xml'
|
23
|
+
require_relative 'usps/api/endpoints'
|
24
|
+
# require_relative 'usps/pagination/cursor'
|
25
|
+
require_relative 'usps/client'
|
26
|
+
|
27
|
+
# module Usps
|
28
|
+
# class Error < StandardError; end
|
29
|
+
# # Your code goes here...
|
30
|
+
# end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# This file was auto-generated by lib/tasks/web.rake
|
3
|
+
|
4
|
+
require_relative 'endpoints/carrier_pickup_schedule'
|
5
|
+
require_relative 'endpoints/city_state_lookup'
|
6
|
+
require_relative 'endpoints/e_vs_express_mail_intl'
|
7
|
+
require_relative 'endpoints/e_vs_first_class_mail_intl'
|
8
|
+
require_relative 'endpoints/e_vs_priority_mail_intl'
|
9
|
+
require_relative 'endpoints/e_vsgxg_get_label'
|
10
|
+
require_relative 'endpoints/e_vsi_cancel'
|
11
|
+
require_relative 'endpoints/hfp_facility_info'
|
12
|
+
require_relative 'endpoints/intl_rate_v2'
|
13
|
+
require_relative 'endpoints/pts_email'
|
14
|
+
require_relative 'endpoints/pts_pod'
|
15
|
+
require_relative 'endpoints/pts_rre'
|
16
|
+
require_relative 'endpoints/ptst_pod'
|
17
|
+
require_relative 'endpoints/rate_v4'
|
18
|
+
require_relative 'endpoints/scan'
|
19
|
+
require_relative 'endpoints/track_v2'
|
20
|
+
require_relative 'endpoints/usps_returns_label'
|
21
|
+
require_relative 'endpoints/verify'
|
22
|
+
require_relative 'endpoints/zip_code_lookup'
|
23
|
+
|
24
|
+
module Usps
|
25
|
+
module Api
|
26
|
+
module Endpoints
|
27
|
+
include CarrierPickupSchedule
|
28
|
+
include CityStateLookup
|
29
|
+
include EVSExpressMailIntl
|
30
|
+
include EVSFirstClassMailIntl
|
31
|
+
include EVSPriorityMailIntl
|
32
|
+
include EVSGXGGetLabel
|
33
|
+
include EVSICancel
|
34
|
+
include HFPFacilityInfo
|
35
|
+
include IntlRateV2
|
36
|
+
include PTSEmail
|
37
|
+
include PTSPod
|
38
|
+
include PTSRre
|
39
|
+
include PTSTPod
|
40
|
+
include RateV4
|
41
|
+
include SCAN
|
42
|
+
include TrackV2
|
43
|
+
include USPSReturnsLabel
|
44
|
+
include Verify
|
45
|
+
include ZipCodeLookup
|
46
|
+
|
47
|
+
ACTIONS = {
|
48
|
+
carrier_pickup_schedule: 'CarrierPickupSchedule',
|
49
|
+
city_state_lookup: 'CityStateLookup',
|
50
|
+
e_vs_express_mail_intl: 'EVSExpressMailIntl',
|
51
|
+
e_vs_first_class_mail_intl: 'EVSFirstClassMailIntl',
|
52
|
+
e_vs_priority_mail_intl: 'EVSPriorityMailIntl',
|
53
|
+
e_vsgxg_get_label: 'EVSGXGGetLabel',
|
54
|
+
e_vsi_cancel: 'EVSICancel',
|
55
|
+
hfp_facility_info: 'HFPFacilityInfo',
|
56
|
+
intl_rate_v2: 'IntlRateV2',
|
57
|
+
pts_email: 'PTSEmail',
|
58
|
+
pts_pod: 'PTSPod',
|
59
|
+
pts_rre: 'PTSRre',
|
60
|
+
ptst_pod: 'PTSTPod',
|
61
|
+
rate_v4: 'RateV4',
|
62
|
+
scan: 'SCAN',
|
63
|
+
track_v2: 'TrackV2',
|
64
|
+
usps_returns_label: 'USPSReturnsLabel',
|
65
|
+
verify: 'Verify',
|
66
|
+
zip_code_lookup: 'ZipCodeLookup',
|
67
|
+
}.freeze
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file was auto-generated by lib/tasks/api.rake
|
4
|
+
|
5
|
+
module Usps
|
6
|
+
module Api
|
7
|
+
module Endpoints
|
8
|
+
module CarrierPickupSchedule
|
9
|
+
#
|
10
|
+
# Package Pickup Schedule API
|
11
|
+
#
|
12
|
+
# The Package Pickup Schedule API schedules a
|
13
|
+
# Package Pickup and provides the user a confirmation number for the scheduled
|
14
|
+
# pickup. Prior to making a Pickup Schedule call, it is recommended to use
|
15
|
+
# the Pickup Availability API to confirm that service is available.
|
16
|
+
#
|
17
|
+
# @option option [(Alias)] :CarrierPickupScheduleRequest (Required)
|
18
|
+
# @option option [String] :FirstName (Required)
|
19
|
+
# - Only alpha characters, apostrophes, spaces, periods, and hyphens "-" may be used. For example: <FirstName>John</FirstName>
|
20
|
+
# @option option [String] :LastName (Required)
|
21
|
+
# - Only alpha characters, apostrophes, spaces, periods and hyphens "-" may be used. For example: <LastName>Doe</LastName>
|
22
|
+
# @option option [String] :FirmName (Optional)
|
23
|
+
# - Only alpha and numeric characters, apostrophes, spaces, hyphens "-" and ampersands "&" may be used. Use this tag for a firm or company name. Some firms/companies that have their own ZIP codes require the use of firm name to properly identify their address. Note: FirmName is Optional except if the First Name and Last Name tags are null. For example: <FirmName>ABC Company</FirmName>
|
24
|
+
# @option option [String] :SuiteOrApt (Required)
|
25
|
+
# - Apartment or suite number. Optional except if needed to uniquely identify an address at a multiple dwelling address, for example, an apartment building. For example: <SuiteOrApt>Suite 777</SuiteOrApt>
|
26
|
+
# @option option [String] :Address2 (Required)
|
27
|
+
# - Street address. For example: <Address2>1390 Market Street</Address2>
|
28
|
+
# @option option [String] :Urbanization (Required)
|
29
|
+
# - Use this tag for Urbanization (for Puerto Rico only). ZIP Code prefixes 006 to 009, if area is so designated.
|
30
|
+
# @option option [String] :City (Required)
|
31
|
+
# - City name. Either ZIP5 or City and State are required. For example: <City>Houston</City>
|
32
|
+
# @option option [String] :State (Required)
|
33
|
+
# - State abbreviation. Either ZIP5 or City and State are required. For example: <State>TX</State>
|
34
|
+
# @option option [String] :ZIP5 (Required)
|
35
|
+
# - 5-digit ZIP Code. Either ZIP5 or City and State are required. For example: <ZIP5>77058</ZIP5>
|
36
|
+
# @option option [String] :ZIP4 (Required)
|
37
|
+
# - Use this tag for a 4 digit ZIP Code. For example: <ZIP4>1234</ZIP4>
|
38
|
+
# @option option [String] :Phone (Required)
|
39
|
+
# - Two formats are allowed: (###) 123-4567 or ###-123-4567. For example: <Phone>5555551234</Phone> or <Phone>555-555-1234</Phone>
|
40
|
+
# @option option [String] :Extension (Optional)
|
41
|
+
# - Optional value for Phone Extension. For example: <Extension>201</Extension>
|
42
|
+
# @option option [(Group)] :Package (Required)
|
43
|
+
# - No values entered with this tag. <ServiceType> and <Count> tags are embedded under this. Refer to the XML request example section, below, to see how these embedded tags are formatted. If the <Count> for a service type is zero, you do not need to encode a <Package> but you must have at least one <Package> with embedded <ServiceType> and <Count> tags.
|
44
|
+
# @option option [String] :ServiceType (Required)
|
45
|
+
# - This tag is embedded under the <Package> tag. If your pickup contains more than one Service Type, use additional <Package> tags for each service type with the accompanying <ServiceType> and <Count> tags. Refer to the XML Request Example below to see how these embedded tags are formatted. For example: <ServiceType>PriorityMailExpress</ServiceType>
|
46
|
+
# @option option [String] :Count (Required)
|
47
|
+
# - This tag is embedded under the <Package> tag. Enter the number of packages for the accompanying <ServiceType> tag. Maximum characters allowed: 3 or 999 packages. If your pickup contains more than one Service Type, use additional <Package> tags for each service type with the accompanying <ServiceType> and <Count> tags. Refer to the XML request example section, below, to see how these embedded tags are formatted. For example: <Count>2</Count>
|
48
|
+
# @option option [String] :EstimatedWeight (Required)
|
49
|
+
# - Enter the estimated aggregate weight (in pounds) of all packages being picked up. For example: <EstimatedWeight>14</EstimatedWeight>
|
50
|
+
# @option option [String] :PackageLocation (Required)
|
51
|
+
# - Enter one of the following values: Note: "Other" requires information in the value for the <SpecialInstructions> tag. For example: <PackageLocation>Front Door</PackageLocation>
|
52
|
+
# @option option [String] :SpecialInstructions (Optional)
|
53
|
+
# - Value Required when PackageLocation is “Other”. Only alpha, numeric, commas, periods, apostrophes, _, &, -, ( ), ?, #, / +, @ and space characters may be used. For example: <SpecialInstructions>Packages are behind the screen door.</SpecialInstructions>
|
54
|
+
# @option option [String] :EmailAddress (Optional)
|
55
|
+
# - If provided, email notifications will be sent confirming package pickup, or request changes and cancellations. Maximum characters allowed: 50. For example: <EmailAddress>cpapple@email.com</EmailAddress>
|
56
|
+
|
57
|
+
#
|
58
|
+
# @see
|
59
|
+
def carrier_pickup_schedule(options = {})
|
60
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request missing') if options[:carrier_pickup_schedule_request].nil?
|
61
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :first_name missing') if options[:carrier_pickup_schedule_request][:first_name].nil?
|
62
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :last_name missing') if options[:carrier_pickup_schedule_request][:last_name].nil?
|
63
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :suite_or_apt missing') if options[:carrier_pickup_schedule_request][:suite_or_apt].nil?
|
64
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :address2 missing') if options[:carrier_pickup_schedule_request][:address2].nil?
|
65
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :urbanization missing') if options[:carrier_pickup_schedule_request][:urbanization].nil?
|
66
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :city missing') if options[:carrier_pickup_schedule_request][:city].nil?
|
67
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :state missing') if options[:carrier_pickup_schedule_request][:state].nil?
|
68
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :zip5 missing') if options[:carrier_pickup_schedule_request][:zip5].nil?
|
69
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :zip4 missing') if options[:carrier_pickup_schedule_request][:zip4].nil?
|
70
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :phone missing') if options[:carrier_pickup_schedule_request][:phone].nil?
|
71
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :package missing') if options[:carrier_pickup_schedule_request][:package].nil?
|
72
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :package, :service_type missing') if options[:carrier_pickup_schedule_request][:package][:service_type].nil?
|
73
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :package, :count missing') if options[:carrier_pickup_schedule_request][:package][:count].nil?
|
74
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :package, :estimated_weight missing') if options[:carrier_pickup_schedule_request][:package][:estimated_weight].nil?
|
75
|
+
throw ArgumentError.new('Required arguments :carrier_pickup_schedule_request, :package, :package_location missing') if options[:carrier_pickup_schedule_request][:package][:package_location].nil?
|
76
|
+
|
77
|
+
request = build_request(:carrier_pickup_schedule, options)
|
78
|
+
get('https://secure.shippingapis.com/ShippingAPI.dll', {
|
79
|
+
API: 'CarrierPickupSchedule',
|
80
|
+
XML: request,
|
81
|
+
})
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def tag_unless_blank(xml, tag_name, data)
|
87
|
+
xml.tag!(tag_name, data) unless data.blank? || data.nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_carrier_pickup_schedule_request(xml, options = {})
|
91
|
+
xml.tag!('FirstName', options[:carrier_pickup_schedule_request][:first_name])
|
92
|
+
xml.tag!('LastName', options[:carrier_pickup_schedule_request][:last_name])
|
93
|
+
tag_unless_blank(xml, 'FirmName', options[:carrier_pickup_schedule_request][:firm_name])
|
94
|
+
xml.tag!('SuiteOrApt', options[:carrier_pickup_schedule_request][:suite_or_apt])
|
95
|
+
xml.tag!('Address2', options[:carrier_pickup_schedule_request][:address2])
|
96
|
+
xml.tag!('Urbanization', options[:carrier_pickup_schedule_request][:urbanization])
|
97
|
+
xml.tag!('City', options[:carrier_pickup_schedule_request][:city])
|
98
|
+
xml.tag!('State', options[:carrier_pickup_schedule_request][:state])
|
99
|
+
xml.tag!('ZIP5', options[:carrier_pickup_schedule_request][:zip5])
|
100
|
+
xml.tag!('ZIP4', options[:carrier_pickup_schedule_request][:zip4])
|
101
|
+
xml.tag!('Phone', options[:carrier_pickup_schedule_request][:phone])
|
102
|
+
tag_unless_blank(xml, 'Extension', options[:carrier_pickup_schedule_request][:extension])
|
103
|
+
xml.tag!('Package') do
|
104
|
+
xml.tag!('ServiceType', options[:carrier_pickup_schedule_request][:package][:service_type])
|
105
|
+
xml.tag!('Count', options[:carrier_pickup_schedule_request][:package][:count])
|
106
|
+
xml.tag!('EstimatedWeight', options[:carrier_pickup_schedule_request][:package][:estimated_weight])
|
107
|
+
xml.tag!('PackageLocation', options[:carrier_pickup_schedule_request][:package][:package_location])
|
108
|
+
tag_unless_blank(xml, 'SpecialInstructions', options[:carrier_pickup_schedule_request][:package][:special_instructions])
|
109
|
+
tag_unless_blank(xml, 'EmailAddress', options[:carrier_pickup_schedule_request][:package][:email_address])
|
110
|
+
end
|
111
|
+
xml.target!
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|