avatax-ruby 0.0.1
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 +11 -0
- data/.rubocop.yml +248 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +157 -0
- data/Rakefile +9 -0
- data/avatax.gemspec +42 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +6 -0
- data/lib/avatax.rb +30 -0
- data/lib/avatax/api/accounts.rb +86 -0
- data/lib/avatax/api/addresses.rb +14 -0
- data/lib/avatax/api/base.rb +18 -0
- data/lib/avatax/api/batches.rb +6 -0
- data/lib/avatax/api/companies.rb +6 -0
- data/lib/avatax/api/contacts.rb +6 -0
- data/lib/avatax/api/definitions.rb +6 -0
- data/lib/avatax/api/items.rb +6 -0
- data/lib/avatax/api/locations.rb +6 -0
- data/lib/avatax/api/nexus.rb +6 -0
- data/lib/avatax/api/settings.rb +6 -0
- data/lib/avatax/api/subscriptions.rb +6 -0
- data/lib/avatax/api/tax_codes.rb +6 -0
- data/lib/avatax/api/tax_rates.rb +28 -0
- data/lib/avatax/api/tax_rules.rb +6 -0
- data/lib/avatax/api/transactions.rb +171 -0
- data/lib/avatax/api/upcs.rb +6 -0
- data/lib/avatax/api/users.rb +6 -0
- data/lib/avatax/api/utilities.rb +6 -0
- data/lib/avatax/client.rb +81 -0
- data/lib/avatax/code.rb +13 -0
- data/lib/avatax/configuration.rb +35 -0
- data/lib/avatax/response.rb +8 -0
- data/lib/avatax/version.rb +3 -0
- metadata +236 -0
data/Rakefile
ADDED
data/avatax.gemspec
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'avatax/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "avatax-ruby"
|
|
8
|
+
spec.version = Avatax::VERSION
|
|
9
|
+
spec.authors = ["Taylor Scott"]
|
|
10
|
+
spec.email = ["tscott@deseretbook.com"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Ruby client for Avatax}
|
|
13
|
+
spec.description = %q{Ruby client for Avatax}
|
|
14
|
+
spec.homepage = "https://github.com/skukx/avatax"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
19
|
+
if spec.respond_to?(:metadata)
|
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
|
21
|
+
else
|
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
26
|
+
spec.bindir = "exe"
|
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
|
+
spec.require_paths = ["lib"]
|
|
29
|
+
|
|
30
|
+
spec.add_runtime_dependency 'activesupport'
|
|
31
|
+
spec.add_runtime_dependency 'faraday'
|
|
32
|
+
spec.add_runtime_dependency 'faraday_middleware'
|
|
33
|
+
|
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
|
35
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
36
|
+
spec.add_development_dependency 'rspec'
|
|
37
|
+
spec.add_development_dependency 'rspec-its'
|
|
38
|
+
spec.add_development_dependency 'vcr'
|
|
39
|
+
spec.add_development_dependency 'webmock'
|
|
40
|
+
spec.add_development_dependency 'rubocop'
|
|
41
|
+
spec.add_development_dependency 'pry'
|
|
42
|
+
end
|
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "avatax"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/circle.yml
ADDED
data/lib/avatax.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'active_support/all'
|
|
2
|
+
require 'faraday'
|
|
3
|
+
require 'faraday_middleware'
|
|
4
|
+
|
|
5
|
+
require 'avatax/version'
|
|
6
|
+
require 'avatax/code'
|
|
7
|
+
require 'avatax/response'
|
|
8
|
+
|
|
9
|
+
require 'avatax/api/base'
|
|
10
|
+
require 'avatax/api/accounts'
|
|
11
|
+
require 'avatax/api/addresses'
|
|
12
|
+
require 'avatax/api/batches'
|
|
13
|
+
require 'avatax/api/companies'
|
|
14
|
+
require 'avatax/api/contacts'
|
|
15
|
+
require 'avatax/api/definitions'
|
|
16
|
+
require 'avatax/api/items'
|
|
17
|
+
require 'avatax/api/locations'
|
|
18
|
+
require 'avatax/api/nexus'
|
|
19
|
+
require 'avatax/api/settings'
|
|
20
|
+
require 'avatax/api/subscriptions'
|
|
21
|
+
require 'avatax/api/tax_codes'
|
|
22
|
+
require 'avatax/api/tax_rates'
|
|
23
|
+
require 'avatax/api/tax_rules'
|
|
24
|
+
require 'avatax/api/transactions'
|
|
25
|
+
require 'avatax/api/upcs'
|
|
26
|
+
require 'avatax/api/users'
|
|
27
|
+
require 'avatax/api/utilities'
|
|
28
|
+
|
|
29
|
+
require 'avatax/configuration'
|
|
30
|
+
require 'avatax/client'
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module Avatax
|
|
2
|
+
module Api
|
|
3
|
+
##
|
|
4
|
+
# Accounts Client
|
|
5
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/
|
|
6
|
+
#
|
|
7
|
+
class Accounts < Base
|
|
8
|
+
##
|
|
9
|
+
# Activate an account
|
|
10
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/#ActivateAccount
|
|
11
|
+
#
|
|
12
|
+
# @param account_id [String, Integer] The ID of the account to activate.
|
|
13
|
+
# @param args [Hash] The arguments for avatax.
|
|
14
|
+
# @return [Avatax::Response]
|
|
15
|
+
#
|
|
16
|
+
def activate(account_id, args = {})
|
|
17
|
+
post_for(:activate, account_id, args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Get configuration for an account
|
|
22
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/#GetAccountConfiguration
|
|
23
|
+
#
|
|
24
|
+
# @param account_id [String, Integer] The ID of the account to activate.
|
|
25
|
+
# @param args [Hash] The arguments for avatax.
|
|
26
|
+
# @return [Avatax::Response]
|
|
27
|
+
#
|
|
28
|
+
def configuration(account_id, args = {})
|
|
29
|
+
get_for(:configuration, account_id, args)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Update configuration for an account
|
|
34
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/#SetAccountConfiguration
|
|
35
|
+
#
|
|
36
|
+
# @param account_id [String, Integer] The ID of the account to activate.
|
|
37
|
+
# @param args [Hash] The arguments for avatax.
|
|
38
|
+
# @return [Avatax::Response]
|
|
39
|
+
#
|
|
40
|
+
def update_configuration(account_id, args = {})
|
|
41
|
+
post_for(:configuration, account_id, args)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Reset the license key for an account.
|
|
46
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/#AccountResetLicenseKey
|
|
47
|
+
#
|
|
48
|
+
# @param account_id [String, Integer] The ID of the account to activate.
|
|
49
|
+
# @param args [Hash] The arguments for avatax.
|
|
50
|
+
# @return [Avatax::Response]
|
|
51
|
+
#
|
|
52
|
+
def reset_license_key(account_id, args = {})
|
|
53
|
+
post_for(:resetlicensekey, account_id, args)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Get an account.
|
|
58
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Accounts/#GetAccount
|
|
59
|
+
#
|
|
60
|
+
# @param account_id [String, Integer] The ID of the account to activate.
|
|
61
|
+
# @param args [Hash] The arguments for avatax.
|
|
62
|
+
# @return [Avatax::Response]
|
|
63
|
+
#
|
|
64
|
+
def get(account_id, args = {})
|
|
65
|
+
get_for(nil, account_id, args)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def get_for(endpoint, account_id, args)
|
|
71
|
+
request_for(:get, endpoint, account_id, args)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def post_for(endpoint, account_id, args)
|
|
75
|
+
request_for(:post, endpoint, account_id, args)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def request_for(method, endpoint, account_id, args)
|
|
79
|
+
raise ArgumentError, 'account_id is required' if account_id.blank?
|
|
80
|
+
|
|
81
|
+
resp = connection.send method, "/api/v2/accounts/#{account_id}/#{endpoint}", args
|
|
82
|
+
handle_response(resp)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Avatax
|
|
2
|
+
module Api
|
|
3
|
+
class Addresses < Base
|
|
4
|
+
##
|
|
5
|
+
# Validate an address
|
|
6
|
+
# @see http://developer.avalara.com/avatax/api-reference/tax/v2/Addresses/#ApiV2AddressesResolvePost
|
|
7
|
+
#
|
|
8
|
+
def validate(args = {})
|
|
9
|
+
resp = connection.post '/api/v2/addresses/resolve', args
|
|
10
|
+
handle_response(resp)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Avatax
|
|
2
|
+
module Api
|
|
3
|
+
class Base
|
|
4
|
+
attr_reader :connection
|
|
5
|
+
|
|
6
|
+
def initialize(connection)
|
|
7
|
+
@connection = connection
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
protected
|
|
11
|
+
|
|
12
|
+
def handle_response(response)
|
|
13
|
+
# Wrap in our own response class
|
|
14
|
+
Avatax::Response.new response
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Avatax
|
|
2
|
+
module Api
|
|
3
|
+
class TaxRates < Base
|
|
4
|
+
BY_ADDRESS_METHOD = :by_address
|
|
5
|
+
BY_POSTAL_CODE_METHOD = :by_postal_code
|
|
6
|
+
|
|
7
|
+
VALID_METHODS = [BY_ADDRESS_METHOD, BY_POSTAL_CODE_METHOD]
|
|
8
|
+
|
|
9
|
+
def get(method, args = {})
|
|
10
|
+
unless VALID_METHODS.include?(method.to_sym)
|
|
11
|
+
raise ArgumentError, 'method must be one of :bt_address or :by_postal_code'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
handle_response(send("get_#{method}", args))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def get_by_address(args)
|
|
20
|
+
connection.get '/api/v2/taxrates/byaddress', args
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def get_by_postal_code(args)
|
|
24
|
+
connection.get '/api/v2/taxrates/bypostalcode', args
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module Avatax
|
|
2
|
+
module Api
|
|
3
|
+
##
|
|
4
|
+
# Transactions client
|
|
5
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/
|
|
6
|
+
#
|
|
7
|
+
class Transactions < Base
|
|
8
|
+
##
|
|
9
|
+
# Get all transactions within a company.
|
|
10
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsGet
|
|
11
|
+
#
|
|
12
|
+
# @param company_code [String] The company_code in avatax.
|
|
13
|
+
# @param args [Hash] Arguments for avatax.
|
|
14
|
+
# @return [Avatax::Response]
|
|
15
|
+
#
|
|
16
|
+
def all(company_code, args = {})
|
|
17
|
+
raise ArgumentError, 'company_code is required' if company_code.blank?
|
|
18
|
+
|
|
19
|
+
resp = connection.get "/api/v2/companies/#{company_code}/transactions/", args
|
|
20
|
+
handle_response(resp)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Get a transaction by code
|
|
25
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeGet
|
|
26
|
+
#
|
|
27
|
+
# @param company_code [String] The company_code in avatax.
|
|
28
|
+
# @param transaction_code [String] The avatax transaction code.
|
|
29
|
+
# @param args [Hash] Arguments for avatax.
|
|
30
|
+
# @return [Avatax::Response]
|
|
31
|
+
#
|
|
32
|
+
def find_by_code(company_code, transaction_code, args = {})
|
|
33
|
+
raise ArgumentError, 'company_code is required' if company_code.blank?
|
|
34
|
+
raise ArgumentError, 'transaction_code is required' if transaction_code.blank?
|
|
35
|
+
|
|
36
|
+
resp = connection.get "/api/v2/companies/#{company_code}/transactions/#{transaction_code}", args
|
|
37
|
+
handle_response(resp)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Get a transaction by code
|
|
42
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2TransactionsByIdGet
|
|
43
|
+
#
|
|
44
|
+
# @param company_code [String] The company_code in avatax.
|
|
45
|
+
# @param transaction_code [String] The avatax transaction ID.
|
|
46
|
+
# @param args [Hash] Arguments for avatax.
|
|
47
|
+
# @return [Avatax::Response]
|
|
48
|
+
#
|
|
49
|
+
def find_by_id(transaction_id, args = {})
|
|
50
|
+
raise ArgumentError, 'transaction_id is required' if transaction_id.blank?
|
|
51
|
+
|
|
52
|
+
resp = connection.get "/api/v2/transactions/#{transaction_id}", args
|
|
53
|
+
handle_response(resp)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Adjust a transaction
|
|
58
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeAdjustPost
|
|
59
|
+
#
|
|
60
|
+
# @param company_code [String] The company_code in avatax.
|
|
61
|
+
# @param transaction_code [String] The avatax transaction code.
|
|
62
|
+
# @param args [Hash] Arguments for avatax.
|
|
63
|
+
# @return [Avatax::Response]
|
|
64
|
+
#
|
|
65
|
+
def adjust(company_code, transaction_code, args = {})
|
|
66
|
+
post_for(:adjust, company_code, transaction_code, args)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Change a transaction code
|
|
71
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeChangecodePost
|
|
72
|
+
#
|
|
73
|
+
# @param company_code [String] The company_code in avatax.
|
|
74
|
+
# @param transaction_code [String] The current avatax transaction code.
|
|
75
|
+
# @param args [Hash] Arguments for avatax.
|
|
76
|
+
# @return [Avatax::Response]
|
|
77
|
+
#
|
|
78
|
+
def change_code(company_code, transaction_code, args = {})
|
|
79
|
+
post_for(:changecode, company_code, transaction_code, args)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Commit a transaction
|
|
84
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeCommitPost
|
|
85
|
+
#
|
|
86
|
+
# @param company_code [String] The company_code in avatax.
|
|
87
|
+
# @param transaction_code [String] The current avatax transaction code.
|
|
88
|
+
# @param args [Hash] Arguments for avatax.
|
|
89
|
+
# @return [Avatax::Response]
|
|
90
|
+
#
|
|
91
|
+
def commit(company_code, transaction_code, args = {})
|
|
92
|
+
args.reverse_merge(commit: true)
|
|
93
|
+
post_for(:commit, company_code, transaction_code, args)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Settle a transaction
|
|
98
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeSettlePost
|
|
99
|
+
#
|
|
100
|
+
# @param company_code [String] The company_code in avatax.
|
|
101
|
+
# @param transaction_code [String] The current avatax transaction code.
|
|
102
|
+
# @param args [Hash] Arguments for avatax.
|
|
103
|
+
# @return [Avatax::Response]
|
|
104
|
+
#
|
|
105
|
+
def settle(company_code, transaction_code, args = {})
|
|
106
|
+
post_for(:settle, company_code, transaction_code, args)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# Verify a transaction
|
|
111
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeVerifyPost
|
|
112
|
+
#
|
|
113
|
+
# @param company_code [String] The company_code in avatax.
|
|
114
|
+
# @param transaction_code [String] The current avatax transaction code.
|
|
115
|
+
# @param args [Hash] Arguments for avatax.
|
|
116
|
+
# @return [Avatax::Response]
|
|
117
|
+
#
|
|
118
|
+
def verify(company_code, transaction_code, args = {})
|
|
119
|
+
post_for(:verify, company_code, transaction_code, args)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# Void a transaction
|
|
124
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2CompaniesByCompanyCodeTransactionsByTransactionCodeVoidPost
|
|
125
|
+
#
|
|
126
|
+
# @param company_code [String] The company_code in avatax.
|
|
127
|
+
# @param transaction_code [String] The current avatax transaction code.
|
|
128
|
+
# @param args [Hash] Arguments for avatax.
|
|
129
|
+
# @return [Avatax::Response]
|
|
130
|
+
#
|
|
131
|
+
def void(company_code, transaction_code, args = {})
|
|
132
|
+
args.reverse_merge!(code: Avatax::Code::DOC_VOIDED)
|
|
133
|
+
post_for(:void, company_code, transaction_code, args)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Create a transaction
|
|
138
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#ApiV2TransactionsCreatePost
|
|
139
|
+
#
|
|
140
|
+
# @param args [Hash] Arguments for avatax.
|
|
141
|
+
# @return [Avatax::Response]
|
|
142
|
+
#
|
|
143
|
+
def create(args = {})
|
|
144
|
+
resp = connection.post '/api/v2/transactions/create', args
|
|
145
|
+
handle_response(resp)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
##
|
|
149
|
+
# Create or Adjust a transaction if transaction already exists.
|
|
150
|
+
# @see https://developer.avalara.com/avatax/api-reference/tax/v2/Transactions/#CreateOrAdjustTransaction
|
|
151
|
+
#
|
|
152
|
+
# @param args [Hash] Arguments for avatax.
|
|
153
|
+
# @return [Avatax::Response]
|
|
154
|
+
#
|
|
155
|
+
def create_or_adjust(args = {})
|
|
156
|
+
resp = connection.post '/api/v2/transactions/createoradjust', args
|
|
157
|
+
handle_response(resp)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
private
|
|
161
|
+
|
|
162
|
+
def post_for(endpoint, company_code, transaction_code, args)
|
|
163
|
+
raise ArgumentError, 'company_code is required' if company_code.blank?
|
|
164
|
+
raise ArgumentError, 'transaction_code is required' if transaction_code.blank?
|
|
165
|
+
|
|
166
|
+
resp = connection.post "/api/v2/companies/#{company_code}/transactions/#{transaction_code}/#{endpoint}", args
|
|
167
|
+
handle_response(resp)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|