easypost 3.5.1 → 5.2.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 +4 -4
- data/.gitattributes +9 -0
- data/.github/CODEOWNERS +2 -0
- data/.github/ISSUE_TEMPLATE/bug_report.yml +81 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yml +37 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- data/.github/workflows/ci.yml +54 -5
- data/.gitignore +27 -17
- data/.gitmodules +3 -0
- data/CHANGELOG.md +295 -119
- data/Gemfile +2 -0
- data/Makefile +70 -0
- data/README.md +184 -72
- data/Rakefile +2 -1
- data/UPGRADE_GUIDE.md +181 -0
- data/VERSION +1 -1
- data/bin/easypost-irb +5 -3
- data/easypost.gemspec +27 -20
- data/lib/easypost/client.rb +179 -0
- data/lib/easypost/connection.rb +64 -0
- data/lib/easypost/constants.rb +15 -0
- data/lib/easypost/errors/api/api_error.rb +108 -0
- data/lib/easypost/errors/api/bad_request_error.rb +6 -0
- data/lib/easypost/errors/api/connection_error.rb +6 -0
- data/lib/easypost/errors/api/external_api_error.rb +18 -0
- data/lib/easypost/errors/api/forbidden_error.rb +6 -0
- data/lib/easypost/errors/api/gateway_timeout_error.rb +6 -0
- data/lib/easypost/errors/api/internal_server_error.rb +6 -0
- data/lib/easypost/errors/api/invalid_request_error.rb +6 -0
- data/lib/easypost/errors/api/method_not_allowed_error.rb +6 -0
- data/lib/easypost/errors/api/not_found_error.rb +6 -0
- data/lib/easypost/errors/api/payment_error.rb +6 -0
- data/lib/easypost/errors/api/proxy_error.rb +6 -0
- data/lib/easypost/errors/api/rate_limit_error.rb +6 -0
- data/lib/easypost/errors/api/redirect_error.rb +6 -0
- data/lib/easypost/errors/api/retry_error.rb +6 -0
- data/lib/easypost/errors/api/service_unavailable_error.rb +6 -0
- data/lib/easypost/errors/api/ssl_error.rb +6 -0
- data/lib/easypost/errors/api/timeout_error.rb +6 -0
- data/lib/easypost/errors/api/unauthorized_error.rb +6 -0
- data/lib/easypost/errors/api/unknown_api_error.rb +6 -0
- data/lib/easypost/errors/easy_post_error.rb +7 -0
- data/lib/easypost/errors/end_of_pagination_error.rb +7 -0
- data/lib/easypost/errors/filtering_error.rb +4 -0
- data/lib/easypost/errors/invalid_object_error.rb +4 -0
- data/lib/easypost/errors/invalid_parameter_error.rb +11 -0
- data/lib/easypost/errors/missing_parameter_error.rb +9 -0
- data/lib/easypost/errors/signature_verification_error.rb +4 -0
- data/lib/easypost/errors.rb +32 -0
- data/lib/easypost/hooks/request_context.rb +16 -0
- data/lib/easypost/hooks/response_context.rb +23 -0
- data/lib/easypost/hooks.rb +34 -0
- data/lib/easypost/http_client.rb +117 -0
- data/lib/easypost/internal_utilities.rb +66 -0
- data/lib/easypost/models/address.rb +5 -0
- data/lib/easypost/models/api_key.rb +5 -0
- data/lib/easypost/models/base.rb +58 -0
- data/lib/easypost/models/batch.rb +5 -0
- data/lib/easypost/models/brand.rb +5 -0
- data/lib/easypost/models/carbon_offset.rb +5 -0
- data/lib/easypost/models/carrier_account.rb +5 -0
- data/lib/easypost/models/carrier_type.rb +5 -0
- data/lib/easypost/models/customs_info.rb +5 -0
- data/lib/easypost/models/customs_item.rb +5 -0
- data/lib/easypost/models/end_shipper.rb +5 -0
- data/lib/easypost/models/error.rb +21 -0
- data/lib/easypost/models/event.rb +5 -0
- data/lib/easypost/models/insurance.rb +6 -0
- data/lib/easypost/models/order.rb +9 -0
- data/lib/easypost/models/parcel.rb +5 -0
- data/lib/easypost/models/payload.rb +5 -0
- data/lib/easypost/models/payment_method.rb +5 -0
- data/lib/easypost/models/pickup.rb +9 -0
- data/lib/easypost/models/pickup_rate.rb +5 -0
- data/lib/easypost/models/postage_label.rb +5 -0
- data/lib/easypost/models/rate.rb +5 -0
- data/lib/easypost/models/referral.rb +5 -0
- data/lib/easypost/models/refund.rb +5 -0
- data/lib/easypost/models/report.rb +5 -0
- data/lib/easypost/models/scan_form.rb +6 -0
- data/lib/easypost/models/shipment.rb +10 -0
- data/lib/easypost/models/tax_identifier.rb +6 -0
- data/lib/easypost/models/tracker.rb +5 -0
- data/lib/easypost/models/user.rb +5 -0
- data/lib/easypost/models/webhook.rb +6 -0
- data/lib/easypost/models.rb +36 -0
- data/lib/easypost/services/address.rb +50 -0
- data/lib/easypost/services/api_key.rb +8 -0
- data/lib/easypost/services/base.rb +27 -0
- data/lib/easypost/services/batch.rb +53 -0
- data/lib/easypost/services/beta_rate.rb +12 -0
- data/lib/easypost/services/beta_referral_customer.rb +40 -0
- data/lib/easypost/services/billing.rb +75 -0
- data/lib/easypost/services/carrier_account.rb +44 -0
- data/lib/easypost/services/carrier_metadata.rb +22 -0
- data/lib/easypost/services/carrier_type.rb +10 -0
- data/lib/easypost/services/customs_info.rb +17 -0
- data/lib/easypost/services/customs_item.rb +15 -0
- data/lib/easypost/services/end_shipper.rb +31 -0
- data/lib/easypost/services/event.rb +32 -0
- data/lib/easypost/services/insurance.rb +26 -0
- data/lib/easypost/services/order.rb +30 -0
- data/lib/easypost/services/parcel.rb +16 -0
- data/lib/easypost/services/pickup.rb +40 -0
- data/lib/easypost/services/rate.rb +8 -0
- data/lib/easypost/services/referral_customer.rb +103 -0
- data/lib/easypost/services/refund.rb +26 -0
- data/lib/easypost/services/report.rb +42 -0
- data/lib/easypost/services/scan_form.rb +25 -0
- data/lib/easypost/services/shipment.rb +106 -0
- data/lib/easypost/services/tracker.rb +38 -0
- data/lib/easypost/services/user.rb +66 -0
- data/lib/easypost/services/webhook.rb +34 -0
- data/lib/easypost/services.rb +33 -0
- data/lib/easypost/util.rb +160 -116
- data/lib/easypost/utilities/constants.rb +5 -0
- data/lib/easypost/utilities/json.rb +23 -0
- data/lib/easypost/utilities/static_mapper.rb +73 -0
- data/lib/easypost/utilities/system.rb +36 -0
- data/lib/easypost/version.rb +3 -1
- data/lib/easypost.rb +20 -143
- metadata +249 -46
- data/lib/easypost/address.rb +0 -58
- data/lib/easypost/api_key.rb +0 -2
- data/lib/easypost/batch.rb +0 -49
- data/lib/easypost/brand.rb +0 -9
- data/lib/easypost/carrier_account.rb +0 -5
- data/lib/easypost/carrier_type.rb +0 -2
- data/lib/easypost/customs_info.rb +0 -5
- data/lib/easypost/customs_item.rb +0 -5
- data/lib/easypost/error.rb +0 -31
- data/lib/easypost/event.rb +0 -7
- data/lib/easypost/insurance.rb +0 -2
- data/lib/easypost/object.rb +0 -151
- data/lib/easypost/order.rb +0 -28
- data/lib/easypost/parcel.rb +0 -2
- data/lib/easypost/pickup.rb +0 -26
- data/lib/easypost/pickup_rate.rb +0 -3
- data/lib/easypost/postage_label.rb +0 -2
- data/lib/easypost/print_job.rb +0 -2
- data/lib/easypost/printer.rb +0 -24
- data/lib/easypost/rate.rb +0 -2
- data/lib/easypost/refund.rb +0 -2
- data/lib/easypost/report.rb +0 -29
- data/lib/easypost/resource.rb +0 -75
- data/lib/easypost/scan_form.rb +0 -6
- data/lib/easypost/shipment.rb +0 -129
- data/lib/easypost/tax_identifier.rb +0 -2
- data/lib/easypost/tracker.rb +0 -7
- data/lib/easypost/user.rb +0 -56
- data/lib/easypost/webhook.rb +0 -29
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EasyPost::Hooks
|
|
4
|
+
def self.subscribe(type, name, block)
|
|
5
|
+
subscribers[type][name] = block
|
|
6
|
+
|
|
7
|
+
name
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.unsubscribe(type, name)
|
|
11
|
+
subscribers[type].delete(name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.unsubscribe_all(type)
|
|
15
|
+
subscribers.delete(type)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.notify(type, context)
|
|
19
|
+
subscribers[type].each_value { |subscriber| subscriber.call(context) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.any_subscribers?(type)
|
|
23
|
+
!subscribers[type].empty?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.subscribers
|
|
27
|
+
@subscribers ||= Hash.new { |hash, key| hash[key] = {} }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private_class_method :subscribers
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
require_relative 'hooks/request_context'
|
|
34
|
+
require_relative 'hooks/response_context'
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
class EasyPost::HttpClient
|
|
6
|
+
def initialize(base_url, config, custom_client_exec = nil)
|
|
7
|
+
@base_url = base_url
|
|
8
|
+
@config = config
|
|
9
|
+
@custom_client_exec = custom_client_exec
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Execute an HTTP request to the API.
|
|
13
|
+
def request(
|
|
14
|
+
method,
|
|
15
|
+
path,
|
|
16
|
+
headers = nil,
|
|
17
|
+
body = nil,
|
|
18
|
+
api_version = EasyPost::InternalUtilities::Constants::API_VERSION
|
|
19
|
+
)
|
|
20
|
+
# Remove leading slash from path.
|
|
21
|
+
path = path[1..] if path[0] == '/'
|
|
22
|
+
|
|
23
|
+
uri = URI.parse("#{@base_url}/#{api_version}/#{path}")
|
|
24
|
+
headers = @config[:headers].merge(headers || {})
|
|
25
|
+
serialized_body = JSON.dump(EasyPost::InternalUtilities.objects_to_ids(body)) if body
|
|
26
|
+
open_timeout = @config[:open_timeout]
|
|
27
|
+
read_timeout = @config[:read_timeout]
|
|
28
|
+
request_timestamp = Time.now
|
|
29
|
+
request_uuid = SecureRandom.uuid
|
|
30
|
+
|
|
31
|
+
if EasyPost::Hooks.any_subscribers?(:request)
|
|
32
|
+
request_context = EasyPost::Hooks::RequestContext.new(
|
|
33
|
+
method: method,
|
|
34
|
+
path: uri.to_s,
|
|
35
|
+
headers: headers,
|
|
36
|
+
request_body: body,
|
|
37
|
+
request_timestamp: request_timestamp,
|
|
38
|
+
request_uuid: request_uuid,
|
|
39
|
+
)
|
|
40
|
+
EasyPost::Hooks.notify(:request, request_context)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Execute the request, return the response.
|
|
44
|
+
|
|
45
|
+
response = if @custom_client_exec
|
|
46
|
+
@custom_client_exec.call(method, uri, headers, open_timeout, read_timeout, serialized_body)
|
|
47
|
+
else
|
|
48
|
+
default_request_execute(method, uri, headers, open_timeout, read_timeout, serialized_body)
|
|
49
|
+
end
|
|
50
|
+
response_timestamp = Time.now
|
|
51
|
+
|
|
52
|
+
if EasyPost::Hooks.any_subscribers?(:response)
|
|
53
|
+
response_context = {
|
|
54
|
+
http_status: nil,
|
|
55
|
+
method: method,
|
|
56
|
+
path: uri.to_s,
|
|
57
|
+
headers: nil,
|
|
58
|
+
response_body: nil,
|
|
59
|
+
request_timestamp: request_timestamp,
|
|
60
|
+
response_timestamp: response_timestamp,
|
|
61
|
+
client_response_object: response,
|
|
62
|
+
request_uuid: request_uuid,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# If using a custom HTTP client, the user will have to infer these from the raw
|
|
66
|
+
# client_response_object attribute
|
|
67
|
+
if response.is_a?(Net::HTTPResponse)
|
|
68
|
+
response_body = begin
|
|
69
|
+
JSON.parse(response.body)
|
|
70
|
+
rescue JSON::ParseError
|
|
71
|
+
response.body
|
|
72
|
+
end
|
|
73
|
+
response_context.merge!(
|
|
74
|
+
{
|
|
75
|
+
http_status: response.code.to_i,
|
|
76
|
+
headers: response.each_header.to_h,
|
|
77
|
+
response_body: response_body,
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
EasyPost::Hooks.notify(:response, EasyPost::Hooks::ResponseContext.new(**response_context))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
response
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def default_request_execute(method, uri, headers, open_timeout, read_timeout, body = nil)
|
|
89
|
+
# Create the request, set the headers and body if necessary.
|
|
90
|
+
request = Net::HTTP.const_get(method.capitalize).new(uri)
|
|
91
|
+
headers.each { |k, v| request[k] = v }
|
|
92
|
+
request.body = body if body
|
|
93
|
+
|
|
94
|
+
begin
|
|
95
|
+
# Attempt to make the request and return the response.
|
|
96
|
+
Net::HTTP.start(
|
|
97
|
+
uri.host,
|
|
98
|
+
uri.port,
|
|
99
|
+
use_ssl: true,
|
|
100
|
+
read_timeout: read_timeout,
|
|
101
|
+
open_timeout: open_timeout,
|
|
102
|
+
) do |http|
|
|
103
|
+
http.request(request)
|
|
104
|
+
end
|
|
105
|
+
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EHOSTUNREACH => e
|
|
106
|
+
# Raise a timeout error if the request times out.
|
|
107
|
+
raise EasyPost::Errors::TimeoutError.new(e.message)
|
|
108
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
109
|
+
# Raise an SSL error if the request fails due to an SSL error.
|
|
110
|
+
raise EasyPost::Errors::SslError.new(e.message)
|
|
111
|
+
rescue StandardError => e
|
|
112
|
+
# Raise an unknown HTTP error if anything else causes the request to fail to complete
|
|
113
|
+
# (this is different from processing 4xx/5xx errors from the API)
|
|
114
|
+
raise EasyPost::Errors::UnknownApiError.new(e.message)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EasyPost::InternalUtilities
|
|
4
|
+
# Convert a string to snake case
|
|
5
|
+
def self.to_snake_case(str)
|
|
6
|
+
str.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
7
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
8
|
+
.downcase
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Form-encode a multi-layer dictionary to a one-layer dictionary.
|
|
12
|
+
def self.form_encode_params(hash, parent_keys = [], parent_dict = {})
|
|
13
|
+
result = parent_dict or {}
|
|
14
|
+
keys = parent_keys or []
|
|
15
|
+
|
|
16
|
+
hash.each do |key, value|
|
|
17
|
+
if value.instance_of?(Hash)
|
|
18
|
+
keys << key
|
|
19
|
+
result = form_encode_params(value, keys, result)
|
|
20
|
+
else
|
|
21
|
+
dict_key = build_dict_key(keys + [key])
|
|
22
|
+
result[dict_key] = value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
result
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Build a dict key from a list of keys.
|
|
29
|
+
# Example: [code, number] -> code[number]
|
|
30
|
+
def self.build_dict_key(keys)
|
|
31
|
+
result = keys[0].to_s
|
|
32
|
+
|
|
33
|
+
keys[1..].each do |key|
|
|
34
|
+
result += "[#{key}]"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Converts an object to an object ID.
|
|
41
|
+
def self.objects_to_ids(obj)
|
|
42
|
+
case obj
|
|
43
|
+
when EasyPost::Models::EasyPostObject
|
|
44
|
+
{ id: obj.id }
|
|
45
|
+
when Hash
|
|
46
|
+
result = {}
|
|
47
|
+
obj.each { |k, v| result[k] = objects_to_ids(v) unless v.nil? }
|
|
48
|
+
result
|
|
49
|
+
when Array
|
|
50
|
+
obj.map { |v| objects_to_ids(v) }
|
|
51
|
+
else
|
|
52
|
+
obj
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Normalizes a list of strings.
|
|
57
|
+
def self.normalize_string_list(lst)
|
|
58
|
+
lst = lst.is_a?(String) ? lst.split(',') : Array(lst)
|
|
59
|
+
lst.map(&:to_s).map(&:downcase).map(&:strip)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
require_relative 'utilities/json'
|
|
64
|
+
require_relative 'utilities/system'
|
|
65
|
+
require_relative 'utilities/static_mapper'
|
|
66
|
+
require_relative 'utilities/constants'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
# The base class for all JSON objects in the library.
|
|
6
|
+
class EasyPost::Models::Object
|
|
7
|
+
def initialize(data)
|
|
8
|
+
@values = data
|
|
9
|
+
add_properties(data)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Convert to a string.
|
|
13
|
+
def to_s(*_args)
|
|
14
|
+
JSON.dump(@values)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Convert object to hash
|
|
18
|
+
def to_hash
|
|
19
|
+
JSON.parse(JSON.dump(@values))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Get element of an array.
|
|
23
|
+
def [](key)
|
|
24
|
+
@values[key.to_s]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Set the element of an array.
|
|
28
|
+
def []=(key, value)
|
|
29
|
+
send(:"#{key}=", value)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def add_properties(values)
|
|
35
|
+
values.each do |key, _|
|
|
36
|
+
define_singleton_method(key) { handle_value(@values[key]) } # getter
|
|
37
|
+
define_singleton_method("#{key}=") { |v| @values[key] = handle_value(v) } # setter
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def handle_value(val)
|
|
42
|
+
case val
|
|
43
|
+
when Hash
|
|
44
|
+
type = EasyPost::InternalUtilities::StaticMapper::BY_TYPE[val['object']] if val['object']
|
|
45
|
+
prefix = EasyPost::InternalUtilities::StaticMapper::BY_PREFIX[val['id'].split('_').first] if val['id']
|
|
46
|
+
cls = type || prefix || EasyPost::Models::EasyPostObject
|
|
47
|
+
cls.new(val)
|
|
48
|
+
when Array
|
|
49
|
+
val.map { |item| handle_value(item) }
|
|
50
|
+
else
|
|
51
|
+
val
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The base class for all API objects in the library that have an ID (plus optional timestamps).
|
|
57
|
+
class EasyPost::Models::EasyPostObject < EasyPost::Models::Object
|
|
58
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# EasyPost Error object.
|
|
4
|
+
class EasyPost::Models::Error
|
|
5
|
+
attr_reader :code, :field, :message
|
|
6
|
+
|
|
7
|
+
# Initialize a new EasyPost Error
|
|
8
|
+
def initialize(code, field = nil, message = nil)
|
|
9
|
+
@code = code
|
|
10
|
+
@field = field
|
|
11
|
+
@message = message
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Create an EasyPost Error from an API error response.
|
|
15
|
+
def self.from_api_error_response(data)
|
|
16
|
+
code = data['code']
|
|
17
|
+
field = data['field'] || nil
|
|
18
|
+
message = data['message'] || nil
|
|
19
|
+
EasyPost::Models::Error.new(code, field, message)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# An Insurance object represents insurance for packages purchased both via the EasyPost API as well
|
|
4
|
+
# as shipments purchased through third parties and later registered with EasyPost.
|
|
5
|
+
class EasyPost::Models::Insurance < EasyPost::Models::EasyPostObject
|
|
6
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The Order object represents a collection of packages and can be used for Multi-Piece Shipments.
|
|
4
|
+
class EasyPost::Models::Order < EasyPost::Models::EasyPostObject
|
|
5
|
+
# Get the lowest rate of an Order (can exclude by having `'!'` as the first element of your optional filter lists).
|
|
6
|
+
def lowest_rate(carriers = [], services = [])
|
|
7
|
+
EasyPost::Util.get_lowest_object_rate(self, carriers, services)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The Pickup object allows you to schedule a pickup from your carrier from your customer's residence or place of business.
|
|
4
|
+
class EasyPost::Models::Pickup < EasyPost::Models::EasyPostObject
|
|
5
|
+
# Get the lowest rate of a Pickup (can exclude by having `'!'` as the first element of your optional filter lists).
|
|
6
|
+
def lowest_rate(carriers = [], services = [])
|
|
7
|
+
EasyPost::Util.get_lowest_object_rate(self, carriers, services, 'pickup_rates')
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# A ScanForm can be created to speed up and simplify the carrier pickup process. The ScanForm is one document that can
|
|
4
|
+
# be scanned to mark all included tracking codes as "Accepted for Shipment" by the carrier.
|
|
5
|
+
class EasyPost::Models::ScanForm < EasyPost::Models::EasyPostObject
|
|
6
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The workhorse of the EasyPost API, a Shipment is made up of a "to" and "from" Address, the Parcel
|
|
4
|
+
# being shipped, and any customs forms required for international deliveries.
|
|
5
|
+
class EasyPost::Models::Shipment < EasyPost::Models::EasyPostObject
|
|
6
|
+
# Get the lowest rate of a Shipment (can exclude by having `'!'` as the first element of your optional filter lists).
|
|
7
|
+
def lowest_rate(carriers = [], services = [])
|
|
8
|
+
EasyPost::Util.get_lowest_object_rate(self, carriers, services)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# TaxIdentifiers are identifying numbers or IDs that are used to charge a specific party when
|
|
4
|
+
# dealing with the importing or exporting of good across international borders.
|
|
5
|
+
class EasyPost::Models::TaxIdentifier < EasyPost::Models::EasyPostObject
|
|
6
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Each Webhook contains the url which EasyPost will notify whenever an object in our system updates. Several types of objects are processed
|
|
4
|
+
# asynchronously in the EasyPost system, so whenever an object updates, an Event is sent via HTTP POST to each configured webhook URL.
|
|
5
|
+
class EasyPost::Models::Webhook < EasyPost::Models::EasyPostObject
|
|
6
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EasyPost::Models
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
require_relative 'models/base' # Must be imported first before the rest of child models
|
|
7
|
+
require_relative 'models/address'
|
|
8
|
+
require_relative 'models/api_key'
|
|
9
|
+
require_relative 'models/batch'
|
|
10
|
+
require_relative 'models/brand'
|
|
11
|
+
require_relative 'models/carbon_offset'
|
|
12
|
+
require_relative 'models/carrier_account'
|
|
13
|
+
require_relative 'models/carrier_type'
|
|
14
|
+
require_relative 'models/customs_info'
|
|
15
|
+
require_relative 'models/customs_item'
|
|
16
|
+
require_relative 'models/end_shipper'
|
|
17
|
+
require_relative 'models/error'
|
|
18
|
+
require_relative 'models/event'
|
|
19
|
+
require_relative 'models/insurance'
|
|
20
|
+
require_relative 'models/order'
|
|
21
|
+
require_relative 'models/parcel'
|
|
22
|
+
require_relative 'models/payload'
|
|
23
|
+
require_relative 'models/payment_method'
|
|
24
|
+
require_relative 'models/pickup_rate'
|
|
25
|
+
require_relative 'models/pickup'
|
|
26
|
+
require_relative 'models/postage_label'
|
|
27
|
+
require_relative 'models/rate'
|
|
28
|
+
require_relative 'models/referral'
|
|
29
|
+
require_relative 'models/refund'
|
|
30
|
+
require_relative 'models/report'
|
|
31
|
+
require_relative 'models/scan_form'
|
|
32
|
+
require_relative 'models/shipment'
|
|
33
|
+
require_relative 'models/tax_identifier'
|
|
34
|
+
require_relative 'models/tracker'
|
|
35
|
+
require_relative 'models/user'
|
|
36
|
+
require_relative 'models/webhook'
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class EasyPost::Services::Address < EasyPost::Services::Service
|
|
4
|
+
MODEL_CLASS = EasyPost::Models::Address
|
|
5
|
+
|
|
6
|
+
# Create an address.
|
|
7
|
+
def create(params = {})
|
|
8
|
+
address = params.reject { |k, _| [:verify, :verify_strict].include?(k) }
|
|
9
|
+
|
|
10
|
+
wrapped_params = { address: address }
|
|
11
|
+
|
|
12
|
+
if params[:verify]
|
|
13
|
+
wrapped_params[:verify] = params[:verify]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if params[:verify_strict]
|
|
17
|
+
wrapped_params[:verify_strict] = params[:verify_strict]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@client.make_request(:post, 'addresses', MODEL_CLASS, params)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Create and verify an Address in one call.
|
|
24
|
+
def create_and_verify(params = {})
|
|
25
|
+
wrapped_params = {}
|
|
26
|
+
wrapped_params[:address] = params
|
|
27
|
+
|
|
28
|
+
@client.make_request(:post, 'addresses/create_and_verify', MODEL_CLASS, wrapped_params).address
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Verify an Address.
|
|
32
|
+
def verify(id)
|
|
33
|
+
@client.make_request(:get, "addresses/#{id}/verify", MODEL_CLASS).address
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Retrieve an Address.
|
|
37
|
+
def retrieve(id)
|
|
38
|
+
@client.make_request(:get, "addresses/#{id}", MODEL_CLASS)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Retrieve all Addresses.
|
|
42
|
+
def all(filters = {})
|
|
43
|
+
@client.make_request(:get, 'addresses', MODEL_CLASS, filters)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Get the next page of addresses.
|
|
47
|
+
def get_next_page(collection, page_size = nil)
|
|
48
|
+
get_next_page_helper(collection, collection.addresses, 'addresses', MODEL_CLASS, page_size)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The base class for all services in the library.
|
|
4
|
+
class EasyPost::Services::Service
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
# Get next page of an object collection
|
|
12
|
+
def get_next_page_helper(collection, current_page_items, endpoint, cls, page_size = nil)
|
|
13
|
+
has_more = collection.has_more || false
|
|
14
|
+
unless !has_more || current_page_items.nil? || current_page_items.empty?
|
|
15
|
+
params = {}
|
|
16
|
+
params[:before_id] = current_page_items.last.id
|
|
17
|
+
unless page_size.nil?
|
|
18
|
+
params[:page_size] = page_size
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
@client.make_request(:get, endpoint, cls, params)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# issue with getting the next page
|
|
25
|
+
raise EasyPost::Errors::EndOfPaginationError.new
|
|
26
|
+
end
|
|
27
|
+
end
|