solidus_avatax_certified 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,183 @@
1
+ <%= render 'spree/admin/shared/taxes_tabs' %>
2
+
3
+ <% content_for :page_title do %>
4
+ <%= Spree.t(:avalara_settings) %>
5
+ <% end %>
6
+
7
+ <% content_for :page_actions do %>
8
+ <li><%= link_to_with_icon 'arrow-left', Spree.t(:back), admin_avatax_settings_path, :class => 'button' %></li>
9
+ <% end %>
10
+
11
+ <%= form_tag(admin_avatax_settings_path, :method => :put, :id => :avatax_settings_form) do %>
12
+
13
+ <div class="yui-g">
14
+ <div class="yui-u first">
15
+ <fieldset>
16
+ <legend><%= Spree.t('avatax_api_keys') %></legend>
17
+ <p>
18
+ <label><%= Spree.t('avatax_company_code') %></label><br />
19
+ <%= text_field_tag('settings[company_code]', Spree::AvalaraPreference.company_code.value, :maxlength => 256, :class => 'avatax') %>
20
+ </p>
21
+
22
+ <p>
23
+ <label><%= Spree.t('avatax_account') %></label><br />
24
+ <%= text_field_tag('settings[account]', Spree::AvalaraPreference.account.value, :maxlength => 256, :class => 'avatax') %>
25
+ </p>
26
+ <p>
27
+ <label><%= Spree.t('avatax_license_key') %></label><br />
28
+ <%= text_field_tag('settings[license_key]', Spree::AvalaraPreference.license_key.value, :maxlength => 256, :class => 'avatax') %>
29
+ </p>
30
+ </fieldset>
31
+
32
+ <fieldset>
33
+ <legend><%= Spree.t('avatax_endpoint_urls') %></legend>
34
+ <p>
35
+ <label><%= Spree.t('avatax_endpoint') %></label><br />
36
+ <%= text_field_tag('settings[endpoint]', Spree::AvalaraPreference.endpoint.value, :size => 46, :maxlength => 256, :class => 'avatax') %>
37
+ </p>
38
+ <p>
39
+ <label><%= Spree.t('avatax_tax_service_path') %></label><br />
40
+ <input type="text" placeholder="<%= AVATAX_SERVICEPATH_TAX %>", readonly>
41
+ </p>
42
+ <p>
43
+ <label><%= Spree.t('avatax_address_service_path') %></label><br />
44
+ <input type="text" placeholder="<%= AVATAX_SERVICEPATH_ADDRESS %>", readonly>
45
+ </p>
46
+ </fieldset>
47
+
48
+ <fieldset>
49
+ <legend><%= Spree.t('avatax_logging') %></legend>
50
+ <p>
51
+ <label><%= Spree.t('enable_avatax_logging') %></label><br />
52
+ <%= check_box_tag('settings[log]','yes' , Spree::AvalaraPreference.log.value, :class => 'avatax') %>
53
+ </p>
54
+ <p>
55
+ <label><%= Spree.t('enable_avatax_log_to_stdout') %></label><br />
56
+ <%= check_box_tag('settings[log_to_stdout]','yes' , Spree::AvalaraPreference.log_to_stdout.value, :class => 'avatax') %>
57
+ </p>
58
+ </fieldset>
59
+
60
+ <fieldset>
61
+ <legend><%= Spree.t('avatax_address_validation') %></legend>
62
+ <p>
63
+ <label><%= Spree.t('enable_avatax_address_validation') %></label><br />
64
+ <%= check_box_tag('settings[address_validation]','yes' , Spree::AvalaraPreference.address_validation.value, :class => 'avatax') %>
65
+ </p>
66
+ <p>
67
+ <label>Refuse Checkout if Address Validation Fails</label><br />
68
+ <%= check_box_tag('settings[refuse_checkout_address_validation_error]','yes' , Spree::AvalaraPreference.refuse_checkout_address_validation_error.value, :class => 'avatax') %>
69
+ </p>
70
+ <p>
71
+ <label>Customer can validate address in checkout</label><br />
72
+ <%= check_box_tag('settings[customer_can_validate]','yes' , Spree::AvalaraPreference.customer_can_validate.value, :class => 'avatax') %>
73
+ </p>
74
+ </fieldset>
75
+
76
+ <fieldset>
77
+ <legend><%= Spree.t('avatax_address_validation_enabled_countries') %></legend>
78
+ <p>
79
+ <% current_countries = Spree::Country.where(name: Spree::AvalaraPreference.validation_enabled_countries_array) %>
80
+ <label><%= Spree.t('avatax_address_validation_enabled_countries') %></label><br />
81
+ <%= select_tag('settings[address_validation_enabled_countries]', options_from_collection_for_select(Spree::Country.all, "name", "name", selected: current_countries), multiple: true, class: "select2 fullwidth") %>
82
+ </p>
83
+ </fieldset>
84
+ <fieldset>
85
+ <legend><%= Spree.t('avatax_tax_calculation') %></legend>
86
+ <p>
87
+ <label><%= Spree.t('enable_avatax_tax_calculation') %></label><br />
88
+ <%= check_box_tag('settings[tax_calculation]','yes' , Spree::AvalaraPreference.tax_calculation.value, :class => 'avatax') %>
89
+ </p>
90
+ </fieldset>
91
+
92
+ <fieldset>
93
+ <legend><%= Spree.t('avatax_document_committing') %></legend>
94
+ <p>
95
+ <label><%= Spree.t('enable_avatax_document_committing') %></label><br />
96
+ <%= check_box_tag('settings[document_commit]','yes' , Spree::AvalaraPreference.document_commit.value, :class => 'avatax') %>
97
+ </p>
98
+ </fieldset>
99
+
100
+ <fieldset id='business-address'>
101
+ <legend><%= Spree.t('business_address') %></legend>
102
+ <p>
103
+ <label><%= Spree.t('address1') %></label><br />
104
+ <%= text_field_tag('address[Line1]', @avatax_origin["Line1"], :size => 46, :maxlength => 256, :class => 'avatax', id: 'address1') %>
105
+ </p>
106
+ <p>
107
+ <label><%= Spree.t('address2') %></label><br />
108
+ <%= text_field_tag('address[Line2]', @avatax_origin["Line2"], :size => 46, :maxlength => 256, :class => 'avatax', id: 'address2') %>
109
+ </p>
110
+ <p>
111
+ <label><%= Spree.t('city') %></label><br />
112
+ <%= text_field_tag('address[City]', @avatax_origin["City"], :size => 46, :maxlength => 256, :class => 'avatax', id: 'city') %>
113
+ </p>
114
+ <p>
115
+ <label><%= Spree.t('country') %></label><br />
116
+ <% curr_country = Spree::Country.find_by(iso: @avatax_origin["Country"]) || Spree::Country.find_by(iso: 'US') %>
117
+ <span id="scountry">
118
+ <%= select_tag 'address[Country]', options_from_collection_for_select(Spree::Country.all, 'id', 'name', curr_country.try(:id)), {:class => 'select2 avatax', id: 'country'} %>
119
+ </span>
120
+ </p>
121
+ <p>
122
+ <label><%= Spree.t('state') %></label><br />
123
+ <span id="sstate">
124
+ <%= select_tag 'address[Region]', options_from_collection_for_select(curr_country.try(:states), 'id', 'name',curr_country.states.find_by(abbr: @avatax_origin["Region"]).try(:id)), {:class => 'select2 avatax', id: 'state'} %>
125
+ </span>
126
+ </p>
127
+ <p>
128
+ <label><%= Spree.t('zipcode') %></label><br />
129
+ <%= text_field_tag('address[PostalCode]', @avatax_origin["PostalCode"], :size => 46, :maxlength => 256, :class => 'avatax', id: 'zipcode') %>
130
+ </p>
131
+
132
+ <a href="#" class="button address_validator" style="float: right;">Validate</a>
133
+ </fieldset>
134
+ <fieldset>
135
+ <legend><%= Spree.t('log_files') %></legend>
136
+ <p>Log files are located in the log directory of your spree website.</p>
137
+ <table>
138
+ <tr>
139
+ <td>
140
+ <table>
141
+ <tr>
142
+ <td>Tax Service calls - tax_svc.log</td>
143
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_txt_tax_svc}) %>
144
+ </td>
145
+ <td>
146
+ <%= link_to("Clear Data", {controller: :avatax_settings, action: :erase_data, remote: true, log_name: "tax_svc"}) %>
147
+ </td>
148
+ </tr>
149
+ <tr>
150
+ <td>Avalara Function calls - post_order_to_avalara.log</td>
151
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_post_order_to_avalara}) %>
152
+ </td>
153
+ <td>
154
+ <%= link_to("Clear Data", {controller: :avatax_settings, action: :erase_data, remote: true, log_name: "post_order_to_avalara"}) %>
155
+ </td>
156
+ </tr>
157
+ <tr>
158
+ <td>Spree Order Item integration calls - avalara_order.log</td>
159
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_avalara_order}) %>
160
+ </td>
161
+ <td>
162
+ <%= link_to("Clear Data", {controller: :avatax_settings, action: :erase_data, remote: true, log_name: "avalara_order"}) %>
163
+ </td>
164
+ </tr>
165
+ </table>
166
+ </td>
167
+ </tr>
168
+ </table>
169
+ </fieldset>
170
+ </div>
171
+ </div>
172
+
173
+ <p class="form-buttons"><%= button Spree.t('save_preferences') %></p>
174
+
175
+ <% end %>
176
+
177
+ <% content_for :head do %>
178
+ <%= javascript_tag do -%>
179
+ $(document).ready(function(){
180
+ $('span#scountry .select2').on('change', function() { update_state('s'); });
181
+ });
182
+ <% end -%>
183
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% success = flash.discard(:success)
2
+ if success %>
3
+ show_flash('success', "<%= success %>")
4
+ <% end %>
5
+ <% error = flash.discard(:error)
6
+ if error %>
7
+ show_flash('error', "<%= error %>")
8
+ <% end %>
@@ -0,0 +1,124 @@
1
+ <%= render 'spree/admin/shared/taxes_tabs' %>
2
+
3
+ <% content_for :page_title do %>
4
+ <%= Spree.t(:avalara_settings) %>
5
+ <% end %>
6
+
7
+ <% content_for :page_actions do %>
8
+ <li><%= link_to_with_icon 'edit', Spree.t(:edit_avalara_settings), edit_admin_avatax_settings_path, :class => 'button' %></li>
9
+ <% end %>
10
+
11
+ <table>
12
+ <tr>
13
+ <th scope="row"><%= Spree.t(:avatax_company_code) %>:</th>
14
+ <td><%= Spree::AvalaraPreference.company_code.value %></td>
15
+ </tr>
16
+ <tr>
17
+ <th scope="row"><%= Spree.t(:avatax_license_key) %>:</th>
18
+ <td><%= Spree::AvalaraPreference.license_key.value %></td>
19
+ </tr>
20
+ <tr>
21
+ <th scope="row"><%= Spree.t(:avatax_account) %>:</th>
22
+ <td><%= Spree::AvalaraPreference.account.value %></td>
23
+ </tr>
24
+ <tr>
25
+ <th scope="row"><%= Spree.t(:avatax_endpoint) %>:</th>
26
+ <td><%= Spree::AvalaraPreference.endpoint.value %></td>
27
+ </tr>
28
+ <tr>
29
+ <th scope="row"><%= Spree.t(:avatax_tax_service_path) %>:</th>
30
+ <td><%= AVATAX_SERVICEPATH_TAX %></td>
31
+ </tr>
32
+ <tr>
33
+ <th scope="row"><%= Spree.t(:avatax_address_service_path) %>:</th>
34
+ <td><%= AVATAX_SERVICEPATH_ADDRESS %></td>
35
+ </tr>
36
+ <tr>
37
+ <th scope="row"><%= Spree.t(:enable_avatax_logging) %>:</th>
38
+ <td><%= Spree::AvalaraPreference.log.value %></td>
39
+ </tr>
40
+ <tr>
41
+ <th scope="row"><%= Spree.t(:enable_avatax_log_to_stdout) %>:</th>
42
+ <td><%= Spree::AvalaraPreference.log_to_stdout.value %></td>
43
+ </tr>
44
+ <tr>
45
+ <th scope="row"><%= Spree.t(:enable_avatax_address_validation) %>:</th>
46
+ <td><%= Spree::AvalaraPreference.address_validation.value %></td>
47
+ </tr>
48
+ <tr>
49
+ <th scope="row">Refuse Checkout if Address Validation Fails</th>
50
+ <td><%= Spree::AvalaraPreference.refuse_checkout_address_validation_error.value %></td>
51
+ </tr>
52
+ <tr>
53
+ <th scope="row">Customer can Validate Address in Checkout</th>
54
+ <td><%= Spree::AvalaraPreference.customer_can_validate.value %></td>
55
+ </tr>
56
+ <tr>
57
+ <th scope="row"><%= Spree.t(:avatax_address_validation_enabled_countries) %>:</th>
58
+ <% address_validated_countries = Spree::AvalaraPreference.validation_enabled_countries_array %>
59
+ <td>
60
+ <% unless address_validated_countries.nil? %>
61
+ <ul style="list-style: inside;">
62
+ <% address_validated_countries.each do |country| %>
63
+ <li><%= Spree::Country.find_by_name(country) %></li>
64
+ <% end %>
65
+ </ul>
66
+ <% end %>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <th scope="row"><%= Spree.t(:enable_avatax_tax_calculation) %>:</th>
71
+ <td><%= Spree::AvalaraPreference.tax_calculation.value %></td>
72
+ </tr>
73
+ <tr>
74
+ <th scope="row"><%= Spree.t(:enable_avatax_document_committing) %>:</th>
75
+ <td><%= Spree::AvalaraPreference.document_commit.value %></td>
76
+ </tr>
77
+
78
+ <tr>
79
+ <th scope="row"><%= Spree.t(:business_address) %>:</th>
80
+
81
+ <td><table>
82
+ <tr><td><%= Spree.t(:address1) %>: <%= @avatax_origin["Line1"] %> </td></tr>
83
+ <tr><td><%= Spree.t(:address2) %>: <%= @avatax_origin["Line2"] %></td></tr>
84
+ <tr><td><%= Spree.t(:city) %>: <%= @avatax_origin["City"] %></td></tr>
85
+ <tr><td><%= Spree.t(:state) %>: <%= @avatax_origin["Region"] %></td></tr>
86
+ <tr><td><%= Spree.t(:zipcode) %>: <%= @avatax_origin["PostalCode"] %></td></tr>
87
+ <tr><td><%= Spree.t(:country_code) %>: <%= @avatax_origin["Country"] %></td></tr>
88
+ </table></td>
89
+ </tr>
90
+ <tr>
91
+ <th>Connection Status</th>
92
+ <td>
93
+ <%= link_to({:controller => :avatax_settings, :action => :ping_my_service, :remote => true }, {:class => 'btn btn-small'}) do %>
94
+ <button>Test Connection</button> <% end %>
95
+ </td>
96
+
97
+ </tr>
98
+
99
+
100
+
101
+ <tr>
102
+ <th>View Log Files</th>
103
+ <td>
104
+ Log files are located in the log directory of your spree website.
105
+ <table>
106
+ <tr>
107
+ <td>Tax Service calls - tax_svc.log</td>
108
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_txt_tax_svc}) %>
109
+ </td>
110
+ </tr>
111
+ <tr>
112
+ <td>Avalara Function calls - post_order_to_avalara.log</td>
113
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_post_order_to_avalara}) %>
114
+ </td>
115
+ </tr>
116
+ <tr>
117
+ <td>Spree Order Item integration calls - avalara_order.log</td>
118
+ <td><%= link_to("Download", {controller: :avatax_settings, action: :get_file_avalara_order}) %>
119
+ </td>
120
+ </tr>
121
+ </table>
122
+ </td>
123
+ </tr>
124
+ </table>
@@ -0,0 +1,8 @@
1
+ <% success = flash.discard(:success)
2
+ if success %>
3
+ show_flash('success', "<%= success %>")
4
+ <% end %>
5
+ <% error = flash.discard(:error)
6
+ if error %>
7
+ show_flash('error', "<%= error %>")
8
+ <% end %>
@@ -0,0 +1,53 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to "#{Spree.t(:editing_user)} #{@user.email}", edit_admin_user_url(@user) %>
3
+ <% end %>
4
+
5
+ <%= render :partial => 'spree/admin/users/sidebar', :locals => { :current => :account } %>
6
+ <%= render :partial => 'spree/admin/users/user_page_actions' %>
7
+
8
+ <fieldset data-hook="admin_user_edit_general_settings" class="alpha twelve columns">
9
+ <legend><%= Spree.t(:general_settings) %></legend>
10
+
11
+ <div data-hook="admin_user_edit_form_header">
12
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @user } %>
13
+ </div>
14
+
15
+ <div data-hook="admin_user_edit_form">
16
+ <%= form_for [:admin, @user], as: :user, url: avalara_information_admin_user_url(@user), method: :put do |f| %>
17
+ <div class="alpha six columns">
18
+ <div class="field">
19
+ <label>Customer Code</label>
20
+ <input type="text" class="fullwidth" placeholder="<%= @user.id %>", readonly>
21
+ </div>
22
+ </div>
23
+ <% use_codes_list = Spree::AvalaraEntityUseCode.all.map {|use_code| ["#{use_code.use_code}) #{use_code.use_code_description}", use_code.id]} %>
24
+ <div class="omega six columns">
25
+ <%= f.field_container :avalara_entity_use_code_id do %>
26
+ <%= label_tag :avalara_entity_use_code_id, t(:avalara_entity_use_code) %><br />
27
+ <%= f.select(:avalara_entity_use_code_id, use_codes_list, include_blank: true) %>
28
+ <% end %>
29
+ </div>
30
+ <div class="clear"></div>
31
+ <div class="alpha six columns">
32
+ <%= f.field_container :exemption_number do %>
33
+ <%= f.label :exemption_number, Spree.t(:exemption_number) %>
34
+ <%= f.text_field :exemption_number, :class => 'fullwidth' %>
35
+ <% end %>
36
+ </div>
37
+ <div class="omega six columns">
38
+ <%= f.field_container :vat_id do %>
39
+ <%= f.label :vat_id, Spree.t(:vat_identification_number) %>
40
+ <%= f.text_field :vat_id, :class => 'fullwidth' %>
41
+ <% end %>
42
+ </div>
43
+ <br><br><br>
44
+ <div class="clear"></div>
45
+ <% if can?(:update, @user) %>
46
+ <div data-hook="admin_user_edit_form_button">
47
+ <%= render :partial => 'spree/admin/shared/edit_resource_links', :locals => { :collection_url => admin_users_url } %>
48
+ </div>
49
+ <% end %>
50
+ </div>
51
+ <% end %>
52
+ </fieldset>
53
+
@@ -0,0 +1,35 @@
1
+ <div class="columns alpha six" data-hook="billing_fieldset_wrapper">
2
+ <fieldset id="billing" data-hook>
3
+ <%= form.fields_for :bill_address do |bill_form| %>
4
+ <legend align="center"><%= Spree.t(:billing_address) %></legend>
5
+ <%= render :partial => 'spree/address/form', :locals => { :form => bill_form, :address_type => 'billing', :address => @order.bill_address } %>
6
+ <% end %>
7
+ </fieldset>
8
+ </div>
9
+
10
+ <div class="columns omega six" data-hook="shipping_fieldset_wrapper">
11
+ <fieldset id="shipping" data-hook>
12
+ <%= form.fields_for :ship_address do |ship_form| %>
13
+ <legend align="center"><%= Spree.t(:shipping_address) %></legend>
14
+ <p class="field checkbox" data-hook="use_billing">
15
+ <%= check_box_tag 'order[use_billing]', '1', @order.shipping_eq_billing_address? %>
16
+ <%= label_tag :order_use_billing, Spree.t(:use_billing_address), :id => 'use_billing' %>
17
+ </p>
18
+ <%= render :partial => 'spree/address/form', :locals => { :form => ship_form, :address_type => 'shipping', :address => @order.ship_address } %>
19
+ <% end %>
20
+ </fieldset>
21
+ </div>
22
+ <hr class="clear" />
23
+
24
+ <%= render partial: 'spree/checkout/address_validator_button' %>
25
+
26
+ <div class="form-buttons" data-hook="buttons">
27
+ <%= submit_tag Spree.t(:save_and_continue), :class => 'continue button primary' %>
28
+ <% if try_spree_current_user %>
29
+ <span data-hook="save_user_address">
30
+ &nbsp; &nbsp;
31
+ <%= check_box_tag 'save_user_address', '1', try_spree_current_user.respond_to?(:persist_order_address) %>
32
+ <%= label_tag :save_user_address, Spree.t(:save_my_address) %>
33
+ </span>
34
+ <% end %>
35
+ </div>
@@ -0,0 +1,3 @@
1
+ <% if Spree::AvalaraPreference.customer_can_validate.is_true? %>
2
+ <button class='button address_validator'>Validate Ship Address</button>
3
+ <% end %>
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/solidus_avatax_certified/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
data/circle.yml ADDED
@@ -0,0 +1,17 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.3.3
4
+
5
+ database:
6
+ override:
7
+ # replace CircleCI's generated database.yml
8
+ # this gem uses sqlite in a dummy app anyway
9
+ - echo "noop"
10
+
11
+ test:
12
+ pre:
13
+ - gem install bundler --pre
14
+ - bundle exec rake test_app:
15
+ environment:
16
+ RAILS_ENV: test
17
+ RACK_ENV: test
@@ -0,0 +1,5 @@
1
+ gem_version = File.read(File.expand_path('../../../GEM_VERSION',__FILE__)).strip
2
+
3
+ AVATAX_CLIENT_VERSION = "a0o33000004FH8l"
4
+ AVATAX_SERVICEPATH_ADDRESS = '/1.0/address/'
5
+ AVATAX_SERVICEPATH_TAX = '/1.0/tax/'
@@ -0,0 +1,3 @@
1
+ Spree.user_class = "Spree::User"
2
+ Spree::PermittedAttributes.user_attributes.concat([:avalara_entity_use_code_id, :exemption_number, :vat_id])
3
+ Rails.application.config.spree.calculators.tax_rates << Spree::Calculator::AvalaraTransaction
@@ -0,0 +1,35 @@
1
+ en:
2
+ spree:
3
+ vat_identification_number: VAT Identification Number
4
+ avalara_transaction_calculator: Avalara Transaction Calculator
5
+ avalara_entity_use_codes: Avalara Entity Use Codes
6
+ new_avalara_entity_use_code: New Avalara Entity Use Code
7
+ back_to_avalara_entity_use_codes_list: Back to Avalara Entity Use Codes List
8
+ editing_avalara_entity_use_code: Editing Avalara Entity Use Code
9
+ use_code: Use Code
10
+ use_code_description: Use Code Description
11
+ avalara_settings: Avalara Settings
12
+ edit_avalara_settings: Edit Avalara Settings
13
+ avatax_company_code: Avatax Company Code
14
+ avatax_license_key: Avatax License Key
15
+ avatax_account: Avatax Account
16
+ avatax_endpoint: Avatax Endpoint
17
+ avatax_tax_service_path: Avatax Tax Service Path
18
+ avatax_address_service_path: Avatax Address Service Path
19
+ enable_avatax_logging: Enable Avatax Logging
20
+ enable_avatax_log_to_stdout: Enable Logging to STDOUT
21
+ enable_avatax_address_validation: Enable Address Validation
22
+ avatax_address_validation_enabled_countries: Address Validation Enabled Countries
23
+ enable_avatax_tax_calculation: Enable Avatax Tax Calculation
24
+
25
+ enable_avatax_document_committing: Enable Avatax Document Committing
26
+ business_address: Business Address
27
+ country_code: 'Country Code (eg: US, GB ect)'
28
+ avatax_api_keys: Avatax API keys
29
+ avatax_endpoint_urls: Avatax Endpoint URLs
30
+ avatax_logging: Avatax Logging
31
+ avatax_address_validation: Avatax Address Validation
32
+ log_files: Log Files
33
+ avatax_tax_calculation: Avatax Tax Calculation
34
+ avatax_document_committing: Avatax Document Committing
35
+ save_preferences: Save Preferences
data/config/routes.rb ADDED
@@ -0,0 +1,18 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ namespace :admin do
3
+ resources :avalara_entity_use_codes
4
+
5
+ resource :avatax_settings do
6
+ get :ping_my_service, :get_file_txt_tax_svc, :get_file_post_order_to_avalara, :get_file_avalara_order, :erase_data, :validate_address
7
+ end
8
+
9
+ resources :users do
10
+ member do
11
+ get :avalara_information
12
+ put :avalara_information
13
+ end
14
+ end
15
+ end
16
+
17
+ get '/checkout/validate_address', to: 'checkout#validate_address', as: :validate_address
18
+ end
@@ -0,0 +1,9 @@
1
+ class CreateSpreeAvalaraTransactions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_avalara_transactions do |t|
4
+ t.references :order, index: true
5
+
6
+ t.timestamps null: false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class CreateSpreeAvalaraEntityUseCodes < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_avalara_entity_use_codes do |t|
4
+ t.string :use_code
5
+ t.string :use_code_description
6
+ t.timestamps null: false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class AddColumnsToSpreeUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_users, :exemption_number, :string
4
+ add_reference :spree_users, :avalara_entity_use_code, index: true
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ class CreateSpreeAvalaraPreferences < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_avalara_preferences do |t|
4
+ t.string :name, null: false
5
+ t.string :value
6
+ t.string :object_type, null: false
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class AddVatIdToSpreeUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_users, :vat_id, :string
4
+ end
5
+ end
data/db/seeds.rb ADDED
@@ -0,0 +1 @@
1
+ SolidusAvataxCertified::PreferenceSeeder.seed!
@@ -0,0 +1,45 @@
1
+ module SolidusAvataxCertified
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ def add_javascripts
6
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_avatax_certified\n"
7
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_avatax_certified\n"
8
+ end
9
+
10
+ def add_stylesheets
11
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_avatax_certified\n", :before => /\*\//, :verbose => true
12
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_avatax_certified\n", :before => /\*\//, :verbose => true
13
+ end
14
+
15
+ def add_migrations
16
+ run 'bundle exec rake railties:install:migrations FROM=solidus_avatax_certified'
17
+ end
18
+
19
+ def auto_migrate?
20
+ ENV['AUTO_RUN_MIGRATIONS'] =~ /true/i
21
+ end
22
+
23
+ def run_migrations
24
+ # hiding this inside parent method so it's not auto-run by rails generator
25
+ def migration_prompt_approved?
26
+ result = ask('Would you like to run the migrations now? [Y/n]')
27
+ !(result =~ /n/i)
28
+ end
29
+
30
+ if auto_migrate? || migration_prompt_approved?
31
+ run 'bundle exec rake db:migrate'
32
+ else
33
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
34
+ end
35
+ end
36
+
37
+ def include_seed_data
38
+ append_file "db/seeds.rb", <<-SEEDS
39
+ \n
40
+ SolidusAvataxCertified::Engine.load_seed if defined?(SolidusAvataxCertified::Engine)
41
+ SEEDS
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,22 @@
1
+ module SolidusAvataxCertified
2
+ class Engine < Rails::Engine
3
+ require "solidus_core"
4
+ isolate_namespace Spree
5
+ engine_name 'solidus_avatax_certified'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ # use rspec for tests
10
+ config.generators do |g|
11
+ g.test_framework :rspec
12
+ end
13
+
14
+ def self.activate
15
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
16
+ Rails.configuration.cache_classes ? require(c) : load(c)
17
+ end
18
+ end
19
+
20
+ config.to_prepare &method(:activate).to_proc
21
+ end
22
+ end