diff --git a/app/controllers/spree/admin/users_controller_decorator.rb b/app/controllers/spree/admin/users_controller_decorator.rb new file mode 100644 index 00000000..0dc52c8a --- /dev/null +++ b/app/controllers/spree/admin/users_controller_decorator.rb @@ -0,0 +1,11 @@ +Spree::Admin::UsersController.class_eval do + def avalara_information + if request.put? + if @user.update_attributes(user_params) + flash.now[:success] = Spree.t(:account_updated) + end + end + + render :avalara_information + end +end diff --git a/app/models/solidus_avatax_certified/address.rb b/app/models/solidus_avatax_certified/address.rb index 403d267c..a11baa19 100644 --- a/app/models/solidus_avatax_certified/address.rb +++ b/app/models/solidus_avatax_certified/address.rb @@ -62,7 +62,7 @@ def origin_ship_addresses end def validate - return 'Address validation disabled' unless address_validation_enabled? + return 'Address validation disabled' unless @ship_address.validation_enabled? return @ship_address if @ship_address.nil? address_hash = { @@ -77,14 +77,6 @@ def validate validation_response(address_hash) end - def country_enabled? - enabled_countries.include?(@ship_address.country.try(:name)) - end - - def address_validation_enabled? - Spree::AvalaraPreference.address_validation.is_true? && country_enabled? - end - private def validation_response(address) @@ -94,19 +86,9 @@ def validation_response(address) http.verify_mode = OpenSSL::SSL::VERIFY_NONE res = http.get(uri.request_uri, 'Authorization' => credential) - response = JSON.parse(res.body) - address = response['Address'] + logger.debug res - if address['City'] != @ship_address.city || address['Region'] != @ship_address.state.abbr - response['ResultCode'] = 'Error' - response['Messages'] = [ - { - 'Summary' => "Did you mean #{address['Line1']}, #{address['City']}, #{address['Region']}, #{address['PostalCode']}?" - } - ] - end - - return response + JSON.parse(res.body) rescue => e "error in address validation: #{e}" end @@ -131,10 +113,6 @@ def account_number Spree::AvalaraPreference.account.value end - def enabled_countries - Spree::AvalaraPreference.validation_enabled_countries_array - end - def logger @logger ||= SolidusAvataxCertified::AvataxLog.new('avalara_order_addresses', 'SolidusAvataxCertified::Address', "Building Addresses for Order#: #{order.number}") end diff --git a/app/models/solidus_avatax_certified/preference_updater.rb b/app/models/solidus_avatax_certified/preference_updater.rb index bd8e4cf0..a01076d6 100644 --- a/app/models/solidus_avatax_certified/preference_updater.rb +++ b/app/models/solidus_avatax_certified/preference_updater.rb @@ -17,7 +17,7 @@ def update def update_stored_preferences Spree::AvalaraPreference.storable_envs.each do |preference| - if !ENV.fetch("AVATAX_#{preference.name.upcase}").nil? + if !ENV["AVATAX_#{preference.name.upcase}"].blank? update_value(preference, ENV["AVATAX_#{preference.name.upcase}"]) else update_value(preference, @avatax_preferences[preference.name.downcase]) diff --git a/app/models/spree/address_decorator.rb b/app/models/spree/address_decorator.rb new file mode 100644 index 00000000..c21e039a --- /dev/null +++ b/app/models/spree/address_decorator.rb @@ -0,0 +1,13 @@ +Spree::Address.class_eval do + def validation_enabled? + Spree::AvalaraPreference.address_validation.is_true? && country_validation_enabled? + end + + def country_validation_enabled? + Spree::Address.validation_enabled_countries.include?(country.try(:name)) + end + + def self.validation_enabled_countries + Spree::AvalaraPreference.validation_enabled_countries_array + end +end diff --git a/app/models/spree/avalara_preference.rb b/app/models/spree/avalara_preference.rb index ac9a7463..aa85e93f 100644 --- a/app/models/spree/avalara_preference.rb +++ b/app/models/spree/avalara_preference.rb @@ -45,6 +45,10 @@ def self.address_validation find_by(name: 'address_validation') end + def self.refuse_checkout_address_validation_error + find_by(name: 'refuse_checkout_address_validation_error') + end + def self.tax_calculation find_by(name: 'tax_calculation') end diff --git a/app/models/spree/avalara_transaction.rb b/app/models/spree/avalara_transaction.rb index 7c78eb6f..74fda00b 100644 --- a/app/models/spree/avalara_transaction.rb +++ b/app/models/spree/avalara_transaction.rb @@ -74,16 +74,6 @@ def post_order_to_avalara(commit = false, invoice_detail = nil) avatax_address = SolidusAvataxCertified::Address.new(order) avatax_line = SolidusAvataxCertified::Line.new(order, invoice_detail) - response = avatax_address.validate - - unless response.nil? - if response['ResultCode'] == 'Success' - logger.info('Address Validation Success') - else - logger.info('Address Validation Failed') - end - end - doc_date = order.completed? ? order.completed_at.strftime('%F') : Date.today.strftime('%F') gettaxes = { @@ -161,7 +151,7 @@ def customer_code end def avatax_client_version - AVATAX_CLIENT_VERSION || 'SolidusV1.2.0-ExtV0.0.1' + AVATAX_CLIENT_VERSION || 'a0o33000004FH8l' end def document_committing_enabled? diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index d77d7669..8afc9bc5 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -7,6 +7,9 @@ self.state_machine.before_transition :to => :canceled, :do => :cancel_avalara, :if => :avalara_eligible? + self.state_machine.before_transition :to => :delivery, + :do => :validate_ship_address, + :if => :address_validation_enabled? def avalara_eligible? Spree::AvalaraPreference.iseligible.is_true? @@ -41,6 +44,19 @@ def avalara_capture_finalize @rtn_tax end + def validate_ship_address + avatax_address = SolidusAvataxCertified::Address.new(self) + response = avatax_address.validate + + return response if response['ResultCode'] == 'Success' + return response if !Spree::AvalaraPreference.refuse_checkout_address_validation_error.is_true? + + messages = response['Messages'].each do |message| + errors.add(:address_validation_failure, message['Summary']) + end + return false + end + def avatax_cache_key key = ['Spree::Order'] key << self.number @@ -57,6 +73,12 @@ def stock_locations Spree::StockLocation.where(id: stock_loc_ids) end + def address_validation_enabled? + return false if ship_address.nil? + + ship_address.validation_enabled? + end + def logger @logger ||= SolidusAvataxCertified::AvataxLog.new('avalara_order', 'order class', 'start order processing') end diff --git a/app/views/spree/admin/avatax_settings/edit.html.erb b/app/views/spree/admin/avatax_settings/edit.html.erb index e282a621..4f20ea8e 100644 --- a/app/views/spree/admin/avatax_settings/edit.html.erb +++ b/app/views/spree/admin/avatax_settings/edit.html.erb @@ -36,10 +36,6 @@

-

-
- -

@@ -65,15 +61,20 @@ <%= check_box_tag('settings[log_to_stdout]','yes' , Spree::AvalaraPreference.log_to_stdout.value, :class => 'avatax') %>

- +
<%= t('avatax_address_validation') %>


<%= check_box_tag('settings[address_validation]','yes' , Spree::AvalaraPreference.address_validation.value, :class => 'avatax') %>

+

+
+ <%= check_box_tag('settings[refuse_checkout_address_validation_error]','yes' , Spree::AvalaraPreference.refuse_checkout_address_validation_error.value, :class => 'avatax') %> +

-
+ +
<%= t('avatax_address_validation_enabled_countries') %>

<% current_countries = Spree::Country.where(name: Spree::AvalaraPreference.validation_enabled_countries_array) %> diff --git a/app/views/spree/admin/avatax_settings/show.html.erb b/app/views/spree/admin/avatax_settings/show.html.erb index 0ce9b213..24ce1085 100644 --- a/app/views/spree/admin/avatax_settings/show.html.erb +++ b/app/views/spree/admin/avatax_settings/show.html.erb @@ -42,6 +42,10 @@ <%= t("enable_avatax_address_validation") %>: <%= Spree::AvalaraPreference.address_validation.value %> + + Refuse Checkout if Address Validation Fails + <%= Spree::AvalaraPreference.refuse_checkout_address_validation_error.value %> + <%= t("avatax_address_validation_enabled_countries") %>: <% address_validated_countries = Spree::AvalaraPreference.validation_enabled_countries_array %> @@ -63,10 +67,6 @@ <%= t("enable_avatax_document_committing") %>: <%= Spree::AvalaraPreference.document_commit.value %> - - <%= t("client_version") %>: - <%= AVATAX_CLIENT_VERSION %> - <%= t("business_address") %>: diff --git a/app/views/spree/admin/users/avalara_information.html.erb b/app/views/spree/admin/users/avalara_information.html.erb index bfbcd6e8..67bfee28 100644 --- a/app/views/spree/admin/users/avalara_information.html.erb +++ b/app/views/spree/admin/users/avalara_information.html.erb @@ -13,17 +13,18 @@

- <%= form_for [:admin, @user], as: :user, url: admin_user_url(@user), method: :put do |f| %> + <%= form_for [:admin, @user], as: :user, url: avalara_information_admin_user_url(@user), method: :put do |f| %>
+ <% use_codes_list = Spree::AvalaraEntityUseCode.all.map {|use_code| ["#{use_code.use_code}) #{use_code.use_code_description}", use_code.id]} %>
<%= f.field_container :avalara_entity_use_code_id do %> <%= label_tag :avalara_entity_use_code_id, t(:avalara_entity_use_code) %>
- <%= hidden_field_tag 'user[avalara_entity_use_code_id]', f.object.avalara_entity_use_code_id , :class => "use_code_picker fullwidth" %> + <%= f.select(:avalara_entity_use_code_id, use_codes_list) %> <% end %>
@@ -33,9 +34,11 @@ <% end %>



-
- <%= render :partial => 'spree/admin/shared/edit_resource_links', :locals => { :collection_url => admin_users_url } %> -
+ <% if can?(:update, @user) %> +
+ <%= render :partial => 'spree/admin/shared/edit_resource_links', :locals => { :collection_url => admin_users_url } %> +
+ <% end %>
<% end %>
diff --git a/config/initializers/avatax.rb b/config/initializers/avatax.rb index 0d6f8be5..4a42af17 100644 --- a/config/initializers/avatax.rb +++ b/config/initializers/avatax.rb @@ -1,6 +1,6 @@ gem_version = File.read(File.expand_path('../../../GEM_VERSION',__FILE__)).strip solidus_version = File.read(File.expand_path('../../../SOLIDUS_VERSION',__FILE__)).strip -AVATAX_CLIENT_VERSION = "SolidusV#{solidus_version}-ExtV#{gem_version}" +AVATAX_CLIENT_VERSION = "a0o33000004FH8l" AVATAX_SERVICEPATH_ADDRESS = '/1.0/address/' AVATAX_SERVICEPATH_TAX = '/1.0/tax/' diff --git a/config/routes.rb b/config/routes.rb index 3c1765ce..ee947dca 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,7 @@ resources :users do member do get :avalara_information + put :avalara_information end end end diff --git a/lib/solidus_avatax_certified/preference_seeder.rb b/lib/solidus_avatax_certified/preference_seeder.rb index 495b3a1d..0c07fb38 100644 --- a/lib/solidus_avatax_certified/preference_seeder.rb +++ b/lib/solidus_avatax_certified/preference_seeder.rb @@ -1,6 +1,6 @@ module SolidusAvataxCertified class PreferenceSeeder - BOOLEAN_PREFERENCES = ['iseligible', 'log', 'address_validation', 'tax_calculation', 'document_commit', 'log_to_stdout'].freeze + BOOLEAN_PREFERENCES = ['iseligible', 'log', 'address_validation', 'tax_calculation', 'document_commit', 'log_to_stdout', 'refuse_checkout_address_validation_error'].freeze STORABLE_ENV_PREFERENCES = ['company_code', 'endpoint', 'account', 'license_key'].freeze class << self @@ -31,7 +31,7 @@ def stored_env_prefs def boolean_prefs BOOLEAN_PREFERENCES.each do |preference| - if preference == 'log_to_stdout' + if ['refuse_checkout_address_validation_error', 'log_to_stdout'].include?(preference) pref = Spree::AvalaraPreference.new(name: preference, value: 'false', object_type: 'boolean') else pref = Spree::AvalaraPreference.new(name: preference, value: 'true', object_type: 'boolean') diff --git a/spec/models/solidus_avatax_certified/address_spec.rb b/spec/models/solidus_avatax_certified/address_spec.rb index 5f29545f..f0e808d9 100644 --- a/spec/models/solidus_avatax_certified/address_spec.rb +++ b/spec/models/solidus_avatax_certified/address_spec.rb @@ -66,11 +66,11 @@ result = address_lines.validate expect(address_lines.validate).to eq("Address validation disabled") end - end - describe '#country_enabled?' do - it 'returns true if the current country is enabled' do - expect(address_lines.country_enabled?).to be_truthy + it 'fails when information is incorrect' do + order.ship_address.update_attributes(city: nil) + + expect(address_lines.validate['ResultCode']).to eq('Error') end end end diff --git a/spec/models/spree/address_decorator_spec.rb b/spec/models/spree/address_decorator_spec.rb new file mode 100644 index 00000000..80ea6715 --- /dev/null +++ b/spec/models/spree/address_decorator_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe Spree::Address, type: :model do + let(:address) { create(:address) } + + describe '#validation_enabled?' do + it 'returns true if preference is true and country validation is enabled' do + Spree::AvalaraPreference.address_validation.update_attributes(value: 'true') + Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada') + + expect(address.validation_enabled?).to be_truthy + end + + it 'returns false if address validation preference is false' do + Spree::AvalaraPreference.address_validation.update_attributes(value: 'false') + + expect(address.validation_enabled?).to be_falsey + end + + it 'returns false if enabled country is not present' do + Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'Canada') + + expect(address.validation_enabled?).to be_falsey + end + end + + describe '#country_validation_enabled?' do + it 'returns true if the current country is enabled' do + expect(address.country_validation_enabled?).to be_truthy + end + end + + describe '#validation_enabled_countries' do + it 'returns an array' do + expect(Spree::Address.validation_enabled_countries).to be_kind_of(Array) + end + + it 'includes United States' do + Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada') + + expect(Spree::Address.validation_enabled_countries).to include('United States') + end + end +end diff --git a/spec/models/spree/order_decorator_spec.rb b/spec/models/spree/order_decorator_spec.rb index b69cbf2a..ca86dbd4 100644 --- a/spec/models/spree/order_decorator_spec.rb +++ b/spec/models/spree/order_decorator_spec.rb @@ -4,7 +4,7 @@ it { should have_one :avalara_transaction } - let(:order) {FactoryGirl.create(:order_with_line_items)} + let(:order) { FactoryGirl.create(:avalara_order, ship_address: create(:address)) } let(:completed_order) { create(:completed_order_with_totals) } let(:variant) { create(:variant) } @@ -104,4 +104,55 @@ expect(order.customer_usage_type).to eq('') end end + + describe '#validate_ship_address' do + it 'should return the response if validation is success' do + Spree::AvalaraPreference.address_validation.update_attributes(value: 'true') + response = order.validate_ship_address + + expect(response['ResultCode']).to eq('Success') + end + + it 'should return the response if refuse checkout on address validation is disabled' do + Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'false') + response = order.validate_ship_address + + expect(response['ResultCode']).to eq('Success') + end + + it 'should return false if validation failed' do + Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'true') + order.ship_address.update_attributes(zipcode: nil, city: nil, address1: nil) + response = order.validate_ship_address + + expect(response).to eq(false) + end + end + + describe '#address_validation_enabled?' do + it 'should return false if ship address is nil' do + order.ship_address = nil + + expect(order.address_validation_enabled?).to be_falsey + end + + it 'returns true if preference is true and country validation is enabled' do + Spree::AvalaraPreference.address_validation.update_attributes(value: 'true') + Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada') + + expect(order.address_validation_enabled?).to be_truthy + end + + it 'returns false if address validation preference is false' do + Spree::AvalaraPreference.address_validation.update_attributes(value: 'false') + + expect(order.address_validation_enabled?).to be_falsey + end + + it 'returns false if enabled country is not present' do + Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'Canada') + + expect(order.address_validation_enabled?).to be_falsey + end + end end diff --git a/spec/support/avatax_config_preferences.rb b/spec/support/avatax_config_preferences.rb index 7a6eb060..d6a7081b 100644 --- a/spec/support/avatax_config_preferences.rb +++ b/spec/support/avatax_config_preferences.rb @@ -2,6 +2,7 @@ class MyConfigPreferences def self.set_preferences SolidusAvataxCertified::PreferenceSeeder.seed!(false) Spree::AvalaraPreference.origin_address.update_attributes(value: "{\"Address1\":\"915 S Jackson St\",\"Address2\":\"\",\"City\":\"Montgomery\",\"Region\":\"Alabama\",\"Zip5\":\"36104\",\"Zip4\":\"\",\"Country\":\"US\"}") - Spree::AvalaraPreference.log_to_stdout.update_attributes(value: 'false') + Spree::AvalaraPreference.log_to_stdout.update_attributes(value: 'false') + Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'false') end end