Taxjar_Salestaxautomation - Version 2.0.0

Version Notes

* Moved TaxJar configuration to System > Configuration > Tax. This is a breaking change with new configuration fields. If upgrading from a previous version, you'll need to re-connect to TaxJar and re-enable your settings.
* Streamlined configuration with focus on SmartCalcs for upcoming free calculations and zip-based rates as a fallback.
* New "Connect to TaxJar" button for faster onboarding.
* New select fields for assigning backup tax rules to custom product and customer tax classes.
* New AJAX sync button for manually refreshing backup rates from TaxJar.
* Admin notifications tied to our RSS feed for extension updates and news.

Download this release

Release Info

Developer TaxJar
Extension Taxjar_Salestaxautomation
Version 2.0.0
Comparing to
See all releases


Code changes from version 1.6.1 to 2.0.0

Files changed (28) hide show
  1. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Backup.php +40 -0
  2. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Enabled.php +42 -0
  3. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Multiselect.php +29 -0
  4. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Edit/Form.php +2 -1
  5. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Grid.php +4 -2
  6. app/code/community/Taxjar/SalesTax/Model/Categories.php +1 -1
  7. app/code/community/Taxjar/SalesTax/Model/Client.php +38 -3
  8. app/code/community/Taxjar/SalesTax/Model/Comment.php +166 -0
  9. app/code/community/Taxjar/SalesTax/Model/Configuration.php +14 -14
  10. app/code/community/Taxjar/SalesTax/Model/Debug.php +9 -5
  11. app/code/community/Taxjar/SalesTax/Model/Import/Comment.php +61 -25
  12. app/code/community/Taxjar/SalesTax/Model/Import/Rate.php +1 -1
  13. app/code/community/Taxjar/SalesTax/Model/Import/Rule.php +8 -7
  14. app/code/community/Taxjar/SalesTax/Model/Observer/AdminNotifications.php +35 -0
  15. app/code/community/Taxjar/SalesTax/Model/Observer/ConfigChanged.php +50 -0
  16. app/code/community/Taxjar/SalesTax/Model/Observer/ImportData.php +85 -0
  17. app/code/community/Taxjar/SalesTax/Model/Observer/ImportRates.php +164 -27
  18. app/code/community/Taxjar/SalesTax/Model/Observer/SalesQuoteCollectTotalsBefore.php +1 -1
  19. app/code/community/Taxjar/SalesTax/Model/Observer/SaveConfig.php +0 -162
  20. app/code/community/Taxjar/SalesTax/Model/Sales/Total/Quote/Tax.php +4 -2
  21. app/code/community/Taxjar/SalesTax/Model/Smartcalcs.php +17 -20
  22. app/code/community/Taxjar/SalesTax/Model/Tax/Class/Source/Customer.php +39 -0
  23. app/code/community/Taxjar/SalesTax/Model/Tax/Class/Source/Product.php +39 -0
  24. app/code/community/Taxjar/SalesTax/controllers/Adminhtml/TaxjarController.php +75 -0
  25. app/code/community/Taxjar/SalesTax/etc/adminhtml.xml +0 -40
  26. app/code/community/Taxjar/SalesTax/etc/config.xml +37 -32
  27. app/code/community/Taxjar/SalesTax/etc/system.xml +62 -43
  28. package.xml +10 -7
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Backup.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Backup Dropdown Renderer
20
+ * Handle state based on presence of API token
21
+ */
22
+ class Taxjar_SalesTax_Block_Adminhtml_Backup extends Mage_Adminhtml_Block_System_Config_Form_Field
23
+ {
24
+ protected function _getElementHtml($element)
25
+ {
26
+ $apiKey = trim(Mage::getStoreConfig('tax/taxjar/apikey'));
27
+
28
+ if ($apiKey) {
29
+ $this->_cacheElementValue($element);
30
+ }
31
+
32
+ return parent::_getElementHtml($element);
33
+ }
34
+
35
+ protected function _cacheElementValue($element)
36
+ {
37
+ $elementValue = (string) $element->getValue();
38
+ Mage::app()->getCache()->save($elementValue, 'taxjar_salestax_config_backup', array('TAXJAR_SALESTAX_BACKUP'), null);
39
+ }
40
+ }
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Enabled.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Config Enabled Dropdown Renderer
20
+ * Handle state based on presence of API token
21
+ */
22
+ class Taxjar_SalesTax_Block_Adminhtml_Enabled extends Mage_Adminhtml_Block_System_Config_Form_Field
23
+ {
24
+ protected function _getElementHtml($element)
25
+ {
26
+ $apiKey = trim(Mage::getStoreConfig('tax/taxjar/apikey'));
27
+
28
+ if (!$apiKey) {
29
+ $element->setDisabled('disabled');
30
+ } else {
31
+ $this->_cacheElementValue($element);
32
+ }
33
+
34
+ return parent::_getElementHtml($element);
35
+ }
36
+
37
+ protected function _cacheElementValue($element)
38
+ {
39
+ $elementValue = (string) $element->getValue();
40
+ Mage::app()->getCache()->save($elementValue, 'taxjar_salestax_config_enabled', array('TAXJAR_SALESTAX_ENABLED'), null);
41
+ }
42
+ }
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Multiselect.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Config Enabled Dropdown Renderer
20
+ * Handle state based on presence of API token
21
+ */
22
+ class Taxjar_SalesTax_Block_Adminhtml_Multiselect extends Mage_Adminhtml_Block_System_Config_Form_Field
23
+ {
24
+ protected function _getElementHtml($element)
25
+ {
26
+ $element->setSize(4);
27
+ return parent::_getElementHtml($element);
28
+ }
29
+ }
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Edit/Form.php CHANGED
@@ -21,10 +21,11 @@ class Taxjar_SalesTax_Block_Adminhtml_Tax_Class_Edit_Form extends Mage_Adminhtml
21
  {
22
  parent::_prepareForm();
23
 
 
24
  $fieldset = $this->getForm()->getElement('base_fieldset');
25
  $currentClass = Mage::registry('tax_class');
26
 
27
- if ($this->getClassType() == 'PRODUCT') {
28
  $fieldset->addField(
29
  'tj_salestax_code', 'select', array(
30
  'name' => 'tj_salestax_code',
21
  {
22
  parent::_prepareForm();
23
 
24
+ $connected = Mage::getStoreConfig('tax/taxjar/connected');
25
  $fieldset = $this->getForm()->getElement('base_fieldset');
26
  $currentClass = Mage::registry('tax_class');
27
 
28
+ if ($connected && $this->getClassType() == 'PRODUCT') {
29
  $fieldset->addField(
30
  'tj_salestax_code', 'select', array(
31
  'name' => 'tj_salestax_code',
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Grid.php CHANGED
@@ -19,9 +19,11 @@ class Taxjar_SalesTax_Block_Adminhtml_Tax_Class_Grid extends Mage_Adminhtml_Bloc
19
  {
20
  protected function _prepareColumns()
21
  {
22
- parent::_prepareColumns();
23
 
24
- if ($this->getClassType() == 'PRODUCT') {
 
 
25
  $this->addColumn(
26
  'tj_salestax_code', array(
27
  'header' => Mage::helper('taxjar')->__('TaxJar Category Code'),
19
  {
20
  protected function _prepareColumns()
21
  {
22
+ parent::_prepareColumns();
23
 
24
+ $connected = Mage::getStoreConfig('tax/taxjar/connected');
25
+
26
+ if ($connected && $this->getClassType() == 'PRODUCT') {
27
  $this->addColumn(
28
  'tj_salestax_code', array(
29
  'header' => Mage::helper('taxjar')->__('TaxJar Category Code'),
app/code/community/Taxjar/SalesTax/Model/Categories.php CHANGED
@@ -29,7 +29,7 @@ class Taxjar_SalesTax_Model_Categories
29
  */
30
  public function toOptionArray()
31
  {
32
- $categories = json_decode(Mage::getStoreConfig('taxjar/config/categories'), true);
33
  $categories = Mage::helper('taxjar')->array_sort($categories, 'product_tax_code', SORT_ASC);
34
 
35
  $output = array(
29
  */
30
  public function toOptionArray()
31
  {
32
+ $categories = json_decode(Mage::getStoreConfig('tax/taxjar/categories'), true);
33
  $categories = Mage::helper('taxjar')->array_sort($categories, 'product_tax_code', SORT_ASC);
34
 
35
  $output = array(
app/code/community/Taxjar/SalesTax/Model/Client.php CHANGED
@@ -22,6 +22,16 @@
22
  */
23
  class Taxjar_SalesTax_Model_Client
24
  {
 
 
 
 
 
 
 
 
 
 
25
  /**
26
  * Connect to the API
27
  *
@@ -29,9 +39,9 @@ class Taxjar_SalesTax_Model_Client
29
  * @param string $url
30
  * @return string
31
  */
32
- public function getResource($apiKey, $url)
33
  {
34
- $response = $this->getClient($apiKey, $url)->request();
35
 
36
  if ($response->isSuccessful()) {
37
  $json = $response->getBody();
@@ -52,7 +62,7 @@ class Taxjar_SalesTax_Model_Client
52
  * @param string $url
53
  * @return Varien_Http_Client $response
54
  */
55
- private function getClient($apiKey, $url)
56
  {
57
  $client = new Varien_Http_Client($url);
58
  $client->setMethod(Varien_Http_Client::GET);
@@ -60,4 +70,29 @@ class Taxjar_SalesTax_Model_Client
60
 
61
  return $client;
62
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
22
  */
23
  class Taxjar_SalesTax_Model_Client
24
  {
25
+ protected $_version = 'v2';
26
+ protected $_storeZip;
27
+ protected $_storeRegionCode;
28
+
29
+ public function __construct()
30
+ {
31
+ $this->_storeZip = trim(Mage::getStoreConfig('shipping/origin/postcode'));
32
+ $this->_storeRegionCode = Mage::getModel('directory/region')->load(Mage::getStoreConfig('shipping/origin/region_id'))->getCode();
33
+ }
34
+
35
  /**
36
  * Connect to the API
37
  *
39
  * @param string $url
40
  * @return string
41
  */
42
+ public function getResource($apiKey, $resource)
43
  {
44
+ $response = $this->_getClient($apiKey, $this->_getApiUrl($resource))->request();
45
 
46
  if ($response->isSuccessful()) {
47
  $json = $response->getBody();
62
  * @param string $url
63
  * @return Varien_Http_Client $response
64
  */
65
+ private function _getClient($apiKey, $url)
66
  {
67
  $client = new Varien_Http_Client($url);
68
  $client->setMethod(Varien_Http_Client::GET);
70
 
71
  return $client;
72
  }
73
+
74
+ /**
75
+ * Get SmartCalcs API URL
76
+ *
77
+ * @param string $type
78
+ * @return string
79
+ */
80
+ private function _getApiUrl($resource)
81
+ {
82
+ $apiUrl = 'https://api.taxjar.com/' . $this->_version;
83
+
84
+ switch($resource) {
85
+ case 'config':
86
+ $apiUrl .= '/plugins/magento/configuration/' . $this->_storeRegionCode;
87
+ break;
88
+ case 'rates':
89
+ $apiUrl .= '/plugins/magento/rates/' . $this->_storeRegionCode . '/' . $this->_storeZip;
90
+ break;
91
+ case 'categories':
92
+ $apiUrl .= '/categories';
93
+ break;
94
+ }
95
+
96
+ return $apiUrl;
97
+ }
98
  }
app/code/community/Taxjar/SalesTax/Model/Comment.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * TaxJar Extension UI
20
+ * Returns TaxJar account with connect buttons
21
+ */
22
+ class Taxjar_SalesTax_Model_Comment
23
+ {
24
+ private $_apiKey;
25
+ private $_apiEmail;
26
+
27
+ /**
28
+ * Display Nexus states loaded and API Key setting
29
+ *
30
+ * @param void
31
+ * @return string
32
+ */
33
+ public function getCommentText()
34
+ {
35
+ $this->_apiKey = Mage::getStoreConfig('tax/taxjar/apikey');
36
+ $this->_apiEmail = Mage::getStoreConfig('tax/taxjar/email');
37
+
38
+ if ($this->_apiKey) {
39
+ return $this->_buildConnectedHtml();
40
+ } else {
41
+ return $this->_buildDisconnectedHtml();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Build connected HTML
47
+ *
48
+ * @param void
49
+ * @return string
50
+ */
51
+ private function _buildConnectedHtml()
52
+ {
53
+ $htmlString = "<p class='note'><span>Sales tax calculations at checkout for improved accuracy and product exemptions. Magento's zip-based rates can be used as a fallback.</span></p><br/>";
54
+ $htmlString .= "<p class='note'><span>TaxJar Account</span></p>";
55
+ $htmlString .= "<ul class='messages'><li class='success-msg'><span style='font-size: 1.4em'>" . $this->_apiEmail . "</span></li></ul>";
56
+ $htmlString .= "<p class='note'><span>Getting Started</span></p><p></p>";
57
+ // $htmlString .= "<p><a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/taxjar/nexus_address/index') . "'>Nexus Addresses</a><br/><span style='font-size: 0.9em'>Before enabling SmartCalcs, set up your nexus addresses so TaxJar knows where to collect sales tax.</span></p>";
58
+ $htmlString .= "<p><a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/tax_class_product/index') . "'>Product Tax Classes</a><br/><span style='font-size: 0.9em'>If some of your products are tax-exempt, assign a TaxJar category tax code for new or existing product tax classes.</span></p>";
59
+ $htmlString .= "<p><a href='http://www.taxjar.com/contact/' target='_blank'>Help & Support</a><br/><span style='font-size: 0.9em'>Need help setting up SmartCalcs? Get in touch with our Magento sales tax experts.</span></p><br/>";
60
+ $htmlString .= $this->_buildConnectionHtml();
61
+ return $htmlString;
62
+ }
63
+
64
+ /**
65
+ * Build disconnected HTML
66
+ *
67
+ * @param void
68
+ * @return string
69
+ */
70
+ private function _buildDisconnectedHtml()
71
+ {
72
+ $htmlString = "<p class='note'><span>Sales tax calculations at checkout for improved accuracy and product exemptions. Magento's zip-based rates can be used as a fallback.</p>";
73
+ $htmlString .= $this->_buildConnectionHtml();
74
+ return $htmlString;
75
+ }
76
+
77
+ /**
78
+ * Build HTML for connect/disconnect buttons
79
+ *
80
+ * @param void
81
+ * @return string
82
+ */
83
+ private function _buildConnectionHtml()
84
+ {
85
+ $authUrl = 'https://app.taxjar.com';
86
+ $popupUrl = $authUrl . '/smartcalcs/connect/magento/?store=' . urlencode($this->_getStoreOrigin());
87
+ $guideUrl = 'http://www.taxjar.com/guides/integrations/magento/';
88
+ $connectUrl = Mage::helper('adminhtml')->getUrl('adminhtml/taxjar/connect');
89
+ $disconnectUrl = Mage::helper('adminhtml')->getUrl('adminhtml/taxjar/disconnect');
90
+
91
+ if (!empty($this->_getStoreGeneralEmail())) {
92
+ $popupUrl .= '&email=' . urlencode($this->_getStoreGeneralEmail());
93
+ }
94
+
95
+ if (!$this->_apiKey) {
96
+ $htmlString = <<<EOT
97
+ <br/><p><button type='button' class='scalable' onclick='openConnectPopup("{$popupUrl}", "Connect to TaxJar", 400, 500)'><span>Connect to TaxJar</span></button>&nbsp;&nbsp;<button type='button' class='scalable' onclick='window.open("{$guideUrl}", "_blank")'><span>Learn More</span></button></p>
98
+ <script>
99
+ function openConnectPopup(url, title, w, h) {
100
+ var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
101
+ var dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;
102
+ var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
103
+ var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
104
+ var left = ((width / 2) - (w / 2)) + dualScreenLeft;
105
+ var top = ((height / 2) - (h / 2)) + dualScreenTop;
106
+
107
+ window.connectPopup = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
108
+
109
+ if (window.focus) window.connectPopup.focus();
110
+ }
111
+
112
+ window.addEventListener('message', function(e) {
113
+ if (e.origin !== '{$authUrl}')
114
+ return;
115
+
116
+ try {
117
+ var data = JSON.parse(e.data);
118
+ if (data.api_token && data.email) {
119
+ window.connectPopup.postMessage('Data received', '{$authUrl}');
120
+ window.location = encodeURI('{$connectUrl}?api_key=' + data.api_token + '&api_email=' + data.email);
121
+ } else {
122
+ throw 'Invalid data';
123
+ }
124
+ } catch(e) {
125
+ alert('Invalid API token or email provided. Please try connecting to TaxJar again or contact support@taxjar.com.');
126
+ }
127
+ }, false);
128
+ </script>
129
+ EOT;
130
+ } else {
131
+ $htmlString = <<<EOT
132
+ <p><button type='button' class='scalable delete' onclick='if (window.confirm("Are you sure you want to disconnect from TaxJar? This will remove all TaxJar rates from your Magento store. If you have a paid TaxJar subscription, manage your account at https://app.taxjar.com.")) window.location="{$disconnectUrl}"'><span>Disconnect TaxJar</span></button>&nbsp;&nbsp;<button type='button' class='scalable' onclick='window.open("{$guideUrl}", "_blank")'><span>Learn More</span></button></p><br/>
133
+ EOT;
134
+ }
135
+
136
+ return $htmlString;
137
+ }
138
+
139
+ /**
140
+ * Get current store origin
141
+ *
142
+ * @param void
143
+ * @return string
144
+ */
145
+ private function _getStoreOrigin()
146
+ {
147
+ $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
148
+ return $protocol . $_SERVER['HTTP_HOST'];
149
+ }
150
+
151
+ /**
152
+ * Get store general contact email if non-default
153
+ *
154
+ * @param void
155
+ * @return string
156
+ */
157
+ private function _getStoreGeneralEmail()
158
+ {
159
+ $email = Mage::getStoreConfig('trans_email/ident_general/email');
160
+ if ($email != 'owner@example.com') {
161
+ return $email;
162
+ } else {
163
+ return '';
164
+ }
165
+ }
166
+ }
app/code/community/Taxjar/SalesTax/Model/Configuration.php CHANGED
@@ -35,7 +35,7 @@ class Taxjar_SalesTax_Model_Configuration
35
  $taxClass = 4;
36
  }
37
 
38
- $this->setConfig('tax/classes/shipping_tax_class', $taxClass);
39
  }
40
 
41
  /**
@@ -52,7 +52,7 @@ class Taxjar_SalesTax_Model_Configuration
52
  $basis = 'origin';
53
  }
54
 
55
- $this->setConfig('tax/calculation/based_on', $basis);
56
  }
57
 
58
  /**
@@ -72,7 +72,7 @@ class Taxjar_SalesTax_Model_Configuration
72
  );
73
 
74
  foreach ($settings as $setting) {
75
- $this->setConfig($setting, 1);
76
  }
77
  }
78
 
@@ -88,9 +88,9 @@ class Taxjar_SalesTax_Model_Configuration
88
  $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
89
 
90
  if (!$existingUserId) {
91
- $apiUserId = $this->createApiUser($apiKey);
92
- $parentRoleId = $this->createApiRoles($apiUserId);
93
- $this->createApiRules($parentRoleId);
94
  }
95
  }
96
 
@@ -100,9 +100,9 @@ class Taxjar_SalesTax_Model_Configuration
100
  * @param integer $parentRoleId
101
  * @return void
102
  */
103
- private function createApiRules($parentRoleId)
104
  {
105
- foreach ($this->resourcesToAllow() as $resource) {
106
  $apiRule = Mage::getModel('api/rules');
107
  $apiRule->setRoleId($parentRoleId);
108
  $apiRule->setResourceId($resource);
@@ -111,7 +111,7 @@ class Taxjar_SalesTax_Model_Configuration
111
  $apiRule->save();
112
  }
113
 
114
- foreach ($this->resourcesToDeny() as $resource) {
115
  $apiRule = Mage::getModel('api/rules');
116
  $apiRule->setRoleId($parentRoleId);
117
  $apiRule->setResourceId($resource);
@@ -127,7 +127,7 @@ class Taxjar_SalesTax_Model_Configuration
127
  * @param integer $apiUserId
128
  * @return integer
129
  */
130
- private function createApiRoles($apiUserId)
131
  {
132
  $parentApiRole = Mage::getModel('api/role');
133
  $parentApiRole->setRoleName('taxjar_api');
@@ -153,7 +153,7 @@ class Taxjar_SalesTax_Model_Configuration
153
  * @param void
154
  * @return void
155
  */
156
- private function createApiUser($apiKey)
157
  {
158
  $apiUser = Mage::getModel('api/user');
159
  $apiUser->setUsername('taxjar');
@@ -174,7 +174,7 @@ class Taxjar_SalesTax_Model_Configuration
174
  * @param string $value
175
  * @return void
176
  */
177
- private function setConfig($path, $value)
178
  {
179
  Mage::getConfig()->saveConfig($path, $value, 'default', 0);
180
  }
@@ -185,7 +185,7 @@ class Taxjar_SalesTax_Model_Configuration
185
  * @param void
186
  * @return array
187
  */
188
- private function resourcesToAllow()
189
  {
190
  return array(
191
  'sales',
@@ -220,7 +220,7 @@ class Taxjar_SalesTax_Model_Configuration
220
  * @param void
221
  * @return array
222
  */
223
- private function resourcesToDeny()
224
  {
225
  return array(
226
  'core',
35
  $taxClass = 4;
36
  }
37
 
38
+ $this->_setConfig('tax/classes/shipping_tax_class', $taxClass);
39
  }
40
 
41
  /**
52
  $basis = 'origin';
53
  }
54
 
55
+ $this->_setConfig('tax/calculation/based_on', $basis);
56
  }
57
 
58
  /**
72
  );
73
 
74
  foreach ($settings as $setting) {
75
+ $this->_setConfig($setting, 1);
76
  }
77
  }
78
 
88
  $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
89
 
90
  if (!$existingUserId) {
91
+ $apiUserId = $this->_createApiUser($apiKey);
92
+ $parentRoleId = $this->_createApiRoles($apiUserId);
93
+ $this->_createApiRules($parentRoleId);
94
  }
95
  }
96
 
100
  * @param integer $parentRoleId
101
  * @return void
102
  */
103
+ private function _createApiRules($parentRoleId)
104
  {
105
+ foreach ($this->_resourcesToAllow() as $resource) {
106
  $apiRule = Mage::getModel('api/rules');
107
  $apiRule->setRoleId($parentRoleId);
108
  $apiRule->setResourceId($resource);
111
  $apiRule->save();
112
  }
113
 
114
+ foreach ($this->_resourcesToDeny() as $resource) {
115
  $apiRule = Mage::getModel('api/rules');
116
  $apiRule->setRoleId($parentRoleId);
117
  $apiRule->setResourceId($resource);
127
  * @param integer $apiUserId
128
  * @return integer
129
  */
130
+ private function _createApiRoles($apiUserId)
131
  {
132
  $parentApiRole = Mage::getModel('api/role');
133
  $parentApiRole->setRoleName('taxjar_api');
153
  * @param void
154
  * @return void
155
  */
156
+ private function _createApiUser($apiKey)
157
  {
158
  $apiUser = Mage::getModel('api/user');
159
  $apiUser->setUsername('taxjar');
174
  * @param string $value
175
  * @return void
176
  */
177
+ private function _setConfig($path, $value)
178
  {
179
  Mage::getConfig()->saveConfig($path, $value, 'default', 0);
180
  }
185
  * @param void
186
  * @return array
187
  */
188
+ private function _resourcesToAllow()
189
  {
190
  return array(
191
  'sales',
220
  * @param void
221
  * @return array
222
  */
223
+ private function _resourcesToDeny()
224
  {
225
  return array(
226
  'core',
app/code/community/Taxjar/SalesTax/Model/Debug.php CHANGED
@@ -29,10 +29,10 @@ class Taxjar_SalesTax_Model_Debug
29
  */
30
  public function getCommentText()
31
  {
32
- $debug = Mage::getStoreConfig('taxjar/config/debug');
33
 
34
  if ($debug) {
35
- return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p><br/>" . $this->getDebugHtmlString();
36
  } else {
37
  return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p>";
38
  }
@@ -44,16 +44,20 @@ class Taxjar_SalesTax_Model_Debug
44
  * @param void
45
  * @return string
46
  */
47
- private function getDebugHtmlString()
48
  {
49
- $states = implode(',', unserialize(Mage::getStoreConfig('taxjar/config/states')));
50
  $apiUser = Mage::getModel('api/user');
51
  $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
52
  $pluginVersion = '1.6.1';
53
  $phpMemory = @ini_get('memory_limit');
54
  $phpVersion = @phpversion();
55
  $magentoVersion = Mage::getVersion();
56
- $lastUpdated = Mage::getStoreConfig('taxjar/config/last_update');
 
 
 
 
57
 
58
  return "<ul> <li><strong>Additional States:</strong> ". $states ."</li> <li><strong>API User ID:</strong> ". $existingUserId ."</li><li><strong>Memory:</strong> ". $phpMemory ."</li> <li><strong>TaxJar Version:</strong> ". $pluginVersion ."</li> <li><strong>PHP Version</strong> ". $phpVersion ."</li> <li><strong>Magento Version:</strong> ". $magentoVersion ."</li> <li><strong>Last Updated:</strong> ". $lastUpdated ."</li> </ul><br/><p><small><strong>Include the above information when emailing TaxJar support at support@taxjar.com</strong><small></p>";
59
  }
29
  */
30
  public function getCommentText()
31
  {
32
+ $debug = Mage::getStoreConfig('tax/taxjar/debug');
33
 
34
  if ($debug) {
35
+ return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p><br/>" . $this->_getDebugHtmlString();
36
  } else {
37
  return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p>";
38
  }
44
  * @param void
45
  * @return string
46
  */
47
+ private function _getDebugHtmlString()
48
  {
49
+ $states = unserialize(Mage::getStoreConfig('tax/taxjar/states'));
50
  $apiUser = Mage::getModel('api/user');
51
  $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
52
  $pluginVersion = '1.6.1';
53
  $phpMemory = @ini_get('memory_limit');
54
  $phpVersion = @phpversion();
55
  $magentoVersion = Mage::getVersion();
56
+ $lastUpdated = Mage::getStoreConfig('tax/taxjar/last_update');
57
+
58
+ if (!empty($states)) {
59
+ $states = implode(',', $states);
60
+ }
61
 
62
  return "<ul> <li><strong>Additional States:</strong> ". $states ."</li> <li><strong>API User ID:</strong> ". $existingUserId ."</li><li><strong>Memory:</strong> ". $phpMemory ."</li> <li><strong>TaxJar Version:</strong> ". $pluginVersion ."</li> <li><strong>PHP Version</strong> ". $phpVersion ."</li> <li><strong>Magento Version:</strong> ". $magentoVersion ."</li> <li><strong>Last Updated:</strong> ". $lastUpdated ."</li> </ul><br/><p><small><strong>Include the above information when emailing TaxJar support at support@taxjar.com</strong><small></p>";
63
  }
app/code/community/Taxjar/SalesTax/Model/Import/Comment.php CHANGED
@@ -21,6 +21,8 @@
21
  */
22
  class Taxjar_SalesTax_Model_Import_Comment
23
  {
 
 
24
  /**
25
  * Display Nexus states loaded and API Key setting
26
  *
@@ -29,16 +31,14 @@ class Taxjar_SalesTax_Model_Import_Comment
29
  */
30
  public function getCommentText()
31
  {
 
32
  $regionId = Mage::getStoreConfig('shipping/origin/region_id');
33
- $regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
34
- $lastUpdate = Mage::getStoreConfig('taxjar/config/last_update');
35
 
36
- if (!empty($lastUpdate)) {
37
- $states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
38
- $statesHtml = $this->buildStatesHtml($states, $regionCode);
39
- return $this->buildInstalledHtml($statesHtml, $lastUpdate);
40
  } else {
41
- return $this->buildNotYetInstalledHtml($this->fullStateName($regionCode));
42
  }
43
  }
44
 
@@ -70,41 +70,45 @@ class Taxjar_SalesTax_Model_Import_Comment
70
  }
71
 
72
  /**
73
- * Build String from State Abbr
74
  *
75
- * @param string $stateCode
76
  * @return string
77
  */
78
- private function fullStateName($stateCode)
79
  {
80
- $regionModel = Mage::getModel('directory/region')->loadByCode($stateCode, 'US');
81
  return $regionModel->getDefaultName();
82
  }
83
 
84
  /**
85
- * Build HTML for installed text
86
  *
87
- * @param string $statesHtml
88
- * @param string $lastUpdate
89
  * @return string
90
  */
91
- private function buildInstalledHtml($statesHtml, $lastUpdate)
92
  {
93
- $htmlString = "<p class='note'><span>TaxJar is installed. Check the <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/tax_rule/index') . "'>Manage Tax Rules section</a> to verify all installed states.</span></p><br/><p>TaxJar has automatically added rates for the following states to your Magento installation:<br/><ul class='messages'>". $statesHtml . "</ul>To manage your TaxJar states <a href='https://app.taxjar.com/account#states' target='_blank'>click here</a>.</p><p>Your sales tax rates were last updated on: <ul class='messages'><li class='info-msg'><ul><li><span style='font-size: 1.4em;'>" . $lastUpdate . "</span></li></ul></li></ul><small>Rates may be automatically or manually updated again once per month. For more information on how your tax settings are changed, <a href='http://www.taxjar.com/guides/integrations/magento/' target='_blank'>click here</a>. Contact <a href='mailto:support@taxjar.com'>support@taxjar.com</a> with the email address registered to your TaxJar account if you need assistance.</small></p><p><small>If you would like to uninstall TaxJar, remove the API Token from the box above and save the config. This will remove all TaxJar rates from your Magento store. You can then uninstall in the Magento Connect Manager.<small></p><p><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</p>";
 
 
 
 
 
94
 
 
 
95
  return $htmlString;
96
  }
97
 
98
  /**
99
- * Build HTML for not yet installed text
100
  *
101
- * @param string $regionName
102
  * @return string
103
  */
104
- private function buildNotYetInstalledHtml($regionName)
105
  {
106
- $htmlString = "<p class='note'><span>Enter your TaxJar API Token</span></p><br/><p>Enter your TaxJar API Token to import current sales tax rates for all zip codes in <b>" . $regionName . "</b>, your state of origin as set in <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit/section/shipping') . "'>Shipping Settings</a>. We will also retrieve all other states from your TaxJar account. To get an API Token, go to <a href='https://app.taxjar.com/account' target='_blank'>TaxJar's Account Screen.</a></p><p>For more information on how your tax settings are changed, <a href='http://www.taxjar.com/guides/integrations/magento/' target='_blank'>click here</a>.</p><p><small><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</small></p>";
107
-
108
  return $htmlString;
109
  }
110
 
@@ -115,17 +119,18 @@ class Taxjar_SalesTax_Model_Import_Comment
115
  * @param string $regionCode
116
  * @return string
117
  */
118
- private function buildStatesHtml($states, $regionCode)
119
  {
120
- $states[] = $regionCode;
121
  $statesHtml = '';
 
122
 
123
  sort($states);
124
 
125
  $taxRatesByState = $this->getNumberOfRatesLoaded($states);
126
 
127
  foreach (array_unique($states) as $state) {
128
- if (($stateName = $this->fullStateName($state)) && !empty($stateName)) {
129
  if ($taxRatesByState['rates_by_state'][$state] == 1 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
130
  $totalForState = 'Origin-based rates set';
131
  $class = 'success';
@@ -137,7 +142,7 @@ class Taxjar_SalesTax_Model_Import_Comment
137
  $totalForState = $taxRatesByState['rates_by_state'][$state] . ' rates';
138
  }
139
 
140
- $statesHtml .= '<li class="' . $class . '-msg"><ul><li><span style="font-size: 1.4em;">' . $stateName . '</span>: ' . $totalForState . '</li></ul></li>';
141
  }
142
  }
143
 
@@ -148,7 +153,38 @@ class Taxjar_SalesTax_Model_Import_Comment
148
  }
149
 
150
  $statesHtml .= '<p class="' . $matches . '-msg" style="background: none !important;"><small>&nbsp;&nbsp;' . $taxRatesByState['total_rates'] . ' of ' . $taxRatesByState['rates_loaded'] . ' expected rates loaded.</small></p>';
 
151
 
152
  return $statesHtml;
153
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  }
21
  */
22
  class Taxjar_SalesTax_Model_Import_Comment
23
  {
24
+ protected $_regionCode;
25
+
26
  /**
27
  * Display Nexus states loaded and API Key setting
28
  *
31
  */
32
  public function getCommentText()
33
  {
34
+ $isEnabled = Mage::getStoreConfig('tax/taxjar/backup');
35
  $regionId = Mage::getStoreConfig('shipping/origin/region_id');
36
+ $this->_regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
 
37
 
38
+ if ($isEnabled) {
39
+ return $this->buildEnabledHtml();
 
 
40
  } else {
41
+ return $this->buildDisabledHtml();
42
  }
43
  }
44
 
70
  }
71
 
72
  /**
73
+ * Get region name from region code
74
  *
75
+ * @param string $regionCode
76
  * @return string
77
  */
78
+ private function getStateName($regionCode)
79
  {
80
+ $regionModel = Mage::getModel('directory/region')->loadByCode($regionCode, 'US');
81
  return $regionModel->getDefaultName();
82
  }
83
 
84
  /**
85
+ * Build HTML for backup rates enabled
86
  *
 
 
87
  * @return string
88
  */
89
+ private function buildEnabledHtml()
90
  {
91
+ $states = unserialize(Mage::getStoreConfig('tax/taxjar/states'));
92
+ $htmlString = "<p class='note'><span>Download zip-based rates from TaxJar as a fallback. TaxJar uses your shipping origin and nexus addresses to sync rates rach month.</span></p><br/>";
93
+
94
+ if (!empty($states)) {
95
+ $htmlString .= "<ul class='messages'>" . $this->buildStatesHtml($states) . "</ul>";
96
+ }
97
 
98
+ $htmlString .= $this->buildSyncHtml();
99
+
100
  return $htmlString;
101
  }
102
 
103
  /**
104
+ * Build HTML for backup rates disabled
105
  *
 
106
  * @return string
107
  */
108
+ private function buildDisabledHtml()
109
  {
110
+ $htmlString = "<p class='note'><span>Download zip-based rates from TaxJar as a fallback. TaxJar uses your shipping origin and nexus addresses to sync rates rach month.</span></p><br/>";
111
+
112
  return $htmlString;
113
  }
114
 
119
  * @param string $regionCode
120
  * @return string
121
  */
122
+ private function buildStatesHtml($states)
123
  {
124
+ $states[] = $this->_regionCode;
125
  $statesHtml = '';
126
+ $lastUpdate = Mage::getStoreConfig('tax/taxjar/last_update');
127
 
128
  sort($states);
129
 
130
  $taxRatesByState = $this->getNumberOfRatesLoaded($states);
131
 
132
  foreach (array_unique($states) as $state) {
133
+ if (($stateName = $this->getStateName($state)) && !empty($stateName)) {
134
  if ($taxRatesByState['rates_by_state'][$state] == 1 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
135
  $totalForState = 'Origin-based rates set';
136
  $class = 'success';
142
  $totalForState = $taxRatesByState['rates_by_state'][$state] . ' rates';
143
  }
144
 
145
+ $statesHtml .= '<li class="' . $class . '-msg"><ul><li style="line-height: 1.9em"><span style="font-size: 1.4em">' . $stateName . '</span>: ' . $totalForState . '</li></ul></li>';
146
  }
147
  }
148
 
153
  }
154
 
155
  $statesHtml .= '<p class="' . $matches . '-msg" style="background: none !important;"><small>&nbsp;&nbsp;' . $taxRatesByState['total_rates'] . ' of ' . $taxRatesByState['rates_loaded'] . ' expected rates loaded.</small></p>';
156
+ $statesHtml .= '<p class="' . $matches . '-msg" style="background: none !important;"><small>&nbsp;&nbsp;' . 'Last synced on ' . $lastUpdate . '</small></p><br/>';
157
 
158
  return $statesHtml;
159
  }
160
+
161
+ /**
162
+ * Build HTML for sync button
163
+ *
164
+ * @return string
165
+ */
166
+ private function buildSyncHtml()
167
+ {
168
+ $syncUrl = Mage::helper('adminhtml')->getUrl('adminhtml/taxjar/sync_rates');
169
+ $redirectUrl = Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit/section/tax');
170
+ $syncHtml = '<p><button type="button" class="scalable" onclick="syncBackupRates()"><span>Sync Backup Rates</span></button></p><br/>';
171
+ $syncHtml .= <<<EOT
172
+ <script>
173
+ function syncBackupRates() {
174
+ new Ajax.Request('{$syncUrl}', {
175
+ method: 'get',
176
+ onCreate: function(request) {
177
+ varienLoaderHandler.handler.onCreate({options: {loaderArea: true}});
178
+ },
179
+ onSuccess: function(data) {
180
+ varienLoaderHandler.handler.onComplete();
181
+ window.location = '{$redirectUrl}';
182
+ }
183
+ });
184
+ }
185
+ </script>
186
+ EOT;
187
+
188
+ return $syncHtml;
189
+ }
190
  }
app/code/community/Taxjar/SalesTax/Model/Import/Rate.php CHANGED
@@ -112,7 +112,7 @@ class Taxjar_SalesTax_Model_Import_Rate
112
  */
113
  private function getRegionFilter()
114
  {
115
- $states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
116
  $filter = array();
117
 
118
  foreach (array_unique($states) as $state) {
112
  */
113
  private function getRegionFilter()
114
  {
115
+ $states = unserialize(Mage::getStoreConfig('tax/taxjar/states'));
116
  $filter = array();
117
 
118
  foreach (array_unique($states) as $state) {
app/code/community/Taxjar/SalesTax/Model/Import/Rule.php CHANGED
@@ -25,28 +25,29 @@ class Taxjar_SalesTax_Model_Import_Rule
25
  * Create new tax rule based on code
26
  *
27
  * @param string $code
 
28
  * @param integer $productClass
29
  * @param integer $position
30
- * @param array $newRates
31
  * @return void
32
  */
33
- public function create($code, $productClass, $position, $newRates)
34
  {
35
  $rule = Mage::getModel('tax/calculation_rule')->load($code, 'code');
36
 
37
  $attributes = array(
38
  'code' => $code,
39
- 'tax_customer_class' => array(3),
40
- 'tax_product_class' => array($productClass),
41
- 'priority' => 1,
42
  'position' => $position,
 
43
  );
44
 
45
  if (isset($rule)) {
46
- $attributes['tax_rate'] = array_merge($rule->getRates(), $newRates);
47
  $rule->delete();
48
  } else {
49
- $attributes['tax_rate'] = $newRates;
50
  }
51
 
52
  $ruleModel = Mage::getSingleton('tax/calculation_rule');
25
  * Create new tax rule based on code
26
  *
27
  * @param string $code
28
+ * @param integer $customerClass
29
  * @param integer $productClass
30
  * @param integer $position
31
+ * @param array $rates
32
  * @return void
33
  */
34
+ public function create($code, $customerClasses, $productClasses, $position, $rates)
35
  {
36
  $rule = Mage::getModel('tax/calculation_rule')->load($code, 'code');
37
 
38
  $attributes = array(
39
  'code' => $code,
40
+ 'tax_customer_class' => $customerClasses,
41
+ 'tax_product_class' => $productClasses,
 
42
  'position' => $position,
43
+ 'priority' => 1
44
  );
45
 
46
  if (isset($rule)) {
47
+ $attributes['tax_rate'] = array_merge($rule->getRates(), $rates);
48
  $rule->delete();
49
  } else {
50
+ $attributes['tax_rate'] = $rates;
51
  }
52
 
53
  $ruleModel = Mage::getSingleton('tax/calculation_rule');
app/code/community/Taxjar/SalesTax/Model/Observer/AdminNotifications.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class TaxJar_SalesTax_Model_Observer_AdminNotifications extends Mage_AdminNotification_Model_Feed
19
+ {
20
+ public function getFeedUrl()
21
+ {
22
+ if (is_null($this->_feedUrl)) {
23
+ $this->_feedUrl = (Mage::getStoreConfigFlag(self::XML_USE_HTTPS_PATH) ? 'https://' : 'http://')
24
+ . 'www.taxjar.com/magento/feed.xml';
25
+ }
26
+ return $this->_feedUrl;
27
+ }
28
+
29
+ public function execute()
30
+ {
31
+ if (Mage::getSingleton('admin/session')->isLoggedIn()) {
32
+ $this->checkUpdate();
33
+ }
34
+ }
35
+ }
app/code/community/Taxjar/SalesTax/Model/Observer/ConfigChanged.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Taxjar_SalesTax_Model_Observer_ConfigChanged
19
+ {
20
+ public function execute($observer)
21
+ {
22
+ $this->_updateSmartcalcs();
23
+ $this->_updateBackupRates();
24
+ }
25
+
26
+ private function _updateSmartcalcs()
27
+ {
28
+ $enabled = Mage::getStoreConfig('tax/taxjar/enabled');
29
+ $prevEnabled = Mage::app()->getCache()->load('taxjar_salestax_config_enabled');
30
+
31
+ if (isset($prevEnabled)) {
32
+ if($prevEnabled != $enabled && $enabled == 1) {
33
+ Mage::dispatchEvent('taxjar_salestax_import_data');
34
+ }
35
+ }
36
+ }
37
+
38
+ private function _updateBackupRates()
39
+ {
40
+ $enabled = Mage::getStoreConfig('tax/taxjar/backup');
41
+ $prevEnabled = Mage::app()->getCache()->load('taxjar_salestax_config_backup');
42
+
43
+ if (isset($prevEnabled)) {
44
+ if($prevEnabled != $enabled) {
45
+ Mage::dispatchEvent('taxjar_salestax_import_data');
46
+ Mage::dispatchEvent('taxjar_salestax_import_rates');
47
+ }
48
+ }
49
+ }
50
+ }
app/code/community/Taxjar/SalesTax/Model/Observer/ImportData.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Taxjar_SalesTax_Model_Observer_ImportData
19
+ {
20
+ protected $_apiKey;
21
+ protected $_client;
22
+
23
+ public function execute(Varien_Event_Observer $observer)
24
+ {
25
+ $this->_apiKey = trim(Mage::getStoreConfig('tax/taxjar/apikey'));
26
+ $storeRegionCode = Mage::getModel('directory/region')->load(Mage::getStoreConfig('shipping/origin/region_id'))->getCode();
27
+
28
+ if ($this->_apiKey) {
29
+ $this->_client = Mage::getModel('taxjar/client');
30
+
31
+ if (isset($storeRegionCode)) {
32
+ $this->_setConfiguration();
33
+ } else {
34
+ Mage::throwException('Please check that you have set a Region/State in Shipping Settings.');
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Get TaxJar product categories
41
+ *
42
+ * @param void
43
+ * @return string
44
+ */
45
+ private function _getCategoryJson()
46
+ {
47
+ $categoryJson = $this->_client->getResource($this->_apiKey, 'categories');
48
+ return $categoryJson['categories'];
49
+ }
50
+
51
+ /**
52
+ * Get TaxJar user account configuration
53
+ *
54
+ * @param void
55
+ * @return string
56
+ */
57
+ private function _getConfigJson()
58
+ {
59
+ $configJson = $this->_client->getResource($this->_apiKey, 'config');
60
+ return $configJson['configuration'];
61
+ }
62
+
63
+ /**
64
+ * Set TaxJar config
65
+ *
66
+ * @param array $configJson
67
+ * @return void
68
+ */
69
+ private function _setConfiguration()
70
+ {
71
+ $configuration = Mage::getModel('taxjar/configuration');
72
+ $configJson = $this->_getConfigJson();
73
+ $categoryJson = $this->_getCategoryJson();
74
+
75
+ $configuration->setTaxBasis($configJson);
76
+ $configuration->setShippingTaxability($configJson);
77
+ $configuration->setDisplaySettings();
78
+ $configuration->setApiSettings($this->_apiKey);
79
+
80
+ Mage::getConfig()->saveConfig('tax/taxjar/categories', json_encode($categoryJson));
81
+ Mage::getConfig()->saveConfig('tax/taxjar/states', serialize(explode(',', $configJson['states'])));
82
+ Mage::getConfig()->saveConfig('tax/taxjar/freight_taxable', $configJson['freight_taxable']);
83
+ Mage::getConfig()->reinit();
84
+ }
85
+ }
app/code/community/Taxjar/SalesTax/Model/Observer/ImportRates.php CHANGED
@@ -17,63 +17,200 @@
17
 
18
  class Taxjar_SalesTax_Model_Observer_ImportRates
19
  {
 
 
 
 
 
 
 
 
 
20
  public function execute(Varien_Event_Observer $observer)
21
  {
22
- // This process can take awhile
23
- @set_time_limit(0);
24
- @ignore_user_abort(true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- $this->newRates = array();
27
- $this->freightTaxableRates = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  $rate = Mage::getModel('taxjar/import_rate');
29
- $filename = $this->getTempFileName();
30
- $rule = Mage::getModel('taxjar/import_rule');
31
- $shippingTaxable = Mage::getStoreConfig('taxjar/config/freight_taxable');
32
- $ratesJson = unserialize(file_get_contents($filename));
33
 
34
  foreach ($ratesJson['rates'] as $rateJson) {
35
  $rateIdWithShippingId = $rate->create($rateJson);
36
 
37
  if ($rateIdWithShippingId[0]) {
38
- $this->newRates[] = $rateIdWithShippingId[0];
39
  }
40
 
41
  if ($rateIdWithShippingId[1]) {
42
- $this->freightTaxableRates[] = $rateIdWithShippingId[1];
43
  }
44
  }
45
-
46
- $this->setLastUpdateDate(date('m-d-Y'));
47
- $rule->create('Retail Customer-Taxable Goods-Rate 1', 2, 1, $this->newRates);
48
-
49
- if ($shippingTaxable) {
50
- $rule->create('Retail Customer-Shipping-Rate 1', 4, 2, $this->freightTaxableRates);
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
 
53
- @unlink($filename);
54
- Mage::getSingleton('core/session')->addSuccess('TaxJar has added new rates to your database! Thanks for using TaxJar!');
55
- Mage::dispatchEvent('taxjar_salestax_import_rates_after');
 
 
56
  }
57
-
58
  /**
59
- * Set the last updated date
60
  *
61
- * @param string $date
62
  * @return void
63
  */
64
- private function setLastUpdateDate($date)
65
  {
66
- Mage::getModel('core/config')->saveConfig('taxjar/config/last_update', $date);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
  /**
70
- * Set the filename
71
  *
72
  * @param void
73
  * @return string
74
  */
75
- private function getTempFileName()
76
  {
77
  return Mage::getBaseDir('tmp') . DS . 'tj_tmp.dat';
78
  }
 
 
 
 
 
 
 
 
 
 
 
79
  }
17
 
18
  class Taxjar_SalesTax_Model_Observer_ImportRates
19
  {
20
+ protected $_apiKey;
21
+ protected $_client;
22
+ protected $_storeZip;
23
+ protected $_storeRegionCode;
24
+ protected $_customerTaxClasses;
25
+ protected $_productTaxClasses;
26
+ protected $_newRates = array();
27
+ protected $_newShippingRates = array();
28
+
29
  public function execute(Varien_Event_Observer $observer)
30
  {
31
+ $isEnabled = Mage::getStoreConfig('tax/taxjar/backup');
32
+ $this->_apiKey = trim(Mage::getStoreConfig('tax/taxjar/apikey'));
33
+
34
+ if ($isEnabled && $this->_apiKey) {
35
+ $this->_client = Mage::getModel('taxjar/client');
36
+ $this->_storeZip = trim(Mage::getStoreConfig('shipping/origin/postcode'));
37
+ $this->_storeRegionCode = Mage::getModel('directory/region')->load(Mage::getStoreConfig('shipping/origin/region_id'))->getCode();
38
+ $this->_customerTaxClasses = explode(',', Mage::getStoreConfig('tax/taxjar/customer_tax_classes'));
39
+ $this->_productTaxClasses = explode(',', Mage::getStoreConfig('tax/taxjar/product_tax_classes'));
40
+ $this->_importRates();
41
+ } else {
42
+ $states = unserialize(Mage::getStoreConfig('tax/taxjar/states'));
43
+
44
+ if (!empty($states)) {
45
+ $this->_purgeRates();
46
+ }
47
+
48
+ $this->_setLastUpdateDate(null);
49
+ Mage::getConfig()->saveConfig('taxjar/smartcalcs/backup', 0);
50
+ Mage::getSingleton('core/session')->addNotice('TaxJar has been uninstalled. All tax rates imported by TaxJar have been removed.');
51
+ }
52
+
53
+ // Clear the cache to avoid UI elements not loading
54
+ Mage::app()->getCacheInstance()->flush();
55
+ }
56
+
57
+ /**
58
+ * Import tax rates from TaxJar
59
+ *
60
+ * @param void
61
+ * @return void
62
+ */
63
+ private function _importRates()
64
+ {
65
+ $isDebugMode = Mage::getStoreConfig('tax/taxjar/debug');
66
+
67
+ if ($isDebugMode) {
68
+ Mage::getSingleton('core/session')->addNotice('Debug mode enabled. Backup tax rates have not been altered.');
69
+ return;
70
+ }
71
+
72
+ if (!empty($this->_storeZip) && preg_match("/(\d{5}-\d{4})|(\d{5})/", $this->_storeZip)) {
73
+ $ratesJson = $this->_getRatesJson();
74
+ } else {
75
+ Mage::throwException('Please check that your zip code is a valid US zip code in Shipping Settings.');
76
+ }
77
+
78
+ if (!count($this->_productTaxClasses) || !count($this->_customerTaxClasses)) {
79
+ Mage::throwException('Please select at least one product tax class and one customer tax class to import backup rates from TaxJar.');
80
+ }
81
+
82
+ // Purge existing TaxJar rates and remove from rules
83
+ $this->_purgeRates();
84
 
85
+ if (file_put_contents($this->_getTempRatesFileName(), serialize($ratesJson)) !== false) {
86
+ // This process can take awhile
87
+ @set_time_limit(0);
88
+ @ignore_user_abort(true);
89
+
90
+ $filename = $this->_getTempRatesFileName();
91
+ $ratesJson = unserialize(file_get_contents($filename));
92
+
93
+ // Create new TaxJar rates and rules
94
+ $this->_createRates($ratesJson);
95
+ $this->_createRules();
96
+ $this->_setLastUpdateDate(date('m-d-Y'));
97
+
98
+ @unlink($filename);
99
+
100
+ Mage::getSingleton('core/session')->addSuccess('TaxJar has added new rates to your database. Thanks for using TaxJar!');
101
+ Mage::dispatchEvent('taxjar_salestax_import_rates_after');
102
+ } else {
103
+ Mage::throwException('Could not write to your Magento temp directory. Please check permissions for ' . Mage::getBaseDir('tmp') . '.');
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Create new tax rates
109
+ *
110
+ * @param void
111
+ * @return void
112
+ */
113
+ private function _createRates($ratesJson)
114
+ {
115
  $rate = Mage::getModel('taxjar/import_rate');
 
 
 
 
116
 
117
  foreach ($ratesJson['rates'] as $rateJson) {
118
  $rateIdWithShippingId = $rate->create($rateJson);
119
 
120
  if ($rateIdWithShippingId[0]) {
121
+ $this->_newRates[] = $rateIdWithShippingId[0];
122
  }
123
 
124
  if ($rateIdWithShippingId[1]) {
125
+ $this->_newShippingRates[] = $rateIdWithShippingId[1];
126
  }
127
  }
128
+ }
129
+
130
+ /**
131
+ * Create or update existing tax rules with new rates
132
+ *
133
+ * @param void
134
+ * @return void
135
+ */
136
+ private function _createRules()
137
+ {
138
+ $rule = Mage::getModel('taxjar/import_rule');
139
+ $productTaxClasses = $this->_productTaxClasses;
140
+ $shippingClass = Mage::getStoreConfig('tax/classes/shipping_tax_class');
141
+ $backupShipping = in_array($shippingClass, $productTaxClasses);
142
+
143
+ if ($backupShipping) {
144
+ $productTaxClasses = array_diff($productTaxClasses, array($shippingClass));
145
  }
146
 
147
+ $rule->create('TaxJar Backup Rates', $this->_customerTaxClasses, $productTaxClasses, 1, $this->_newRates);
148
+
149
+ if ($backupShipping) {
150
+ $rule->create('TaxJar Backup Rates (Shipping)', $this->_customerTaxClasses, array($shippingClass), 2, $this->_newShippingRates);
151
+ }
152
  }
153
+
154
  /**
155
+ * Purge existing rule calculations and rates
156
  *
157
+ * @param void
158
  * @return void
159
  */
160
+ private function _purgeRates()
161
  {
162
+ $rates = Mage::getModel('taxjar/import_rate')->getExistingRates()->load();
163
+
164
+ foreach ($rates as $rate) {
165
+ $calculations = Mage::getModel('taxjar/import_rate')->getCalculationsByRateId($rate->getId())->load();
166
+
167
+ try {
168
+ foreach ($calculations as $calculation) {
169
+ $calculation->delete();
170
+ }
171
+ } catch (Exception $e) {
172
+ Mage::getSingleton('core/session')->addError('There was an error deleting from Magento model tax/calculation');
173
+ }
174
+
175
+ try {
176
+ $rate->delete();
177
+ } catch (Exception $e) {
178
+ Mage::getSingleton('core/session')->addError('There was an error deleting from Magento model tax/calculation_rate');
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Get TaxJar backup rates
185
+ *
186
+ * @param void
187
+ * @return string
188
+ */
189
+ private function _getRatesJson()
190
+ {
191
+ $ratesJson = $this->_client->getResource($this->_apiKey, 'rates');
192
+ return $ratesJson;
193
  }
194
 
195
  /**
196
+ * Get the temp rates filename
197
  *
198
  * @param void
199
  * @return string
200
  */
201
+ private function _getTempRatesFileName()
202
  {
203
  return Mage::getBaseDir('tmp') . DS . 'tj_tmp.dat';
204
  }
205
+
206
+ /**
207
+ * Set the last updated date
208
+ *
209
+ * @param string $date
210
+ * @return void
211
+ */
212
+ private function _setLastUpdateDate($date)
213
+ {
214
+ Mage::getConfig()->saveConfig('tax/taxjar/last_update', $date);
215
+ }
216
  }
app/code/community/Taxjar/SalesTax/Model/Observer/SalesQuoteCollectTotalsBefore.php CHANGED
@@ -21,7 +21,7 @@ class Taxjar_SalesTax_Model_Observer_SalesQuoteCollectTotalsBefore
21
  {
22
  $storeId = $observer->getEvent()->getQuote()->getStoreId();
23
 
24
- if (Mage::getStoreConfig('taxjar/smartcalcs/enabled', $storeId)) {
25
  Mage::getConfig()->setNode('global/sales/quote/totals/tax/class', 'Taxjar_SalesTax_Model_Sales_Total_Quote_Tax');
26
  }
27
 
21
  {
22
  $storeId = $observer->getEvent()->getQuote()->getStoreId();
23
 
24
+ if (Mage::getStoreConfig('tax/taxjar/enabled', $storeId)) {
25
  Mage::getConfig()->setNode('global/sales/quote/totals/tax/class', 'Taxjar_SalesTax_Model_Sales_Total_Quote_Tax');
26
  }
27
 
app/code/community/Taxjar/SalesTax/Model/Observer/SaveConfig.php DELETED
@@ -1,162 +0,0 @@
1
- <?php
2
- /**
3
- * Taxjar_SalesTax
4
- *
5
- * NOTICE OF LICENSE
6
- *
7
- * This source file is subject to the Open Software License (OSL 3.0)
8
- * that is bundled with this package in the file LICENSE.txt.
9
- * It is also available through the world-wide-web at this URL:
10
- * http://opensource.org/licenses/osl-3.0.php
11
- *
12
- * @category Taxjar
13
- * @package Taxjar_SalesTax
14
- * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
- */
17
-
18
- class Taxjar_SalesTax_Model_Observer_SaveConfig
19
- {
20
- protected $_version = 'v2';
21
- protected $_storeZip;
22
- protected $_regionCode;
23
-
24
- public function execute($observer)
25
- {
26
- $apiKey = Mage::getStoreConfig('taxjar/config/apikey');
27
- $apiKey = preg_replace('/\s+/', '', $apiKey);
28
-
29
- if ($apiKey) {
30
- $client = Mage::getModel('taxjar/client');
31
- $configuration = Mage::getModel('taxjar/configuration');
32
- $regionId = Mage::getStoreConfig('shipping/origin/region_id');
33
- $this->_storeZip = trim(Mage::getStoreConfig('shipping/origin/postcode'));
34
- $this->_regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
35
- $validZip = preg_match("/(\d{5}-\d{4})|(\d{5})/", $this->_storeZip);
36
- $debug = Mage::getStoreConfig('taxjar/config/debug');
37
-
38
- if (isset($this->_regionCode)) {
39
- $configJson = $client->getResource($apiKey, $this->apiUrl('config'));
40
- $configJson = $configJson['configuration'];
41
- } else {
42
- Mage::throwException('Please check that you have set a Region/State in Shipping Settings.');
43
- }
44
-
45
- if ($debug) {
46
- Mage::getSingleton('core/session')->addNotice('Debug mode enabled. Tax rates have not been altered.');
47
- return;
48
- }
49
-
50
- if ($configJson['wait_for_rates'] > 0) {
51
- $dateUpdated = Mage::getStoreConfig('taxjar/config/last_update');
52
- Mage::getSingleton('core/session')->addNotice('Your last rate update was too recent. Please wait at least 5 minutes and try again.');
53
- return;
54
- }
55
-
56
- if ($validZip === 1 && isset($this->_storeZip) && $this->_storeZip !== '') {
57
- $ratesJson = $client->getResource($apiKey, $this->apiUrl('rates'));
58
- } else {
59
- Mage::throwException('Please check that your zip code is a valid US zip code in Shipping Settings.');
60
- }
61
-
62
- $categoriesJson = $client->getResource($apiKey, $this->apiUrl('categories'));
63
-
64
- $configuration->setTaxBasis($configJson);
65
- $configuration->setShippingTaxability($configJson);
66
- $configuration->setDisplaySettings();
67
- $configuration->setApiSettings($apiKey);
68
-
69
- Mage::getModel('core/config')->saveConfig('taxjar/config/categories', json_encode($categoriesJson['categories']));
70
- Mage::getModel('core/config')->saveConfig('taxjar/config/states', serialize(explode(',', $configJson['states'])));
71
- Mage::getModel('core/config')->saveConfig('taxjar/config/freight_taxable', $configJson['freight_taxable']);
72
-
73
- $this->purgeExisting();
74
-
75
- if (false !== file_put_contents($this->getTempFileName(), serialize($ratesJson))) {
76
- Mage::dispatchEvent('taxjar_salestax_import_rates');
77
- } else {
78
- // We need to be able to store the file...
79
- Mage::throwException('Could not write to your Magento temp directory. Please check permissions for '.Mage::getBaseDir('tmp').'.');
80
- }
81
- } else {
82
- Mage::getSingleton('core/session')->addNotice('TaxJar has been uninstalled. All tax rates have been removed.');
83
- Mage::getModel('core/config')->saveConfig('taxjar/smartcalcs/enabled', 0);
84
- $this->purgeExisting();
85
- $this->setLastUpdateDate(null);
86
- }
87
-
88
- // Clearing the cache to avoid UI elements not loading
89
- Mage::app()->getCacheInstance()->flush();
90
- }
91
-
92
- /**
93
- * Build URL string
94
- *
95
- * @param string $type
96
- * @return string
97
- */
98
- private function apiUrl($type)
99
- {
100
- $apiHost = 'https://api.taxjar.com/';
101
- $prefix = $apiHost . $this->_version . '/plugins/magento/';
102
-
103
- if ($type == 'config') {
104
- return $prefix . 'configuration/' . $this->_regionCode;
105
- } elseif ($type == 'rates') {
106
- return $prefix . 'rates/' . $this->_regionCode . '/' . $this->_storeZip;
107
- } elseif ($type == 'categories') {
108
- return $apiHost . $this->_version . '/categories';
109
- }
110
- }
111
-
112
- /**
113
- * Purge existing rule calculations and rates
114
- *
115
- * @param void
116
- * @return void
117
- */
118
- private function purgeExisting()
119
- {
120
- $rates = Mage::getModel('taxjar/import_rate')->getExistingRates()->load();
121
-
122
- foreach ($rates as $rate) {
123
- $calculations = Mage::getModel('taxjar/import_rate')->getCalculationsByRateId($rate->getId())->load();
124
-
125
- try {
126
- foreach ($calculations as $calculation) {
127
- $calculation->delete();
128
- }
129
- } catch (Exception $e) {
130
- Mage::getSingleton('core/session')->addError('There was an error deleting from Magento model tax/calculation');
131
- }
132
-
133
- try {
134
- $rate->delete();
135
- } catch (Exception $e) {
136
- Mage::getSingleton('core/session')->addError('There was an error deleting from Magento model tax/calculation_rate');
137
- }
138
- }
139
- }
140
-
141
- /**
142
- * Set the last updated date
143
- *
144
- * @param string $date
145
- * @return void
146
- */
147
- private function setLastUpdateDate($date)
148
- {
149
- Mage::getModel('core/config')->saveConfig('taxjar/config/last_update', $date);
150
- }
151
-
152
- /**
153
- * Set the filename
154
- *
155
- * @param void
156
- * @return string
157
- */
158
- private function getTempFileName()
159
- {
160
- return Mage::getBaseDir('tmp') . DS . 'tj_tmp.dat';
161
- }
162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/Model/Sales/Total/Quote/Tax.php CHANGED
@@ -31,7 +31,9 @@ class Taxjar_SalesTax_Model_Sales_Total_Quote_Tax extends Mage_Tax_Model_Sales_T
31
  $this->_roundingDeltas = array();
32
  $this->_baseRoundingDeltas = array();
33
  $this->_hiddenTaxes = array();
34
- $this->_address = $address;
 
 
35
  $address->setShippingTaxAmount(0);
36
  $address->setBaseShippingTaxAmount(0);
37
 
@@ -51,7 +53,7 @@ class Taxjar_SalesTax_Model_Sales_Total_Quote_Tax extends Mage_Tax_Model_Sales_T
51
  $itemTax = $smartCalcs->getResponseLineItem($item->getProductId());
52
 
53
  if (isset($itemTax)) {
54
- $item->setTaxPercent($itemTax['combined_rate'] * 100);
55
  $item->setTaxAmount($store->convertPrice($itemTax['tax_collectable']));
56
  $item->setBaseTaxAmount($itemTax['tax_collectable']);
57
  }
31
  $this->_roundingDeltas = array();
32
  $this->_baseRoundingDeltas = array();
33
  $this->_hiddenTaxes = array();
34
+ $this->_setAddress($address);
35
+ $this->_setAmount(0);
36
+ $this->_setBaseAmount(0);
37
  $address->setShippingTaxAmount(0);
38
  $address->setBaseShippingTaxAmount(0);
39
 
53
  $itemTax = $smartCalcs->getResponseLineItem($item->getProductId());
54
 
55
  if (isset($itemTax)) {
56
+ $item->setTaxPercent($itemTax['combined_tax_rate'] * 100);
57
  $item->setTaxAmount($store->convertPrice($itemTax['tax_collectable']));
58
  $item->setBaseTaxAmount($itemTax['tax_collectable']);
59
  }
app/code/community/Taxjar/SalesTax/Model/Smartcalcs.php CHANGED
@@ -37,7 +37,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
37
  public function initTaxForOrder($address)
38
  {
39
  $storeId = $address->getQuote()->getStore()->getId();
40
- $apiKey = preg_replace('/\s+/', '', Mage::getStoreConfig('taxjar/config/apikey'));
41
 
42
  if (!$apiKey) {
43
  return;
@@ -47,7 +47,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
47
  return;
48
  }
49
 
50
- if (!$this->hasNexus($address->getRegionCode())) {
51
  return;
52
  }
53
 
@@ -74,27 +74,27 @@ class Taxjar_SalesTax_Model_Smartcalcs
74
  $order = array_merge($fromAddress, $toAddress, array(
75
  'amount' => (float) $address->getSubtotal(),
76
  'shipping' => (float) $address->getShippingAmount(),
77
- 'line_items' => $this->getLineItems($address),
78
  ));
79
 
80
- if ($this->orderChanged($order)) {
81
  $client = new Varien_Http_Client('https://api.taxjar.com/v2/taxes');
82
  $client->setHeaders('Authorization', 'Bearer ' . $apiKey);
83
  $client->setRawData(json_encode($order), 'application/json');
84
 
85
- $this->setSessionData('order', json_encode($order));
86
 
87
  try {
88
  $response = $client->request('POST');
89
  $this->_response = $response;
90
- $this->setSessionData('response', $response);
91
  } catch (Zend_Http_Client_Exception $e) {
92
  // Catch API timeouts and network issues
93
  $this->_response = null;
94
- $this->unsetSessionData('response');
95
  }
96
  } else {
97
- $sessionResponse = $this->getSessionData('response');
98
 
99
  if (isset($sessionResponse)) {
100
  $this->_response = $sessionResponse;
@@ -139,10 +139,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
139
  $matchedKey = array_search($productId, Mage::helper('taxjar')->array_column($lineItems, 'id'));
140
 
141
  if (isset($lineItems[$matchedKey])) {
142
- $matchedItem = $lineItems[$matchedKey];
143
- $matchedItem['combined_rate'] = $matchedItem['state_sales_tax_rate'] + $matchedItem['county_tax_rate'] + $matchedItem['city_tax_rate'] + $matchedItem['special_tax_rate'];
144
-
145
- return $matchedItem;
146
  }
147
  }
148
  }
@@ -154,9 +151,9 @@ class Taxjar_SalesTax_Model_Smartcalcs
154
  * @param string $regionCode
155
  * @return bool
156
  */
157
- private function hasNexus($regionCode)
158
  {
159
- $states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
160
 
161
  if (in_array($regionCode, $states)) {
162
  return true;
@@ -171,7 +168,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
171
  * @param array $address
172
  * @return array
173
  */
174
- private function getLineItems($address)
175
  {
176
  $lineItems = array();
177
  $items = $address->getAllItems();
@@ -204,9 +201,9 @@ class Taxjar_SalesTax_Model_Smartcalcs
204
  * @param array $currentOrder
205
  * @return bool
206
  */
207
- private function orderChanged($currentOrder)
208
  {
209
- $sessionOrder = json_decode($this->getSessionData('order'), true);
210
 
211
  if ($sessionOrder) {
212
  return $currentOrder != $sessionOrder;
@@ -221,7 +218,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
221
  * @param string $key
222
  * @return object
223
  */
224
- private function getSessionData($key)
225
  {
226
  return Mage::getModel('checkout/session')->getData('taxjar_salestax_' . $key);
227
  }
@@ -233,7 +230,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
233
  * @param string $val
234
  * @return object
235
  */
236
- private function setSessionData($key, $val)
237
  {
238
  return Mage::getModel('checkout/session')->setData('taxjar_salestax_' . $key, $val);
239
  }
@@ -244,7 +241,7 @@ class Taxjar_SalesTax_Model_Smartcalcs
244
  * @param string $key
245
  * @return object
246
  */
247
- private function unsetSessionData($key)
248
  {
249
  return Mage::getModel('checkout/session')->unsetData('taxjar_salestax_' . $key);
250
  }
37
  public function initTaxForOrder($address)
38
  {
39
  $storeId = $address->getQuote()->getStore()->getId();
40
+ $apiKey = preg_replace('/\s+/', '', Mage::getStoreConfig('tax/taxjar/apikey'));
41
 
42
  if (!$apiKey) {
43
  return;
47
  return;
48
  }
49
 
50
+ if (!$this->_hasNexus($address->getRegionCode())) {
51
  return;
52
  }
53
 
74
  $order = array_merge($fromAddress, $toAddress, array(
75
  'amount' => (float) $address->getSubtotal(),
76
  'shipping' => (float) $address->getShippingAmount(),
77
+ 'line_items' => $this->_getLineItems($address),
78
  ));
79
 
80
+ if ($this->_orderChanged($order)) {
81
  $client = new Varien_Http_Client('https://api.taxjar.com/v2/taxes');
82
  $client->setHeaders('Authorization', 'Bearer ' . $apiKey);
83
  $client->setRawData(json_encode($order), 'application/json');
84
 
85
+ $this->_setSessionData('order', json_encode($order));
86
 
87
  try {
88
  $response = $client->request('POST');
89
  $this->_response = $response;
90
+ $this->_setSessionData('response', $response);
91
  } catch (Zend_Http_Client_Exception $e) {
92
  // Catch API timeouts and network issues
93
  $this->_response = null;
94
+ $this->_unsetSessionData('response');
95
  }
96
  } else {
97
+ $sessionResponse = $this->_getSessionData('response');
98
 
99
  if (isset($sessionResponse)) {
100
  $this->_response = $sessionResponse;
139
  $matchedKey = array_search($productId, Mage::helper('taxjar')->array_column($lineItems, 'id'));
140
 
141
  if (isset($lineItems[$matchedKey])) {
142
+ return $lineItems[$matchedKey];
 
 
 
143
  }
144
  }
145
  }
151
  * @param string $regionCode
152
  * @return bool
153
  */
154
+ private function _hasNexus($regionCode)
155
  {
156
+ $states = unserialize(Mage::getStoreConfig('tax/taxjar/states'));
157
 
158
  if (in_array($regionCode, $states)) {
159
  return true;
168
  * @param array $address
169
  * @return array
170
  */
171
+ private function _getLineItems($address)
172
  {
173
  $lineItems = array();
174
  $items = $address->getAllItems();
201
  * @param array $currentOrder
202
  * @return bool
203
  */
204
+ private function _orderChanged($currentOrder)
205
  {
206
+ $sessionOrder = json_decode($this->_getSessionData('order'), true);
207
 
208
  if ($sessionOrder) {
209
  return $currentOrder != $sessionOrder;
218
  * @param string $key
219
  * @return object
220
  */
221
+ private function _getSessionData($key)
222
  {
223
  return Mage::getModel('checkout/session')->getData('taxjar_salestax_' . $key);
224
  }
230
  * @param string $val
231
  * @return object
232
  */
233
+ private function _setSessionData($key, $val)
234
  {
235
  return Mage::getModel('checkout/session')->setData('taxjar_salestax_' . $key, $val);
236
  }
241
  * @param string $key
242
  * @return object
243
  */
244
+ private function _unsetSessionData($key)
245
  {
246
  return Mage::getModel('checkout/session')->unsetData('taxjar_salestax_' . $key);
247
  }
app/code/community/Taxjar/SalesTax/Model/Tax/Class/Source/Customer.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Customer Tax Classes
20
+ *
21
+ * @author Taxjar (support@taxjar.com)
22
+ */
23
+ class Taxjar_SalesTax_Model_Tax_Class_Source_Customer
24
+ {
25
+ public function toOptionArray()
26
+ {
27
+ $output = array();
28
+ $customerClasses = Mage::getModel('tax/class')
29
+ ->getCollection()
30
+ ->addFieldToFilter('class_type', 'CUSTOMER')
31
+ ->load();
32
+
33
+ foreach($customerClasses as $customerClass) {
34
+ $output[] = array('value' => $customerClass->getClassId(), 'label' => $customerClass->getClassName());
35
+ }
36
+
37
+ return $output;
38
+ }
39
+ }
app/code/community/Taxjar/SalesTax/Model/Tax/Class/Source/Product.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Product Tax Classes
20
+ *
21
+ * @author Taxjar (support@taxjar.com)
22
+ */
23
+ class Taxjar_SalesTax_Model_Tax_Class_Source_Product
24
+ {
25
+ public function toOptionArray()
26
+ {
27
+ $output = array();
28
+ $productClasses = Mage::getModel('tax/class')
29
+ ->getCollection()
30
+ ->addFieldToFilter('class_type', 'PRODUCT')
31
+ ->load();
32
+
33
+ foreach($productClasses as $productClass) {
34
+ $output[] = array('value' => $productClass->getClassId(), 'label' => $productClass->getClassName());
35
+ }
36
+
37
+ return $output;
38
+ }
39
+ }
app/code/community/Taxjar/SalesTax/controllers/Adminhtml/TaxjarController.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Taxjar_SalesTax
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @category Taxjar
13
+ * @package Taxjar_SalesTax
14
+ * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * TaxJar Admin Router
20
+ * Connect and disconnect TaxJar accounts
21
+ */
22
+ class Taxjar_SalesTax_Adminhtml_TaxjarController extends Mage_Adminhtml_Controller_Action
23
+ {
24
+ /**
25
+ * Connect to TaxJar
26
+ */
27
+ public function connectAction()
28
+ {
29
+ $apiKey = (string) $this->getRequest()->getParam('api_key');
30
+ $apiEmail = (string) $this->getRequest()->getParam('api_email');
31
+
32
+ if ($apiKey && $apiEmail) {
33
+ Mage::getConfig()->saveConfig('tax/taxjar/apikey', $apiKey);
34
+ Mage::getConfig()->saveConfig('tax/taxjar/email', $apiEmail);
35
+ Mage::getConfig()->saveConfig('tax/taxjar/connected', 1);
36
+ Mage::getSingleton('core/session')->addSuccess('TaxJar account for ' . $apiEmail . ' is now connected.');
37
+ } else {
38
+ Mage::getSingleton('core/session')->addError('Could not connect your TaxJar account. Please make sure you have a valid API token and try again.');
39
+ }
40
+
41
+ $this->_redirect('adminhtml/system_config/edit/section/tax');
42
+ }
43
+
44
+ /**
45
+ * Disconnect from TaxJar
46
+ */
47
+ public function disconnectAction()
48
+ {
49
+ Mage::getConfig()->saveConfig('tax/taxjar/apikey', '');
50
+ Mage::getConfig()->saveConfig('tax/taxjar/email', '');
51
+ Mage::getConfig()->saveConfig('tax/taxjar/connected', 0);
52
+ Mage::getConfig()->saveConfig('tax/taxjar/enabled', 0);
53
+ Mage::getConfig()->saveConfig('tax/taxjar/backup', 0);
54
+ Mage::getConfig()->reinit();
55
+
56
+ Mage::getSingleton('core/session')->addSuccess('Your TaxJar account has been disconnected.');
57
+ Mage::dispatchEvent('taxjar_salestax_import_rates');
58
+
59
+ $this->_redirect('adminhtml/system_config/edit/section/tax');
60
+ }
61
+
62
+ /**
63
+ * Sync backup rates from TaxJar
64
+ */
65
+ public function sync_ratesAction()
66
+ {
67
+ Mage::dispatchEvent('taxjar_salestax_import_data');
68
+ Mage::dispatchEvent('taxjar_salestax_import_rates');
69
+ }
70
+
71
+ protected function _isAllowed()
72
+ {
73
+ return Mage::getSingleton('admin/session')->isAllowed('system/config/tax');
74
+ }
75
+ }
app/code/community/Taxjar/SalesTax/etc/adminhtml.xml DELETED
@@ -1,40 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Taxjar_SalesTax
5
- *
6
- * NOTICE OF LICENSE
7
- *
8
- * This source file is subject to the Open Software License (OSL 3.0)
9
- * that is bundled with this package in the file LICENSE.txt.
10
- * It is also available through the world-wide-web at this URL:
11
- * http://opensource.org/licenses/osl-3.0.php
12
- *
13
- * @category Taxjar
14
- * @package Taxjar_SalesTax
15
- * @copyright Copyright (c) 2016 TaxJar. TaxJar is a trademark of TPS Unlimited, Inc. (http://www.taxjar.com)
16
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
- */
18
- -->
19
- <config>
20
- <!-- repeated in config.xml for compatibility -->
21
- <acl>
22
- <resources>
23
- <admin>
24
- <children>
25
- <system>
26
- <children>
27
- <config>
28
- <children>
29
- <taxjar>
30
- <title>TaxJar Sales Tax Automation</title>
31
- </taxjar>
32
- </children>
33
- </config>
34
- </children>
35
- </system>
36
- </children>
37
- </admin>
38
- </resources>
39
- </acl>
40
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/etc/config.xml CHANGED
@@ -57,15 +57,24 @@
57
  </salestax_setup>
58
  </resources>
59
  <events>
60
- <admin_system_config_changed_section_taxjar>
61
  <observers>
62
  <taxjar>
63
  <type>singleton</type>
64
- <class>taxjar/observer_saveConfig</class>
65
  <method>execute</method>
66
  </taxjar>
67
  </observers>
68
- </admin_system_config_changed_section_taxjar>
 
 
 
 
 
 
 
 
 
69
  <taxjar_salestax_import_rates>
70
  <observers>
71
  <taxjar>
@@ -84,40 +93,28 @@
84
  </taxjar>
85
  </observers>
86
  </sales_quote_collect_totals_before>
 
 
 
 
 
 
 
 
 
87
  </events>
88
  </global>
89
- <frontend>
90
  <routers>
91
- <taxjar>
92
- <use>standard</use>
93
  <args>
94
- <module>Taxjar_SalesTax</module>
95
- <frontName>taxjar</frontName>
 
96
  </args>
97
- </taxjar>
98
  </routers>
99
- </frontend>
100
- <adminhtml>
101
- <acl>
102
- <resources>
103
- <admin>
104
- <children>
105
- <system>
106
- <children>
107
- <config>
108
- <children>
109
- <taxjar>
110
- <title>TaxJar Sales Tax Automation</title>
111
- </taxjar>
112
- </children>
113
- </config>
114
- </children>
115
- </system>
116
- </children>
117
- </admin>
118
- </resources>
119
- </acl>
120
- </adminhtml>
121
  <crontab>
122
  <jobs>
123
  <taxjar>
@@ -125,9 +122,17 @@
125
  <cron_expr>0 8 1 * *</cron_expr>
126
  </schedule>
127
  <run>
128
- <model>taxjar/observer_saveConfig::execute</model>
129
  </run>
130
  </taxjar>
131
  </jobs>
132
  </crontab>
 
 
 
 
 
 
 
 
133
  </config>
57
  </salestax_setup>
58
  </resources>
59
  <events>
60
+ <admin_system_config_changed_section_tax>
61
  <observers>
62
  <taxjar>
63
  <type>singleton</type>
64
+ <class>taxjar/observer_configChanged</class>
65
  <method>execute</method>
66
  </taxjar>
67
  </observers>
68
+ </admin_system_config_changed_section_tax>
69
+ <taxjar_salestax_import_data>
70
+ <observers>
71
+ <taxjar>
72
+ <type>singleton</type>
73
+ <class>taxjar/observer_importData</class>
74
+ <method>execute</method>
75
+ </taxjar>
76
+ </observers>
77
+ </taxjar_salestax_import_data>
78
  <taxjar_salestax_import_rates>
79
  <observers>
80
  <taxjar>
93
  </taxjar>
94
  </observers>
95
  </sales_quote_collect_totals_before>
96
+ <controller_action_predispatch>
97
+ <observers>
98
+ <taxjar>
99
+ <type>singleton</type>
100
+ <class>taxjar/observer_adminNotifications</class>
101
+ <method>execute</method>
102
+ </taxjar>
103
+ </observers>
104
+ </controller_action_predispatch>
105
  </events>
106
  </global>
107
+ <admin>
108
  <routers>
109
+ <adminhtml>
 
110
  <args>
111
+ <modules>
112
+ <Taxjar_SalesTax after="Mage_Adminhtml">Taxjar_SalesTax_Adminhtml</Taxjar_SalesTax>
113
+ </modules>
114
  </args>
115
+ </adminhtml>
116
  </routers>
117
+ </admin>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  <crontab>
119
  <jobs>
120
  <taxjar>
122
  <cron_expr>0 8 1 * *</cron_expr>
123
  </schedule>
124
  <run>
125
+ <model>taxjar/observer_importRates::execute</model>
126
  </run>
127
  </taxjar>
128
  </jobs>
129
  </crontab>
130
+ <default>
131
+ <tax>
132
+ <taxjar>
133
+ <product_tax_classes>2</product_tax_classes>
134
+ <customer_tax_classes>3</customer_tax_classes>
135
+ </taxjar>
136
+ </tax>
137
+ </default>
138
  </config>
app/code/community/Taxjar/SalesTax/etc/system.xml CHANGED
@@ -17,42 +17,68 @@
17
  */
18
  -->
19
  <config>
20
- <tabs>
21
- <taxjar translate="label" module="taxjar">
22
- <label>TaxJar</label>
23
- <sort_order>0</sort_order>
24
- </taxjar>
25
- </tabs>
26
  <sections>
27
- <taxjar translate="label" module="taxjar">
28
- <label>Sales Tax Automation</label>
29
- <tab>taxjar</tab>
30
- <frontend_type>text</frontend_type>
31
- <sort_order>1000</sort_order>
32
- <show_in_default>1</show_in_default>
33
- <show_in_website>1</show_in_website>
34
- <show_in_store>1</show_in_store>
35
  <groups>
36
- <config translate="label">
37
- <label>TaxJar Options</label>
38
- <frontend_type>text</frontend_type>
39
- <sort_order>1</sort_order>
40
  <show_in_default>1</show_in_default>
41
  <show_in_website>1</show_in_website>
42
  <show_in_store>1</show_in_store>
43
  <expanded>1</expanded>
44
  <fields>
45
- <apikey translate="label">
46
- <label>API Token</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  <comment>
48
  <model>taxjar/import_comment</model>
49
  </comment>
50
- <frontend_type>text</frontend_type>
 
 
51
  <sort_order>1</sort_order>
52
  <show_in_default>1</show_in_default>
53
  <show_in_website>1</show_in_website>
54
  <show_in_store>1</show_in_store>
55
- </apikey>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  <debug translate="label">
57
  <label>Debug Mode</label>
58
  <comment>
@@ -64,31 +90,24 @@
64
  <show_in_default>1</show_in_default>
65
  <show_in_website>1</show_in_website>
66
  <show_in_store>1</show_in_store>
 
67
  </debug>
68
- </fields>
69
- </config>
70
- <smartcalcs translate="label">
71
- <label>SmartCalcs Integration</label>
72
- <frontend_type>text</frontend_type>
73
- <sort_order>2</sort_order>
74
- <show_in_default>1</show_in_default>
75
- <show_in_website>1</show_in_website>
76
- <show_in_store>1</show_in_store>
77
- <expanded>1</expanded>
78
- <fields>
79
- <enabled translate="label">
80
- <label>Enabled</label>
81
- <comment>Optional sales tax calculations at checkout for improved accuracy and product exemptions. Zip-based rates will be used as a fallback. When enabled, your store will make more API calls.</comment>
82
- <source_model>adminhtml/system_config_source_yesno</source_model>
83
- <frontend_type>select</frontend_type>
84
- <sort_order>1</sort_order>
85
  <show_in_default>1</show_in_default>
86
  <show_in_website>1</show_in_website>
87
- <show_in_store>1</show_in_store>
88
- </enabled>
 
 
 
 
89
  </fields>
90
- </smartcalcs>
91
  </groups>
92
- </taxjar>
93
  </sections>
94
  </config>
17
  */
18
  -->
19
  <config>
 
 
 
 
 
 
20
  <sections>
21
+ <tax>
 
 
 
 
 
 
 
22
  <groups>
23
+ <taxjar translate="label" module="taxjar">
24
+ <label>SmartCalcs by TaxJar</label>
25
+ <sort_order>0</sort_order>
 
26
  <show_in_default>1</show_in_default>
27
  <show_in_website>1</show_in_website>
28
  <show_in_store>1</show_in_store>
29
  <expanded>1</expanded>
30
  <fields>
31
+ <enabled translate="label">
32
+ <label>Enabled for Checkout</label>
33
+ <comment>
34
+ <model>taxjar/comment</model>
35
+ </comment>
36
+ <source_model>adminhtml/system_config_source_yesno</source_model>
37
+ <frontend_model>taxjar/adminhtml_enabled</frontend_model>
38
+ <frontend_type>select</frontend_type>
39
+ <sort_order>0</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ </enabled>
44
+ <backup translate="label">
45
+ <label>Backup Rates</label>
46
  <comment>
47
  <model>taxjar/import_comment</model>
48
  </comment>
49
+ <source_model>adminhtml/system_config_source_yesno</source_model>
50
+ <frontend_model>taxjar/adminhtml_backup</frontend_model>
51
+ <frontend_type>select</frontend_type>
52
  <sort_order>1</sort_order>
53
  <show_in_default>1</show_in_default>
54
  <show_in_website>1</show_in_website>
55
  <show_in_store>1</show_in_store>
56
+ <depends><connected>1</connected></depends>
57
+ </backup>
58
+ <product_tax_classes>
59
+ <label>Backup Product Tax Classes</label>
60
+ <comment>When creating or updating backup tax rules, TaxJar will use these product tax classes.</comment>
61
+ <source_model>taxjar/tax_class_source_product</source_model>
62
+ <frontend_model>taxjar/adminhtml_multiselect</frontend_model>
63
+ <frontend_type>multiselect</frontend_type>
64
+ <sort_order>2</sort_order>
65
+ <show_in_default>1</show_in_default>
66
+ <show_in_website>1</show_in_website>
67
+ <show_in_store>1</show_in_store>
68
+ <depends><connected>1</connected></depends>
69
+ </product_tax_classes>
70
+ <customer_tax_classes>
71
+ <label>Backup Customer Tax Classes</label>
72
+ <comment>When creating or updating backup tax rules, TaxJar will use these customer tax classes.</comment>
73
+ <source_model>taxjar/tax_class_source_customer</source_model>
74
+ <frontend_model>taxjar/adminhtml_multiselect</frontend_model>
75
+ <frontend_type>multiselect</frontend_type>
76
+ <sort_order>3</sort_order>
77
+ <show_in_default>1</show_in_default>
78
+ <show_in_website>1</show_in_website>
79
+ <show_in_store>1</show_in_store>
80
+ <depends><connected>1</connected></depends>
81
+ </customer_tax_classes>
82
  <debug translate="label">
83
  <label>Debug Mode</label>
84
  <comment>
90
  <show_in_default>1</show_in_default>
91
  <show_in_website>1</show_in_website>
92
  <show_in_store>1</show_in_store>
93
+ <depends><connected>1</connected></depends>
94
  </debug>
95
+ <apikey translate="label">
96
+ <label>API Token</label>
97
+ <comment>Your TaxJar API token for sales tax calculations and backup rates.</comment>
98
+ <frontend_type>text</frontend_type>
99
+ <sort_order>11</sort_order>
 
 
 
 
 
 
 
 
 
 
 
 
100
  <show_in_default>1</show_in_default>
101
  <show_in_website>1</show_in_website>
102
+ <show_in_store>11</show_in_store>
103
+ <depends>
104
+ <connected>1</connected>
105
+ <debug>1</debug>
106
+ </depends>
107
+ </apikey>
108
  </fields>
109
+ </taxjar>
110
  </groups>
111
+ </tax>
112
  </sections>
113
  </config>
package.xml CHANGED
@@ -1,20 +1,23 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Taxjar_Salestaxautomation</name>
4
- <version>1.6.1</version>
5
  <stability>stable</stability>
6
  <license>MIT</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Easily collect sales tax without altering your Magento store&#x2019;s checkout experience or performance.</summary>
10
  <description>TaxJar for Magento allows you to quickly calculate sales tax at checkout using our SmartCalcs API and zip-based rates as a backup.</description>
11
- <notes>* Hotfix SmartCalcs integration model casing.&#xD;
12
- * Trim shipping origin postal code before making API requests.&#xD;
13
- * Minor code cleanup.</notes>
 
 
 
14
  <authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
15
- <date>2016-04-12</date>
16
- <time>21:37:56</time>
17
- <contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Block"><dir name="Adminhtml"><dir name="Tax"><dir name="Class"><dir name="Edit"><file name="Form.php" hash="1e3f944f2c50c5ae9f215577c7f8eeba"/></dir><file name="Grid.php" hash="abee26b12865446aa06d30763c5c5d24"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="d19f2af9ff020d2e0d31369cf43eac50"/></dir><dir name="Model"><file name="Calculation.php" hash="89c05ee42f8316563ea610f11b53a26d"/><file name="Categories.php" hash="ec9523c7d5bdae21b48034434ea43797"/><file name="Client.php" hash="31cc9e1fdada520ee102b4bc2f443164"/><file name="Configuration.php" hash="831e93bcfdf2d10a55038f95dfcb00fb"/><file name="Debug.php" hash="1ae53e80ca55813260e24df9cb354a07"/><dir name="Import"><file name="Comment.php" hash="dff4f3c810e4c1e6e3ca7d85563636e9"/><file name="Rate.php" hash="1fcc66b5493c9963564fdd372e49a360"/><file name="Rule.php" hash="80f2a71950f0bf535608e25d99fbb236"/></dir><dir name="Observer"><file name="ImportRates.php" hash="6a9faaaa2231b04e430d3f4981d9ccdc"/><file name="SalesQuoteCollectTotalsBefore.php" hash="989a2823f1718385bec7143cc9a55ead"/><file name="SaveConfig.php" hash="26d8a559937081fd9d6c5620ea707ac2"/></dir><dir name="Sales"><dir name="Total"><dir name="Quote"><file name="Tax.php" hash="4fa3951e4de0174ea0fc3da3de64e741"/></dir></dir></dir><file name="Smartcalcs.php" hash="0dcb488208f445576935b3b22a280746"/></dir><dir name="etc"><file name="adminhtml.xml" hash="440972a63d83b2475f187f38172f54ca"/><file name="config.xml" hash="689e028a1427931d8e04c9aecc32d465"/><file name="system.xml" hash="2e4defe58b81bfa07b5c8a91fe0a7963"/></dir><dir name="sql"><dir name="salestax_setup"><file name="install-1.6.0.php" hash="9d400004ec642113a8cc907fe5d33960"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Taxjar_SalesTax.xml" hash="552596be5ec12440753bf69ed6005747"/></dir></target></contents>
18
  <compatible/>
19
  <dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies>
20
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Taxjar_Salestaxautomation</name>
4
+ <version>2.0.0</version>
5
  <stability>stable</stability>
6
  <license>MIT</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Easily collect sales tax without altering your Magento store&#x2019;s checkout experience or performance.</summary>
10
  <description>TaxJar for Magento allows you to quickly calculate sales tax at checkout using our SmartCalcs API and zip-based rates as a backup.</description>
11
+ <notes>* Moved TaxJar configuration to System &gt; Configuration &gt; Tax. This is a breaking change with new configuration fields. If upgrading from a previous version, you'll need to re-connect to TaxJar and re-enable your settings.&#xD;
12
+ * Streamlined configuration with focus on SmartCalcs for upcoming free calculations and zip-based rates as a fallback.&#xD;
13
+ * New "Connect to TaxJar" button for faster onboarding.&#xD;
14
+ * New select fields for assigning backup tax rules to custom product and customer tax classes.&#xD;
15
+ * New AJAX sync button for manually refreshing backup rates from TaxJar.&#xD;
16
+ * Admin notifications tied to our RSS feed for extension updates and news.</notes>
17
  <authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
18
+ <date>2016-05-22</date>
19
+ <time>20:31:31</time>
20
+ <contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Block"><dir name="Adminhtml"><file name="Backup.php" hash="99896b0425b06dbf6ccaa8fbdce96995"/><file name="Enabled.php" hash="aea3371b026dcb77339f67ffbe12c37a"/><file name="Multiselect.php" hash="a4f5750cb3f5139dea6f0a781a523ba2"/><dir name="Tax"><dir name="Class"><dir name="Edit"><file name="Form.php" hash="655e276e44ad233b055eee8965391088"/></dir><file name="Grid.php" hash="a52bbe41bc9255bf54720ab4142bfaa7"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="d19f2af9ff020d2e0d31369cf43eac50"/></dir><dir name="Model"><file name="Calculation.php" hash="89c05ee42f8316563ea610f11b53a26d"/><file name="Categories.php" hash="934947240f1a1c7ae7b9ba323aacabd6"/><file name="Client.php" hash="49a5d39125d60c0d0a6583e726b813bf"/><file name="Comment.php" hash="86ac0f475f9430e32dd80b52cd82d4be"/><file name="Configuration.php" hash="c59b69931392eb896e4d0c46b7d2e38b"/><file name="Debug.php" hash="d170affaf34de16eee0d840e76485e6c"/><dir name="Import"><file name="Comment.php" hash="31294b614dce9d399e18788d5e99e7f3"/><file name="Rate.php" hash="00ad69812c8d2f31915cac959483c1eb"/><file name="Rule.php" hash="597ff0e337b4e04e43660b4d4f05d0e0"/></dir><dir name="Observer"><file name="AdminNotifications.php" hash="462c1210a649d81a2a49db7c03d7f293"/><file name="ConfigChanged.php" hash="45bc280865ee95743dc8c4b188607a62"/><file name="ImportData.php" hash="ca21015ca41f8352fe015b4a82fc428d"/><file name="ImportRates.php" hash="30e9209294e44fe84eede56df8dccd00"/><file name="SalesQuoteCollectTotalsBefore.php" hash="37c28ddaf8a27d548bf463fff1aa7da1"/></dir><dir name="Sales"><dir name="Total"><dir name="Quote"><file name="Tax.php" hash="3763db17501ccd79e8b81f379f0b5607"/></dir></dir></dir><file name="Smartcalcs.php" hash="59c95419e35cce5fa03f46d1917de097"/><dir name="Tax"><dir name="Class"><dir name="Source"><file name="Customer.php" hash="9f2941032dc80219f9def35de5c5afc8"/><file name="Product.php" hash="3e0d0826d3d43e8a7c63f2e2e44b810a"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="TaxjarController.php" hash="40c4c3865ffd7ba0c7bf403965994d46"/></dir></dir><dir name="etc"><file name="config.xml" hash="230b5523931e0d39b8ec3d42c9cf632f"/><file name="system.xml" hash="7307753f550f490112ded20317c1a07d"/></dir><dir name="sql"><dir name="salestax_setup"><file name="install-1.6.0.php" hash="9d400004ec642113a8cc907fe5d33960"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Taxjar_SalesTax.xml" hash="552596be5ec12440753bf69ed6005747"/></dir></target></contents>
21
  <compatible/>
22
  <dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies>
23
  </package>