solidus_avatax_certified 1.0.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.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.env_example +4 -0
  3. data/.gitignore +16 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/GEM_VERSION +1 -0
  7. data/Gemfile +18 -0
  8. data/LICENSE +26 -0
  9. data/README.md +27 -0
  10. data/Rakefile +21 -0
  11. data/app/assets/javascripts/spree/backend/address_validator.js +84 -0
  12. data/app/assets/javascripts/spree/backend/solidus_avatax_certified.js +5 -0
  13. data/app/assets/javascripts/spree/backend/use_code_picker.js +51 -0
  14. data/app/assets/javascripts/spree/frontend/address_validator.js +87 -0
  15. data/app/assets/javascripts/spree/frontend/flash.js.coffee +26 -0
  16. data/app/assets/javascripts/spree/frontend/solidus_avatax_certified.js +4 -0
  17. data/app/assets/stylesheets/spree/backend/solidus_avatax_certified.css +4 -0
  18. data/app/assets/stylesheets/spree/frontend/solidus_avatax_certified.css +4 -0
  19. data/app/controllers/spree/admin/avalara_entity_use_codes_controller.rb +15 -0
  20. data/app/controllers/spree/admin/avatax_settings_controller.rb +82 -0
  21. data/app/controllers/spree/admin/users_controller_decorator.rb +11 -0
  22. data/app/controllers/spree/checkout_controller_decorator.rb +22 -0
  23. data/app/models/solidus_avatax_certified/address.rb +95 -0
  24. data/app/models/solidus_avatax_certified/avatax_log.rb +69 -0
  25. data/app/models/solidus_avatax_certified/line.rb +146 -0
  26. data/app/models/solidus_avatax_certified/preference_updater.rb +74 -0
  27. data/app/models/spree/address_decorator.rb +13 -0
  28. data/app/models/spree/adjustment_decorator.rb +10 -0
  29. data/app/models/spree/avalara_entity_use_code.rb +5 -0
  30. data/app/models/spree/avalara_preference.rb +72 -0
  31. data/app/models/spree/avalara_transaction.rb +181 -0
  32. data/app/models/spree/calculator/avalara_transaction.rb +86 -0
  33. data/app/models/spree/line_item_decorator.rb +25 -0
  34. data/app/models/spree/order_decorator.rb +85 -0
  35. data/app/models/spree/payment_decorator.rb +23 -0
  36. data/app/models/spree/refund_decorator.rb +30 -0
  37. data/app/models/spree/shipment_decorator.rb +28 -0
  38. data/app/models/spree/shipping_rate_decorator.rb +25 -0
  39. data/app/models/spree/user_decorator.rb +3 -0
  40. data/app/models/tax_svc.rb +143 -0
  41. data/app/overrides/spree/admin/shared/_configuration_menu.rb +10 -0
  42. data/app/overrides/spree/admin/users/sidebar.rb +8 -0
  43. data/app/overrides/spree/admin/users/validation_button.rb +6 -0
  44. data/app/views/spree/admin/avalara_entity_use_codes/_form.html.erb +27 -0
  45. data/app/views/spree/admin/avalara_entity_use_codes/edit.html.erb +16 -0
  46. data/app/views/spree/admin/avalara_entity_use_codes/index.html.erb +33 -0
  47. data/app/views/spree/admin/avalara_entity_use_codes/new.html.erb +17 -0
  48. data/app/views/spree/admin/avalara_entity_use_codes/show.html.erb +24 -0
  49. data/app/views/spree/admin/avatax_settings/edit.html.erb +183 -0
  50. data/app/views/spree/admin/avatax_settings/ping_my_service.js.erb +8 -0
  51. data/app/views/spree/admin/avatax_settings/show.html.erb +124 -0
  52. data/app/views/spree/admin/avatax_settings/validate_address.js.erb +8 -0
  53. data/app/views/spree/admin/users/avalara_information.html.erb +53 -0
  54. data/app/views/spree/checkout/_address.html.erb +35 -0
  55. data/app/views/spree/checkout/_address_validator_button.html.erb +3 -0
  56. data/bin/rails +7 -0
  57. data/circle.yml +17 -0
  58. data/config/initializers/avatax.rb +5 -0
  59. data/config/initializers/spree.rb +3 -0
  60. data/config/locales/en.yml +35 -0
  61. data/config/routes.rb +18 -0
  62. data/db/migrate/20160624154205_create_spree_avalara_transactions.rb +9 -0
  63. data/db/migrate/20160624154423_create_spree_avalara_entity_use_codes.rb +9 -0
  64. data/db/migrate/20160624155217_add_columns_to_spree_users.rb +6 -0
  65. data/db/migrate/20160628200504_create_spree_avalara_preferences.rb +10 -0
  66. data/db/migrate/20160805193512_add_vat_id_to_spree_users.rb +5 -0
  67. data/db/seeds.rb +1 -0
  68. data/lib/generators/solidus_avatax_certified/install/install_generator.rb +45 -0
  69. data/lib/solidus_avatax_certified/engine.rb +22 -0
  70. data/lib/solidus_avatax_certified/preference_seeder.rb +69 -0
  71. data/lib/solidus_avatax_certified/seeder.rb +117 -0
  72. data/lib/solidus_avatax_certified.rb +2 -0
  73. data/lib/tasks/load_seeds.rake +15 -0
  74. data/setup.md +12 -0
  75. data/solidus_avatax_certified.gemspec +42 -0
  76. data/spec/controllers/spree/admin/avalara_entity_use_codes_controller_spec.rb +53 -0
  77. data/spec/controllers/spree/admin/avatax_settings_controller_spec.rb +67 -0
  78. data/spec/factories/avalara_entity_use_code_factory.rb +6 -0
  79. data/spec/factories/avalara_factories.rb +76 -0
  80. data/spec/factories/avalara_order_factory.rb +62 -0
  81. data/spec/factories/avalara_preference_factory.rb +7 -0
  82. data/spec/factories/avalara_shipment_factory.rb +27 -0
  83. data/spec/factories/avalara_shipping_method_factory.rb +23 -0
  84. data/spec/factories/tax_rate_factory.rb +19 -0
  85. data/spec/features/certification_spec.rb +77 -0
  86. data/spec/features/checkout_spec.rb +156 -0
  87. data/spec/features/vat_spec.rb +153 -0
  88. data/spec/models/solidus_avatax_certified/address_spec.rb +80 -0
  89. data/spec/models/solidus_avatax_certified/avatax_log_spec.rb +97 -0
  90. data/spec/models/solidus_avatax_certified/line_spec.rb +100 -0
  91. data/spec/models/spree/address_decorator_spec.rb +44 -0
  92. data/spec/models/spree/adjustment_decorator_spec.rb +25 -0
  93. data/spec/models/spree/avalara_entity_use_code_spec.rb +5 -0
  94. data/spec/models/spree/avalara_preference_spec.rb +173 -0
  95. data/spec/models/spree/avalara_transaction_spec.rb +203 -0
  96. data/spec/models/spree/calculator/avalara_transaction_spec.rb +129 -0
  97. data/spec/models/spree/line_item_decorator_spec.rb +33 -0
  98. data/spec/models/spree/order_decorator_spec.rb +164 -0
  99. data/spec/models/spree/payment_decorator_spec.rb +117 -0
  100. data/spec/models/spree/refund_decorator_spec.rb +81 -0
  101. data/spec/models/spree/shipment_decorator_spec.rb +36 -0
  102. data/spec/models/spree/shipping_rate_decorator_spec.rb +17 -0
  103. data/spec/models/spree/user_decorator_spec.rb +5 -0
  104. data/spec/spec_helper.rb +81 -0
  105. data/spec/support/avatax_config_preferences.rb +8 -0
  106. data/spec/support/vcr.rb +9 -0
  107. data/spec/vcr/Certification/Exempt_sales_should_be_reflected_in_the_test_data_through_use_of_ExemptionNo_or_CustomerUsageType_/does_not_add_additional_tax.yml +276 -0
  108. data/spec/vcr/Certification/Transactions_have_been_committed_/commits_an_order.yml +336 -0
  109. data/spec/vcr/Certification/Transactions_have_been_voided/cancelled_/should_be_successful/returns_ResultCode_with_value_Success.yml +522 -0
  110. data/spec/vcr/Certification/return_orders/_commit_avatax_final/should_commit_avatax_final.yml +404 -0
  111. data/spec/vcr/Checkout/complete_order/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  112. data/spec/vcr/Checkout/complete_order/order_line_items_and_shipments_have_an_additional_tax_total_sum_of_0_40.yml +72 -0
  113. data/spec/vcr/Checkout/payment/tax_included/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  114. data/spec/vcr/Checkout/payment/tax_included/order_line_items_and_shipments_have_an_included_tax_total_sum_of_0_38.yml +72 -0
  115. data/spec/vcr/Checkout/payment/tax_not_included/on_payment_page/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  116. data/spec/vcr/Checkout/payment/tax_not_included/on_payment_page/order_line_items_and_shipments_and_shipments_have_an_additional_tax_total_sum_of_0_40.yml +72 -0
  117. data/spec/vcr/Checkout/payment/with_promotion/tax_not_included/has_adjusted_tax_amount_after_promotion_applied.yml +73 -0
  118. data/spec/vcr/SolidusAvataxCertified_Address/_validate/fails_when_information_is_incorrect.yml +54 -0
  119. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_item_pre-tax_total_rate.yml +137 -0
  120. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_previous_included_tax_total_is_order_is_at_address.yml +138 -0
  121. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_previous_included_tax_total_is_order_is_at_cart.yml +137 -0
  122. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_item_pre-tax_total_rate.yml +136 -0
  123. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_additional_tax_total_if_order_is_at_address.yml +137 -0
  124. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_additional_tax_total_if_order_is_at_cart.yml +136 -0
  125. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_tax_total_if_preference_tax_calculation_is_false.yml +136 -0
  126. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/when_the_line_item_is_discounted/should_be_equal_to_the_items_pre-tax_total_rate.yml +276 -0
  127. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/when_the_order_is_discounted/should_be_equal_to_the_items_pre-tax_total_rate.yml +206 -0
  128. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/computing_normal_shipment/should_be_equal_4_0.yml +141 -0
  129. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/when_tax_is_included_in_price/should_be_equal_to_3_85.yml +143 -0
  130. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/with_promotion/should_equal_3_96.yml +210 -0
  131. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_an_order/when_computing_an_order/should_raise_error.yml +136 -0
  132. data/spec/vcr/Spree_Order/_cancel_avalara/should_receive_cancel_order_when_cancel_avalara_is_called.yml +136 -0
  133. data/spec/vcr/Spree_Order/_cancel_avalara/state_machine_event_cancel/should_recieve_cancel_avalara_when_event_cancel_is_called.yml +259 -0
  134. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_false_if_validation_failed.yml +54 -0
  135. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_the_response_if_refuse_checkout_on_address_validation_is_disabled.yml +59 -0
  136. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_the_response_if_validation_is_success.yml +59 -0
  137. data/spec/vcr/Spree_Payment/_avalara_finalize/should_update_the_amount_to_be_the_order_total.yml +136 -0
  138. data/spec/vcr/Spree_Payment/_cancel_avalara/committed_order/should_be_successful/ResultCode_returns_Success.yml +205 -0
  139. data/spec/vcr/Spree_Payment/_cancel_avalara/uncommitted_order/should_fail/ResultCode_returns_Error.yml +191 -0
  140. data/spec/vcr/Spree_Payment/_purchase_/receive_avalara_finalize.yml +136 -0
  141. data/spec/vcr/Spree_Payment/_void_transaction_/receive_cancel_avalara.yml +136 -0
  142. data/spec/vcr/Spree_Refund/full_refund/returns_correct_tax_calculations.yml +270 -0
  143. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  144. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/origin_country_tax_is_returned.yml +138 -0
  145. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +143 -0
  146. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +139 -0
  147. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/destination_country_tax_is_returned.yml +139 -0
  148. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +144 -0
  149. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_same_EU_country/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  150. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_same_EU_country/tax_detail_country_equals_to_IT.yml +138 -0
  151. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  152. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/tax_detail_country_equals_to_IT.yml +137 -0
  153. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/total_tax_is_0_since_utah_is_not_in_jurisdiction.yml +137 -0
  154. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +138 -0
  155. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_has_Nexus_Jurisdiction_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +195 -0
  156. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_has_Nexus_Jurisdiction_Registered/tax_detail_region_equals_to_AL.yml +195 -0
  157. data/spec/vcr/address_validation_success.yml +59 -0
  158. data/spec/vcr/capture_with_customer_usage_type.yml +72 -0
  159. data/spec/vcr/order_cancel.yml +258 -0
  160. data/spec/vcr/order_capture.yml +72 -0
  161. data/spec/vcr/order_capture_finalize.yml +141 -0
  162. data/spec/vcr/order_capture_with_promo.yml +73 -0
  163. data/spec/vcr/order_return_capture.yml +68 -0
  164. data/spec/vcr/tax_included_order.yml +73 -0
  165. metadata +581 -0
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Address, type: :model do
4
+ let(:address) { build(:address) }
5
+
6
+ describe '#validation_enabled?' do
7
+ it 'returns true if preference is true and country validation is enabled' do
8
+ Spree::AvalaraPreference.address_validation.update_attributes(value: 'true')
9
+ Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada')
10
+
11
+ expect(address.validation_enabled?).to be_truthy
12
+ end
13
+
14
+ it 'returns false if address validation preference is false' do
15
+ Spree::AvalaraPreference.address_validation.update_attributes(value: 'false')
16
+
17
+ expect(address.validation_enabled?).to be_falsey
18
+ end
19
+
20
+ it 'returns false if enabled country is not present' do
21
+ Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'Canada')
22
+
23
+ expect(address.validation_enabled?).to be_falsey
24
+ end
25
+ end
26
+
27
+ describe '#country_validation_enabled?' do
28
+ it 'returns true if the current country is enabled' do
29
+ expect(address.country_validation_enabled?).to be_truthy
30
+ end
31
+ end
32
+
33
+ describe '#validation_enabled_countries' do
34
+ it 'returns an array' do
35
+ expect(Spree::Address.validation_enabled_countries).to be_kind_of(Array)
36
+ end
37
+
38
+ it 'includes United States' do
39
+ Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada')
40
+
41
+ expect(Spree::Address.validation_enabled_countries).to include('United States')
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Adjustment, type: :model do
4
+ let(:order) { build(:avalara_order) }
5
+
6
+ describe 'not_tax' do
7
+ it 'does not include adjustments with source_type of Spree::TaxRate' do
8
+ tax_adjustment = create(:adjustment, source_type: 'Spree::TaxRate', order: order)
9
+ non_tax_adjustment = create(:adjustment, source_type: 'Spree::Promotion', order: order)
10
+
11
+ expect(Spree::Adjustment.not_tax).to_not include(tax_adjustment)
12
+ expect(Spree::Adjustment.not_tax).to include(non_tax_adjustment)
13
+ end
14
+ end
15
+
16
+ describe '#avatax_cache_key' do
17
+ it 'should respond with a cache key' do
18
+ adjustment = build(:adjustment, id: 1, amount: 20.0, order: order)
19
+
20
+ expected_response = 'Spree::Adjustment-1-20.0'
21
+
22
+ expect(adjustment.avatax_cache_key).to eq(expected_response)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::AvalaraEntityUseCode, type: :model do
4
+ it { should have_many :users }
5
+ end
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::AvalaraPreference, type: :model do
4
+ it { should validate_uniqueness_of :name }
5
+ it { should validate_presence_of :name }
6
+ it { should validate_presence_of :object_type }
7
+
8
+ describe '#booleans' do
9
+ it 'should return records with object_type of boolean' do
10
+ boolean_pref = create(:avalara_preference, object_type: 'boolean')
11
+ other_pref = create(:avalara_preference, object_type: 'string')
12
+
13
+ expect(Spree::AvalaraPreference.booleans).to include(boolean_pref)
14
+ expect(Spree::AvalaraPreference.booleans).to_not include(other_pref)
15
+ end
16
+ end
17
+
18
+ describe '#strings' do
19
+ it 'should return records with object_type of string' do
20
+ string_pref = create(:avalara_preference, object_type: 'string')
21
+ other_pref = create(:avalara_preference, object_type: 'boolean')
22
+
23
+ expect(Spree::AvalaraPreference.strings).to include(string_pref)
24
+ expect(Spree::AvalaraPreference.strings).to_not include(other_pref)
25
+ end
26
+ end
27
+
28
+ describe '#arrays' do
29
+ it 'should return records with object_type of array' do
30
+ array_pref = create(:avalara_preference, object_type: 'array')
31
+ other_pref = create(:avalara_preference, object_type: 'boolean')
32
+
33
+ expect(Spree::AvalaraPreference.arrays).to include(array_pref)
34
+ expect(Spree::AvalaraPreference.arrays).to_not include(other_pref)
35
+ end
36
+ end
37
+
38
+ describe '#jsons' do
39
+ it 'should return records with object_type of json' do
40
+ json_pref = create(:avalara_preference, object_type: 'json')
41
+ other_pref = create(:avalara_preference, object_type: 'boolean')
42
+
43
+ expect(Spree::AvalaraPreference.jsons).to include(json_pref)
44
+ expect(Spree::AvalaraPreference.jsons).to_not include(other_pref)
45
+ end
46
+ end
47
+
48
+ describe '#storeable_env' do
49
+ it 'should return records with that have name is either company_code, license_key, account and endpoint' do
50
+ storable_pref = Spree::AvalaraPreference.company_code
51
+ other_pref = create(:avalara_preference, name: 'other')
52
+
53
+ expect(Spree::AvalaraPreference.storable_envs).to include(storable_pref)
54
+ expect(Spree::AvalaraPreference.storable_envs).to_not include(other_pref)
55
+ end
56
+ end
57
+
58
+ describe '#company_code' do
59
+ it 'should return object with the same name' do
60
+ company_code = Spree::AvalaraPreference.find_by(name: 'company_code')
61
+
62
+ expect(Spree::AvalaraPreference.company_code).to eq(company_code)
63
+ end
64
+ end
65
+
66
+ describe '#license_key' do
67
+ it 'should return object with same name' do
68
+ license_key = Spree::AvalaraPreference.find_by(name: 'license_key')
69
+
70
+ expect(Spree::AvalaraPreference.license_key).to eq(license_key)
71
+ end
72
+ end
73
+
74
+ describe '#account' do
75
+ it 'should return object with same name' do
76
+ account = Spree::AvalaraPreference.find_by(name: 'account')
77
+
78
+ expect(Spree::AvalaraPreference.account).to eq(account)
79
+ end
80
+ end
81
+
82
+ describe '#endpoint' do
83
+ it 'should return object with same name' do
84
+ endpoint = Spree::AvalaraPreference.find_by(name: 'endpoint')
85
+
86
+ expect(Spree::AvalaraPreference.endpoint).to eq(endpoint)
87
+ end
88
+ end
89
+
90
+ describe '#origin_address' do
91
+ it 'should return object with same name' do
92
+ origin_address = Spree::AvalaraPreference.find_by(name: 'origin_address')
93
+
94
+ expect(Spree::AvalaraPreference.origin_address).to eq(origin_address)
95
+ end
96
+ end
97
+
98
+ describe '#log' do
99
+ it 'should return object with same name' do
100
+ log = Spree::AvalaraPreference.find_by(name: 'log')
101
+
102
+ expect(Spree::AvalaraPreference.log).to eq(log)
103
+ end
104
+ end
105
+
106
+ describe '#log_to_stdout' do
107
+ it 'should return object with same name' do
108
+ log_to_stdout = Spree::AvalaraPreference.find_by(name: 'log_to_stdout')
109
+
110
+ expect(Spree::AvalaraPreference.log_to_stdout).to eq(log_to_stdout)
111
+ end
112
+ end
113
+
114
+ describe '#address_validation' do
115
+ it 'should return object with same name' do
116
+ address_validation = Spree::AvalaraPreference.find_by(name: 'address_validation')
117
+
118
+ expect(Spree::AvalaraPreference.address_validation).to eq(address_validation)
119
+ end
120
+ end
121
+
122
+ describe '#refuse_checkout_address_validation_error' do
123
+ it 'should return object with same name' do
124
+ pref = Spree::AvalaraPreference.find_by(name: 'refuse_checkout_address_validation_error')
125
+
126
+ expect(Spree::AvalaraPreference.refuse_checkout_address_validation_error).to eq(pref)
127
+ end
128
+ end
129
+
130
+ describe '#tax_calculation' do
131
+ it 'should return object with same name' do
132
+ tax_calculation = Spree::AvalaraPreference.find_by(name: 'tax_calculation')
133
+
134
+ expect(Spree::AvalaraPreference.tax_calculation).to eq(tax_calculation)
135
+ end
136
+ end
137
+
138
+ describe '#document_commit' do
139
+ it 'should return object with same name' do
140
+ document_commit = Spree::AvalaraPreference.find_by(name: 'document_commit')
141
+
142
+ expect(Spree::AvalaraPreference.document_commit).to eq(document_commit)
143
+ end
144
+ end
145
+
146
+ describe '#validation_enabled_countries' do
147
+ it 'should return object with name address_validation_enabled_countries' do
148
+ validation_enabled_countries = Spree::AvalaraPreference.find_by(name: 'address_validation_enabled_countries')
149
+
150
+ expect(Spree::AvalaraPreference.validation_enabled_countries).to eq(validation_enabled_countries)
151
+ end
152
+ end
153
+
154
+ describe '#validation_enabled_countries_array' do
155
+ it 'should return the objects value as an array' do
156
+ value = ['United States', 'Canada']
157
+
158
+ expect(Spree::AvalaraPreference.validation_enabled_countries_array).to eq(value)
159
+ end
160
+ end
161
+
162
+ describe '#is_true?' do
163
+ it 'should return true if value is a string of true or false' do
164
+ expect(Spree::AvalaraPreference.tax_calculation.is_true?).to be_in([true, false])
165
+ end
166
+
167
+ it 'should return false if value is an empty string' do
168
+ Spree::AvalaraPreference.origin_address.update_attributes(value: "")
169
+
170
+ expect(Spree::AvalaraPreference.origin_address.is_true?).to be_falsey
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,203 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::AvalaraTransaction, :vcr do
4
+
5
+ it { should belong_to :order }
6
+ it { should validate_presence_of :order }
7
+ it { should validate_uniqueness_of :order_id }
8
+ it { should have_db_index :order_id }
9
+
10
+ let(:included_in_price) { false }
11
+ let(:order) { create(:avalara_order, tax_included: included_in_price) }
12
+
13
+ context 'captured orders' do
14
+
15
+ before do
16
+ VCR.use_cassette("order_capture") do
17
+ order.avalara_capture
18
+ end
19
+ end
20
+
21
+ describe '#lookup_avatax' do
22
+ subject do
23
+ VCR.use_cassette("order_capture") do
24
+ order.avalara_transaction.lookup_avatax
25
+ end
26
+ end
27
+
28
+ it 'should look up avatax' do
29
+ expect(subject['TotalTax']).to eq('0.6')
30
+ end
31
+ end
32
+
33
+ describe '#commit_avatax' do
34
+ subject do
35
+ VCR.use_cassette("order_capture") do
36
+ order.avalara_transaction.commit_avatax('SalesOrder')
37
+ end
38
+ end
39
+
40
+ it 'should commit avatax' do
41
+ expect(subject['TotalTax']).to eq('0.6')
42
+ end
43
+
44
+ context 'tax calculation disabled' do
45
+ it 'should respond with total tax of 0' do
46
+ Spree::AvalaraPreference.tax_calculation.update_attributes(value: 'false')
47
+ expect(order.avalara_transaction.commit_avatax('SalesOrder')[:TotalTax]).to eq('0.00')
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'promo' do
53
+ let(:promotion) { create(:promotion, :with_order_adjustment) }
54
+
55
+ before do
56
+ create(:adjustment, order: order, source: promotion.promotion_actions.first, adjustable: order)
57
+ order.update!
58
+ end
59
+
60
+ subject do
61
+ VCR.use_cassette('order_capture_with_promo', allow_playback_repeats: true) do
62
+ order.avalara_transaction.commit_avatax('SalesOrder')
63
+ end
64
+ end
65
+
66
+ it 'applies discount' do
67
+ expect(subject['TotalDiscount']).to eq('10')
68
+ end
69
+ end
70
+
71
+ context 'included_in_price' do
72
+ let(:included_in_price) { true }
73
+
74
+ subject do
75
+ VCR.use_cassette("tax_included_order") do
76
+ order.avalara_transaction.commit_avatax('SalesOrder')
77
+ end
78
+ end
79
+
80
+ it 'calculates the included tax amount from item total' do
81
+ expect(subject['TotalTax']).to eq('0.57')
82
+ end
83
+ end
84
+
85
+ describe '#commit_avatax_final' do
86
+ subject do
87
+ VCR.use_cassette("order_capture_finalize", allow_playback_repeats: true) do
88
+ order.avalara_transaction.commit_avatax_final('SalesInvoice')
89
+ end
90
+ end
91
+
92
+ it 'should commit avatax final' do
93
+ expect(subject['TotalTax']).to eq('0.6')
94
+ end
95
+
96
+ it 'should fail to commit to avatax if settings are false' do
97
+ Spree::AvalaraPreference.document_commit.update_attributes(value: 'false')
98
+
99
+ expect(subject).to eq('avalara document committing disabled')
100
+ end
101
+
102
+ context 'tax calculation disabled' do
103
+ it 'should respond with total tax of 0' do
104
+ Spree::AvalaraPreference.tax_calculation.update_attributes(value: 'false')
105
+ expect(subject[:TotalTax]).to eq('0.00')
106
+ end
107
+ end
108
+
109
+ context 'with CustomerUsageType' do
110
+ let(:use_code) { create(:avalara_entity_use_code) }
111
+
112
+ before do
113
+ order.user.update_attributes(avalara_entity_use_code: use_code)
114
+ end
115
+
116
+ subject do
117
+ VCR.use_cassette('capture_with_customer_usage_type') do
118
+ order.avalara_transaction.commit_avatax('SalesInvoice')
119
+ end
120
+ end
121
+
122
+ it 'does not add additional tax' do
123
+ expect(subject['TotalTax']).to eq('0')
124
+ end
125
+ end
126
+ end
127
+
128
+
129
+ describe '#cancel_order' do
130
+
131
+ describe 'when successful' do
132
+ let(:order) { create(:completed_avalara_order) }
133
+ subject do
134
+ VCR.use_cassette("order_cancel") do
135
+ order.avalara_capture_finalize
136
+ order.avalara_transaction.cancel_order
137
+ end
138
+ end
139
+
140
+ it 'should receive ResultCode of Success' do
141
+ expect(subject['ResultCode']).to eq('Success')
142
+ end
143
+ end
144
+
145
+ context 'error' do
146
+ it 'should receive error' do
147
+ order = create(:order)
148
+ order.avalara_transaction = Spree::AvalaraTransaction.create
149
+ expect(order.avalara_transaction).to receive(:cancel_order_to_avalara).and_return('Error in Tax')
150
+ order.avalara_transaction.cancel_order
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'return orders' do
157
+ let(:order) { create(:completed_avalara_order) }
158
+ let(:reimbursement) { create(:reimbursement, order: order) }
159
+ let(:refund) { build(:refund, payment: order.payments.first, amount: order.total.to_f) }
160
+
161
+ before do
162
+ VCR.use_cassette("order_capture_finalize") do
163
+ order.avalara_capture_finalize
164
+ order.reload
165
+ end
166
+ end
167
+
168
+ describe '#commit_avatax' do
169
+ subject do
170
+ VCR.use_cassette("order_return_capture") do
171
+ order.avalara_transaction.commit_avatax('ReturnOrder', refund)
172
+ end
173
+ end
174
+
175
+ it 'should receive a ResultCode of Success' do
176
+ expect(subject['ResultCode']).to eq('Success')
177
+ end
178
+
179
+ it 'should have a TotalTax equal to additional_tax_total' do
180
+ expect(subject['TotalTax']).to eq("#{-order.additional_tax_total.to_f}")
181
+ end
182
+ end
183
+
184
+ describe '#commit_avatax_final' do
185
+ subject do
186
+ VCR.use_cassette("order_return_capture") do
187
+ order.avalara_transaction.commit_avatax_final('ReturnOrder', refund)
188
+ end
189
+ end
190
+
191
+ it 'should commit avatax final' do
192
+ expect(subject).to be_kind_of(Hash)
193
+ expect(subject['ResultCode']).to eq('Success')
194
+ expect(subject['TotalTax']).to eq("#{-order.additional_tax_total.to_f}")
195
+ end
196
+
197
+ it 'should receive post_order_to_avalara' do
198
+ expect(order.avalara_transaction).to receive(:post_return_to_avalara)
199
+ subject
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Calculator::AvalaraTransaction do
4
+ let(:included_in_price) { false }
5
+ let!(:order) { create(:avalara_order, line_items_price: 10, shipment_cost: 100, tax_included: included_in_price) }
6
+ let(:tax_category) { Spree::TaxCategory.find_or_create_by(name: 'Clothing', tax_code: 'P0000000') }
7
+ let(:calculator) { Spree::TaxRate.find_by(name: 'Tax').calculator }
8
+ let(:line_item) { order.line_items.first }
9
+
10
+ describe '#description' do
11
+ it 'responds with avalara_transaction' do
12
+ expect(calculator.description).to eq('Avalara Transaction Calculator')
13
+ end
14
+ end
15
+
16
+ context '#compute', :vcr do
17
+ context 'when given an order' do
18
+ before do
19
+ allow(order).to receive_messages :line_items => [line_item]
20
+ end
21
+
22
+ context 'when computing an order' do
23
+ it 'should raise error' do
24
+ expect{calculator.compute(order)}.to raise_error(RuntimeError)
25
+ end
26
+ end
27
+ end
28
+ context 'when computing a line item' do
29
+ context 'when tax is included in price' do
30
+ let(:included_in_price) { true }
31
+ it 'should be equal to the item pre-tax total * rate' do
32
+ expect(calculator.compute(line_item)).to eq(0.38)
33
+ end
34
+
35
+ it 'should be equal to the previous included_tax_total is order is at cart' do
36
+ order.state = 'cart'
37
+ line_item.included_tax_total = 0.1
38
+ expect(calculator.compute(line_item)).to eq(0.1)
39
+ end
40
+
41
+ it 'should be equal to the previous included_tax_total is order is at address' do
42
+ order.state = 'address'
43
+ line_item.included_tax_total = 0.1
44
+ expect(calculator.compute(line_item)).to eq(0.1)
45
+ end
46
+ end
47
+
48
+ context 'when tax is not included in price' do
49
+
50
+ it 'should be equal to the item pre-tax total * rate' do
51
+ expect(calculator.compute(line_item)).to eq(0.4)
52
+ end
53
+
54
+ it 'should be equal to the previous additional_tax_total if order is at cart' do
55
+ order.state = 'cart'
56
+ line_item.additional_tax_total = 0.1
57
+ expect(calculator.compute(line_item)).to eq(0.1)
58
+ end
59
+
60
+ it 'should be equal to the previous additional_tax_total if order is at address' do
61
+ order.state = 'address'
62
+ line_item.additional_tax_total = 0.1
63
+ expect(calculator.compute(line_item)).to eq(0.1)
64
+ end
65
+
66
+ it 'should be equal to the previous tax total if preference tax_calculation is false' do
67
+ Spree::AvalaraPreference.tax_calculation.update_attributes(value: 'false')
68
+
69
+ line_item.additional_tax_total = 0.1
70
+ expect(calculator.compute(line_item)).to eq(0.1)
71
+ end
72
+
73
+ context 'when the order is discounted' do
74
+ let(:promotion) { create(:promotion, :with_order_adjustment, weighted_order_adjustment_amount: 2) }
75
+
76
+ before do
77
+ create(:adjustment, order: order, source: promotion.promotion_actions.first, adjustable: order)
78
+ order.update!
79
+ end
80
+
81
+ it 'should be equal to the items pre-tax total * rate' do
82
+ expect(calculator.compute(line_item)).to eq(0.32)
83
+ end
84
+ end
85
+
86
+ context 'when the line item is discounted' do
87
+ let!(:promotion) { create(:promotion_with_item_adjustment, adjustment_rate: 2) }
88
+
89
+ before do
90
+ create(:adjustment, order: order, source: promotion.promotion_actions.first, adjustable: line_item)
91
+ line_item.reload
92
+ order.reload.update!
93
+ end
94
+
95
+ it 'should be equal to the items pre-tax total * rate' do
96
+ expect(calculator.compute(line_item)).to eq(0.32)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'when given a shipment' do
103
+ let(:shipping_rate) { Spree::TaxRate.find_by(name: 'Shipping Tax') }
104
+ let(:shipping_calculator) { Spree::Calculator::AvalaraTransaction.new(calculable: shipping_rate) }
105
+ let!(:shipment) { order.shipments.first }
106
+
107
+ describe 'computing normal shipment' do
108
+ it 'should be equal 4.0' do
109
+ expect(shipping_calculator.compute(shipment)).to eq(4.0)
110
+ end
111
+ end
112
+
113
+ describe 'with promotion' do
114
+ it 'should equal 3.96' do
115
+ shipment.update_attributes(promo_total: -1)
116
+ expect(shipping_calculator.compute(shipment)).to eq(3.96)
117
+ end
118
+ end
119
+
120
+ describe 'when tax is included in price' do
121
+ let(:included_in_price) { true }
122
+
123
+ it 'should be equal to 3.85' do
124
+ expect(shipping_calculator.compute(shipment)).to eq(3.85)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::LineItem, type: :model do
4
+
5
+ let(:order) { create :order_with_line_items, line_items_count: 1 }
6
+ let(:line_item) { order.line_items.first }
7
+
8
+ describe '#to_hash' do
9
+ it 'should create hash of line item information' do
10
+ expect(line_item.to_hash).to be_kind_of(Hash)
11
+ end
12
+ it 'should have index of 1' do
13
+ response = line_item.to_hash
14
+ expect(response['Index']).to eq(1)
15
+ end
16
+ end
17
+
18
+ describe '#avatax_cache_key' do
19
+ it 'should respond with a cache key' do
20
+ line_item = Spree::LineItem.new(price: 10, id: 1, quantity: 1)
21
+
22
+ expected_response = 'Spree::LineItem-1-1-10.0-0.0'
23
+
24
+ expect(line_item.avatax_cache_key).to eq(expected_response)
25
+ end
26
+ end
27
+
28
+ describe '#avatax_line_code' do
29
+ it 'should equal LI' do
30
+ expect(line_item.avatax_line_code).to eq('LI')
31
+ end
32
+ end
33
+ end