Taxjar_Salestaxautomation - Version 1.6.0

Version Notes

* SmartCalcs integration at checkout for live sales tax calculations and higher accuracy.
* Product tax code support for exemptions.
* Fix rule and rate purging when uninstalling extension.

Download this release

Release Info

Developer TaxJar
Extension Taxjar_Salestaxautomation
Version 1.6.0
Comparing to
See all releases


Code changes from version 1.5.1 to 1.6.0

Files changed (26) hide show
  1. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Edit/Form.php +40 -0
  2. app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Grid.php +38 -0
  3. app/code/community/Taxjar/SalesTax/Helper/Data.php +144 -2
  4. app/code/community/Taxjar/SalesTax/Model/Calculation.php +45 -29
  5. app/code/community/Taxjar/SalesTax/Model/Categories.php +51 -0
  6. app/code/community/Taxjar/SalesTax/Model/Client.php +51 -34
  7. app/code/community/Taxjar/SalesTax/Model/Comment.php +0 -134
  8. app/code/community/Taxjar/SalesTax/Model/Configuration.php +319 -303
  9. app/code/community/Taxjar/SalesTax/Model/Debug.php +52 -35
  10. app/code/community/Taxjar/SalesTax/Model/Import/Comment.php +154 -0
  11. app/code/community/Taxjar/SalesTax/Model/Import/Rate.php +125 -0
  12. app/code/community/Taxjar/SalesTax/Model/Import/Rule.php +58 -0
  13. app/code/community/Taxjar/SalesTax/Model/Observer.php +0 -189
  14. app/code/community/Taxjar/SalesTax/Model/Observer/ImportRates.php +79 -0
  15. app/code/community/Taxjar/SalesTax/Model/Observer/SalesQuoteCollectTotalsBefore.php +30 -0
  16. app/code/community/Taxjar/SalesTax/Model/Observer/SaveConfig.php +162 -0
  17. app/code/community/Taxjar/SalesTax/Model/Rate.php +0 -97
  18. app/code/community/Taxjar/SalesTax/Model/Rule.php +0 -40
  19. app/code/community/Taxjar/SalesTax/Model/Sales/Total/Quote/Tax.php +133 -0
  20. app/code/community/Taxjar/SalesTax/Model/SmartCalcs.php +251 -0
  21. app/code/community/Taxjar/SalesTax/etc/adminhtml.xml +38 -21
  22. app/code/community/Taxjar/SalesTax/etc/config.xml +127 -87
  23. app/code/community/Taxjar/SalesTax/etc/system.xml +91 -53
  24. app/code/community/Taxjar/SalesTax/sql/salestax_setup/install-1.6.0.php +35 -0
  25. app/etc/modules/Taxjar_SalesTax.xml +19 -2
  26. package.xml +8 -6
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Edit/Form.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
+ class Taxjar_SalesTax_Block_Adminhtml_Tax_Class_Edit_Form extends Mage_Adminhtml_Block_Tax_Class_Edit_Form
19
+ {
20
+ protected function _prepareForm()
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',
31
+ 'label' => Mage::helper('taxjar')->__('TaxJar Category'),
32
+ 'value' => $currentClass->getTjSalestaxCode(),
33
+ 'values' => Mage::getModel('taxjar/categories')->toOptionArray()
34
+ )
35
+ );
36
+ }
37
+
38
+ return $this;
39
+ }
40
+ }
app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Grid.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Block_Adminhtml_Tax_Class_Grid extends Mage_Adminhtml_Block_Tax_Class_Grid
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'),
28
+ 'align' => 'left',
29
+ 'index' => 'tj_salestax_code',
30
+ 'width' => '150px',
31
+ 'type' => 'text'
32
+ )
33
+ );
34
+ }
35
+
36
+ return $this;
37
+ }
38
+ }
app/code/community/Taxjar/SalesTax/Helper/Data.php CHANGED
@@ -1,10 +1,152 @@
1
  <?php
2
  /**
3
- * TaxJar helper
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  *
5
  * @author Taxjar (support@taxjar.com)
6
  */
7
  class Taxjar_SalesTax_Helper_Data extends Mage_Core_Helper_Abstract
8
  {
9
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
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 Data Helper
20
  *
21
  * @author Taxjar (support@taxjar.com)
22
  */
23
  class Taxjar_SalesTax_Helper_Data extends Mage_Core_Helper_Abstract
24
  {
25
+ /**
26
+ * Return the values from a single column in the input array
27
+ * Backport for PHP < 5.5 https://github.com/ramsey/array_column
28
+ *
29
+ * @param array $input
30
+ * @param string $columnKey
31
+ * @param string $indexKey
32
+ * @return array
33
+ */
34
+ public function array_column($input = null, $columnKey = null, $indexKey = null)
35
+ {
36
+ if (function_exists('array_column')) {
37
+ return array_column($input, $columnKey, $indexKey);
38
+ }
39
+
40
+ // Using func_get_args() in order to check for proper number of
41
+ // parameters and trigger errors exactly as the built-in array_column()
42
+ // does in PHP 5.5.
43
+ $argc = func_num_args();
44
+ $params = func_get_args();
45
+ if ($argc < 2) {
46
+ trigger_error("array_column() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
47
+ return null;
48
+ }
49
+ if (!is_array($params[0])) {
50
+ trigger_error(
51
+ 'array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given',
52
+ E_USER_WARNING
53
+ );
54
+ return null;
55
+ }
56
+ if (!is_int($params[1])
57
+ && !is_float($params[1])
58
+ && !is_string($params[1])
59
+ && $params[1] !== null
60
+ && !(is_object($params[1]) && method_exists($params[1], '__toString'))
61
+ ) {
62
+ trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
63
+ return false;
64
+ }
65
+ if (isset($params[2])
66
+ && !is_int($params[2])
67
+ && !is_float($params[2])
68
+ && !is_string($params[2])
69
+ && !(is_object($params[2]) && method_exists($params[2], '__toString'))
70
+ ) {
71
+ trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
72
+ return false;
73
+ }
74
+ $paramsInput = $params[0];
75
+ $paramsColumnKey = ($params[1] !== null) ? (string) $params[1] : null;
76
+ $paramsIndexKey = null;
77
+ if (isset($params[2])) {
78
+ if (is_float($params[2]) || is_int($params[2])) {
79
+ $paramsIndexKey = (int) $params[2];
80
+ } else {
81
+ $paramsIndexKey = (string) $params[2];
82
+ }
83
+ }
84
+ $resultArray = array();
85
+ foreach ($paramsInput as $row) {
86
+ $key = $value = null;
87
+ $keySet = $valueSet = false;
88
+ if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
89
+ $keySet = true;
90
+ $key = (string) $row[$paramsIndexKey];
91
+ }
92
+ if ($paramsColumnKey === null) {
93
+ $valueSet = true;
94
+ $value = $row;
95
+ } elseif (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
96
+ $valueSet = true;
97
+ $value = $row[$paramsColumnKey];
98
+ }
99
+ if ($valueSet) {
100
+ if ($keySet) {
101
+ $resultArray[$key] = $value;
102
+ } else {
103
+ $resultArray[] = $value;
104
+ }
105
+ }
106
+ }
107
+ return $resultArray;
108
+ }
109
+
110
+ /**
111
+ * Sort a multidimensional array by key
112
+ *
113
+ * @param array $array
114
+ * @param string $on
115
+ * @param const $order
116
+ * @return array
117
+ */
118
+ public function array_sort($array, $on, $order = SORT_ASC)
119
+ {
120
+ $new_array = array();
121
+ $sortable_array = array();
122
+
123
+ if (count($array) > 0) {
124
+ foreach ($array as $k => $v) {
125
+ if (is_array($v)) {
126
+ foreach ($v as $k2 => $v2) {
127
+ if ($k2 == $on) {
128
+ $sortable_array[$k] = $v2;
129
+ }
130
+ }
131
+ } else {
132
+ $sortable_array[$k] = $v;
133
+ }
134
+ }
135
+
136
+ switch ($order) {
137
+ case SORT_ASC:
138
+ asort($sortable_array);
139
+ break;
140
+ case SORT_DESC:
141
+ arsort($sortable_array);
142
+ break;
143
+ }
144
+
145
+ foreach ($sortable_array as $k => $v) {
146
+ $new_array[$k] = $array[$k];
147
+ }
148
+ }
149
+
150
+ return $new_array;
151
+ }
152
  }
app/code/community/Taxjar/SalesTax/Model/Calculation.php CHANGED
@@ -1,37 +1,53 @@
1
  <?php
2
  /**
3
- * TaxJar Zip+4 Rate Calculation Support for US
 
 
 
 
 
 
 
4
  *
5
- * @author Taxjar (support@taxjar.com)
 
 
 
 
 
 
 
 
6
  */
7
  class Taxjar_SalesTax_Model_Calculation extends Mage_Tax_Model_Resource_Calculation
8
  {
9
- /**
10
- * Returns tax rates for request and when US only uses five digit zip code lookups
11
- *
12
- * @param Varien_Object $request
13
- * @return array
14
- */
15
- protected function _getRates($request)
16
- {
17
- // Grab each current value
18
- $countryId = $request->getCountryId();
19
- $currentPostcode = $request->getPostcode();
20
- if ($countryId == 'US') {
21
- // Trim whitespace
22
- $newPostcode = preg_replace('/\s+/', '', $request->getPostcode());
23
- // Snatch only the first five characters
24
- $newPostcode = substr($newPostcode, 0, 5);
25
- // Replace the request's zip code with one that now has 5 digits
26
- $request->setPostcode($newPostcode);
27
- // Find rates by the new 5-digit zip
28
- $rates = parent::_getRates($request);
29
- // Reset the request's postcode to what it was
30
- $request->setPostcode($currentPostcode);
31
- } else {
32
- // Non-US should just work normally
33
- $rates = parent::_getRates($request);
 
 
 
34
  }
35
- return $rates;
36
- }
37
  }
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
+ * Calculation Model
20
+ * TaxJar Zip+4 Rate Calculation Support for US
21
  */
22
  class Taxjar_SalesTax_Model_Calculation extends Mage_Tax_Model_Resource_Calculation
23
  {
24
+ /**
25
+ * Returns tax rates for request and when US only uses five digit zip code lookups
26
+ *
27
+ * @param Varien_Object $request
28
+ * @return array
29
+ */
30
+ protected function _getRates($request)
31
+ {
32
+ $countryId = $request->getCountryId();
33
+ $currentPostcode = $request->getPostcode();
34
+
35
+ if ($countryId == 'US') {
36
+ // Trim whitespace
37
+ $newPostcode = preg_replace('/\s+/', '', $request->getPostcode());
38
+ // Snatch only the first five characters
39
+ $newPostcode = substr($newPostcode, 0, 5);
40
+ // Replace the request's zip code with one that now has 5 digits
41
+ $request->setPostcode($newPostcode);
42
+ // Find rates by the new 5-digit zip
43
+ $rates = parent::_getRates($request);
44
+ // Reset the request's postcode to what it was
45
+ $request->setPostcode($currentPostcode);
46
+ } else {
47
+ // Non-US should just work normally
48
+ $rates = parent::_getRates($request);
49
+ }
50
+
51
+ return $rates;
52
  }
 
 
53
  }
app/code/community/Taxjar/SalesTax/Model/Categories.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 Categories Model
20
+ * Populates tax category dropdown under
21
+ */
22
+ class Taxjar_SalesTax_Model_Categories
23
+ {
24
+ /**
25
+ * Populate dropdown options
26
+ *
27
+ * @param void
28
+ * @return array
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(
36
+ array(
37
+ 'label' => 'None',
38
+ 'value' => ''
39
+ )
40
+ );
41
+
42
+ foreach($categories as $category) {
43
+ $output[] = array(
44
+ 'label' => $category['name'] . ' (' . $category['product_tax_code'] . ')',
45
+ 'value' => $category['product_tax_code']
46
+ );
47
+ }
48
+
49
+ return $output;
50
+ }
51
+ }
app/code/community/Taxjar/SalesTax/Model/Client.php CHANGED
@@ -1,4 +1,20 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
  * TaxJar HTTP Client
4
  *
@@ -6,41 +22,42 @@
6
  */
7
  class Taxjar_SalesTax_Model_Client
8
  {
9
- /**
10
- * Connect to the API
11
- *
12
- * @param $string, $string
13
- * @return JSON $string
14
- */
15
- public function getResource($apiKey, $url)
16
- {
17
- $response = $this->getClient($apiKey, $url)->request();
18
-
19
- if ($response->isSuccessful()) {
20
- $json = $response->getBody();
21
 
22
- return json_decode($json, true);
23
- } else {
24
- if ($response->getStatus() == 403) {
25
- Mage::throwException('Your last rate update was too recent. Please wait at least 5 minutes and try again.');
26
- } else {
27
- Mage::throwException('Could not connect to TaxJar.');
28
- }
29
- }
30
- }
 
 
31
 
32
- /**
33
- * Client GET call
34
- *
35
- * @param $string, $string
36
- * @return Varien_Http_Client $response
37
- */
38
- private function getClient($apiKey, $url)
39
- {
40
- $client = new Varien_Http_Client($url);
41
- $client->setMethod(Varien_Http_Client::GET);
42
- $client->setHeaders('Authorization', 'Token token="' . $apiKey . '"');
 
43
 
44
- return $client;
45
- }
46
  }
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 HTTP Client
20
  *
22
  */
23
  class Taxjar_SalesTax_Model_Client
24
  {
25
+ /**
26
+ * Connect to the API
27
+ *
28
+ * @param string $apiKey
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();
38
+ return json_decode($json, true);
39
+ } else {
40
+ if ($response->getStatus() == 403) {
41
+ Mage::throwException('Your last rate update was too recent. Please wait at least 5 minutes and try again.');
42
+ } else {
43
+ Mage::throwException('Could not connect to TaxJar.');
44
+ }
45
+ }
46
+ }
47
 
48
+ /**
49
+ * Client GET call
50
+ *
51
+ * @param string $apiKey
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);
59
+ $client->setHeaders('Authorization', 'Token token="' . $apiKey . '"');
60
 
61
+ return $client;
62
+ }
63
  }
app/code/community/Taxjar/SalesTax/Model/Comment.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
- /**
3
- * TaxJar Extension UI
4
- *
5
- * @author Taxjar (support@taxjar.com)
6
- */
7
- class Taxjar_SalesTax_Model_Comment
8
- {
9
- /**
10
- * Display Nexus states loaded and API Key setting
11
- *
12
- * @param void
13
- * @return $string
14
- */
15
- public function getCommentText()
16
- {
17
- $regionId = Mage::getStoreConfig('shipping/origin/region_id');
18
- $regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
19
- $lastUpdate = Mage::getStoreConfig('taxjar/config/last_update');
20
-
21
- if (!empty($lastUpdate)) {
22
- $states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
23
- $statesHtml = $this->buildStatesHtml($states, $regionCode);
24
- return $this->buildInstalledHtml($statesHtml, $lastUpdate);
25
- } else {
26
- return $this->buildNotYetInstalledHtml($this->fullStateName($regionCode));
27
- }
28
- }
29
-
30
- /**
31
- * Get the number of rates loaded
32
- *
33
- * @param void
34
- * @return $array
35
- */
36
- private function getNumberOfRatesLoaded($states)
37
- {
38
- $rates = Mage::getModel("tax/calculation_rate");
39
- $stateRatesLoadedCount = 0;
40
- $ratesByState = array();
41
-
42
- foreach (array_unique($states) as $state) {
43
- $regionModel = Mage::getModel('directory/region')->loadByCode($state, 'US');
44
- $regionId = $regionModel->getId();
45
- $ratesByState[$state] = $rates->getCollection()->addFieldToFilter('tax_region_id', array('eq' => $regionId))->getSize();
46
- }
47
-
48
- $rateCalcs = array(
49
- "total_rates" => array_sum($ratesByState),
50
- "rates_loaded" => Mage::getModel('taxjar/rate')->getExistingRates()->getSize(),
51
- "rates_by_state" => $ratesByState
52
- );
53
-
54
- return $rateCalcs;
55
- }
56
-
57
- /**
58
- * Build String from State Abbr
59
- *
60
- * @param $string
61
- * @return $string
62
- */
63
- private function fullStateName($stateCode)
64
- {
65
- $regionModel = Mage::getModel('directory/region')->loadByCode($stateCode, 'US');
66
- return $regionModel->getDefaultName();
67
- }
68
-
69
- /**
70
- * Build HTML for installed text
71
- *
72
- * @param $string, $string
73
- * @return $string
74
- */
75
- private function buildInstalledHtml($statesHtml, $lastUpdate)
76
- {
77
- $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 <em>automatically</em> 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://taxjar.com/magento/tax-settings' 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, then save the config. This will remove all tax rates in 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>";
78
- return $htmlString;
79
- }
80
-
81
- /**
82
- * Build HTML for not yet installed text
83
- *
84
- * @param $string
85
- * @return $string
86
- */
87
- private function buildNotYetInstalledHtml($regionName)
88
- {
89
- $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://taxjar.com/magento/tax-settings' 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>";
90
- return $htmlString;
91
- }
92
-
93
- /**
94
- * Build HTML list of states
95
- *
96
- * @param $string, $string
97
- * @return $string
98
- */
99
- private function buildStatesHtml($states, $regionCode)
100
- {
101
- $states[] = $regionCode;
102
- $statesHtml = '';
103
-
104
- sort($states);
105
-
106
- $taxRatesByState = $this->getNumberOfRatesLoaded($states);
107
-
108
- foreach (array_unique($states) as $state) {
109
- if (($stateName = $this->fullStateName($state)) && !empty($stateName)) {
110
- if ($taxRatesByState["rates_by_state"][$state] == 1 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
111
- $totalForState = 'Origin-based rates set';
112
- $class = 'success';
113
- } elseif ($taxRatesByState["rates_by_state"][$state] == 0 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
114
- $class = 'error';
115
- $totalForState = '<a href="https://app.taxjar.com/account#states" target="_blank">Click here</a> and add a zip code for this state to load rates.';
116
- } else {
117
- $class = 'success';
118
- $totalForState = $taxRatesByState["rates_by_state"][$state] . " rates";
119
- }
120
- $statesHtml .= '<li class="' . $class . '-msg"><ul><li><span style="font-size: 1.4em;">' . $stateName . '</span>: ' . $totalForState . '</li></ul></li>';
121
- }
122
- };
123
-
124
- if ($taxRatesByState['rates_loaded'] != $taxRatesByState['total_rates']) {
125
- $matches = 'error';
126
- } else {
127
- $matches = 'success';
128
- }
129
-
130
- $statesHtml .= '<p class="' . $matches . '-msg" style="background: none !important;"><small>&nbsp;&nbsp;' . $taxRatesByState['total_rates'] . ' of ' . $taxRatesByState['rates_loaded'] . ' expected rates loaded.</small></p>';
131
-
132
- return $statesHtml;
133
- }
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/Model/Configuration.php CHANGED
@@ -1,333 +1,349 @@
1
  <?php
2
  /**
3
- * TaxJar configuration setter
4
  *
5
- * @author Taxjar (support@taxjar.com)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  */
7
  class Taxjar_SalesTax_Model_Configuration
8
  {
9
- /**
10
- * Sets shipping taxability in Magento
11
- *
12
- * @param JSON $string
13
- * @return void
14
- */
15
- public function setShippingTaxability($configJson)
16
- {
17
- $taxClass = 0;
 
 
 
 
18
 
19
- if ($configJson['freight_taxable']) {
20
- $taxClass = 4;
21
  }
22
 
23
- $this->setConfig('tax/classes/shipping_tax_class', $taxClass);
24
- }
 
 
 
 
 
 
 
25
 
26
- /**
27
- * Sets tax basis in Magento
28
- *
29
- * @param JSON $string
30
- * @return void
31
- */
32
- public function setTaxBasis($configJson)
33
- {
34
- $basis = 'shipping';
35
 
36
- if ($configJson['tax_source'] === 'origin') {
37
- $basis = 'origin';
38
  }
39
 
40
- $this->setConfig('tax/calculation/based_on', $basis);
41
- }
42
-
43
- /**
44
- * Set display settings for tax in Magento
45
- *
46
- * @param void
47
- * @return void
48
- */
49
- public function setDisplaySettings()
50
- {
51
- $settings = array(
52
- 'tax/display/type',
53
- 'tax/display/shipping',
54
- 'tax/cart_display/price',
55
- 'tax/cart_display/subtotal',
56
- 'tax/cart_display/shipping'
57
- );
58
 
59
- foreach ($settings as $setting) {
60
- $this->setConfig($setting, 1);
 
61
  }
62
- }
63
 
64
- /**
65
- * Setup the TaxJar API user
66
- *
67
- * @param $string
68
- * @return void
69
- */
70
- public function setApiSettings($apiKey)
71
- {
72
- $apiUser = Mage::getModel('api/user');
73
- $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
74
 
75
- if (!$existingUserId) {
76
- $apiUserId = $this->createApiUser($apiKey);
77
- $parentRoleId = $this->createApiRoles($apiUserId);
78
- $this->createApiRules($parentRoleId);
 
79
  }
80
- }
81
 
82
- /**
83
- * Set the API resources for our API user
84
- *
85
- * @param void
86
- * @return void
87
- */
88
- private function createApiRules($parentRoleId)
89
- {
90
- foreach ($this->resourcesToAllow() as $resource) {
91
- $apiRule = Mage::getModel('api/rules');
92
- $apiRule->setRoleId($parentRoleId);
93
- $apiRule->setResourceId($resource);
94
- $apiRule->setRoleType('G');
95
- $apiRule->setApiPermission('allow');
96
- $apiRule->save();
97
- }
98
 
99
- foreach ($this->resourcesToDeny() as $resource) {
100
- $apiRule = Mage::getModel('api/rules');
101
- $apiRule->setRoleId($parentRoleId);
102
- $apiRule->setResourceId($resource);
103
- $apiRule->setRoleType('G');
104
- $apiRule->setApiPermission('deny');
105
- $apiRule->save();
 
106
  }
107
- }
108
 
109
- /**
110
- * Set the roles for our API User
111
- *
112
- * @param $integer
113
- * @return $integer
114
- */
115
- private function createApiRoles($apiUserId)
116
- {
117
- $parentApiRole = Mage::getModel('api/role');
118
- $parentApiRole->setRoleName('taxjar_api');
119
- $parentApiRole->setTreeLevel(1);
120
- $parentApiRole->setRoleType('G');
121
- $parentApiRole->save();
122
- $parentRoleId = $parentApiRole->getId();
123
 
124
- $childApiRole = Mage::getModel('api/role');
125
- $childApiRole->setRoleName('TaxJar');
126
- $childApiRole->setTreeLevel(1);
127
- $childApiRole->setParentId($parentRoleId);
128
- $childApiRole->setRoleType('U');
129
- $childApiRole->setUserId($apiUserId);
130
- $childApiRole->save();
131
 
132
- return $parentRoleId;
133
- }
134
 
135
- /**
136
- * Set the API resources for our API user
137
- *
138
- * @param void
139
- * @return void
140
- */
141
- private function createApiUser($apiKey)
142
- {
143
- $apiUser = Mage::getModel('api/user');
144
- $apiUser->setUsername('taxjar');
145
- $apiUser->setFirstname('TaxJar');
146
- $apiUser->setLastname('Magento');
147
- $apiUser->setEmail('support@taxjar.com');
148
- $apiUser->setApiKey($apiKey);
149
- $apiUser->setIsActive(1);
150
- $apiUser->save();
151
 
152
- return $apiUser->getUserId();
153
- }
154
 
155
- /**
156
- * Store config
157
- *
158
- * @param $string, $mixed
159
- * @return void
160
- */
161
- private function setConfig($path, $value)
162
- {
163
- Mage::getConfig()->saveConfig($path, $value, 'default', 0);
164
- }
 
165
 
166
- /**
167
- * resources to allow for our API user
168
- *
169
- * @param void
170
- * @return $array
171
- */
172
- private function resourcesToAllow()
173
- {
174
- return array(
175
- 'sales',
176
- 'sales/order',
177
- 'sales/order/change',
178
- 'sales/order/info',
179
- 'sales/order/shipment',
180
- 'sales/order/shipment/create',
181
- 'sales/order/shipment/comment',
182
- 'sales/order/shipment/track',
183
- 'sales/order/shipment/info',
184
- 'sales/order/shipment/send',
185
- 'sales/order/invoice',
186
- 'sales/order/invoice/create',
187
- 'sales/order/invoice/comment',
188
- 'sales/order/invoice/capture',
189
- 'sales/order/invoice/void',
190
- 'sales/order/invoice/cancel',
191
- 'sales/order/invoice/info',
192
- 'sales/order/creditmemo',
193
- 'sales/order/creditmemo/create',
194
- 'sales/order/creditmemo/comment',
195
- 'sales/order/creditmemo/cancel',
196
- 'sales/order/creditmemo/info',
197
- 'sales/order/creditmemo/list'
198
- );
199
- }
200
 
201
- /**
202
- * resources to deny for our API user
203
- *
204
- * @param void
205
- * @return $array
206
- */
207
- private function resourcesToDeny()
208
- {
209
- return array(
210
- 'core',
211
- 'core/store',
212
- 'core/store/info',
213
- 'core/store/list',
214
- 'core/magento',
215
- 'core/magento/info',
216
- 'directory',
217
- 'directory/country',
218
- 'directory/region',
219
- 'customer',
220
- 'customer/create',
221
- 'customer/update',
222
- 'customer/delete',
223
- 'customer/info',
224
- 'customer/address',
225
- 'customer/address/create',
226
- 'customer/address/update',
227
- 'customer/address/delete',
228
- 'customer/address/info',
229
- 'catalog',
230
- 'catalog/category',
231
- 'catalog/category/create',
232
- 'catalog/category/update',
233
- 'catalog/category/move',
234
- 'catalog/category/delete',
235
- 'catalog/category/tree',
236
- 'catalog/category/info',
237
- 'catalog/category/attributes',
238
- 'catalog/category/product',
239
- 'catalog/category/product/assign',
240
- 'catalog/category/product/update',
241
- 'catalog/category/product/remove',
242
- 'catalog/product',
243
- 'catalog/product/create',
244
- 'catalog/product/update',
245
- 'catalog/product/delete',
246
- 'catalog/product/update_tier_price',
247
- 'catalog/product/info',
248
- 'catalog/product/listOfAdditionalAttributes',
249
- 'catalog/product/attributes',
250
- 'catalog/product/attribute',
251
- 'catalog/product/attribute/read',
252
- 'catalog/product/attribute/write',
253
- 'catalog/product/attribute/types',
254
- 'catalog/product/attribute/create',
255
- 'catalog/product/attribute/update',
256
- 'catalog/product/attribute/remove',
257
- 'catalog/product/attribute/info',
258
- 'catalog/product/attribute/option',
259
- 'catalog/product/attribute/option/add',
260
- 'catalog/product/attribute/option/remove',
261
- 'catalog/product/attribute/set',
262
- 'catalog/product/attribute/set/list',
263
- 'catalog/product/attribute/set/create',
264
- 'catalog/product/attribute/set/remove',
265
- 'catalog/product/attribute/set/attribute_add',
266
- 'catalog/product/attribute/set/attribute_remove',
267
- 'catalog/product/attribute/set/group_add',
268
- 'catalog/product/attribute/set/group_rename',
269
- 'catalog/product/attribute/set/group_remove',
270
- 'catalog/product/link',
271
- 'catalog/product/link/assign',
272
- 'catalog/product/link/update',
273
- 'catalog/product/link/remove',
274
- 'catalog/product/media',
275
- 'catalog/product/media/create',
276
- 'catalog/product/media/update',
277
- 'catalog/product/media/remove',
278
- 'catalog/product/option',
279
- 'catalog/product/option/add',
280
- 'catalog/product/option/update',
281
- 'catalog/product/option/types',
282
- 'catalog/product/option/info',
283
- 'catalog/product/option/list',
284
- 'catalog/product/option/remove',
285
- 'catalog/product/option/value',
286
- 'catalog/product/option/value/list',
287
- 'catalog/product/option/value/info',
288
- 'catalog/product/option/value/add',
289
- 'catalog/product/option/value/update',
290
- 'catalog/product/option/value/remove',
291
- 'catalog/product/tag',
292
- 'catalog/product/tag/list',
293
- 'catalog/product/tag/info',
294
- 'catalog/product/tag/add',
295
- 'catalog/product/tag/update',
296
- 'catalog/product/tag/remove',
297
- 'catalog/product/downloadable_link',
298
- 'catalog/product/downloadable_link/add',
299
- 'catalog/product/downloadable_link/list',
300
- 'catalog/product/downloadable_link/remove',
301
- 'cataloginventory',
302
- 'cataloginventory/update',
303
- 'cataloginventory/info',
304
- 'cart',
305
- 'cart/create',
306
- 'cart/order',
307
- 'cart/info',
308
- 'cart/totals',
309
- 'cart/license',
310
- 'cart/product',
311
- 'cart/product/add',
312
- 'cart/product/update',
313
- 'cart/product/remove',
314
- 'cart/product/list',
315
- 'cart/product/moveToCustomerQuote',
316
- 'cart/customer',
317
- 'cart/customer/set',
318
- 'cart/customer/addresses',
319
- 'cart/shipping',
320
- 'cart/shipping/method',
321
- 'cart/shipping/list',
322
- 'cart/payment',
323
- 'cart/payment/method',
324
- 'cart/payment/list',
325
- 'cart/coupon',
326
- 'cart/coupon/add',
327
- 'cart/coupon/remove',
328
- 'giftmessage',
329
- 'giftmessage/set',
330
- 'all'
331
- );
332
- }
333
  }
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
+ * Configuration Model
20
+ * Set default config values in Magento
21
  */
22
  class Taxjar_SalesTax_Model_Configuration
23
  {
24
+ /**
25
+ * Sets shipping taxability in Magento
26
+ *
27
+ * @param string $configJson
28
+ * @return void
29
+ */
30
+ public function setShippingTaxability($configJson)
31
+ {
32
+ $taxClass = 0;
33
+
34
+ if ($configJson['freight_taxable']) {
35
+ $taxClass = 4;
36
+ }
37
 
38
+ $this->setConfig('tax/classes/shipping_tax_class', $taxClass);
 
39
  }
40
 
41
+ /**
42
+ * Sets tax basis in Magento
43
+ *
44
+ * @param string $configJson
45
+ * @return void
46
+ */
47
+ public function setTaxBasis($configJson)
48
+ {
49
+ $basis = 'shipping';
50
 
51
+ if ($configJson['tax_source'] === 'origin') {
52
+ $basis = 'origin';
53
+ }
 
 
 
 
 
 
54
 
55
+ $this->setConfig('tax/calculation/based_on', $basis);
 
56
  }
57
 
58
+ /**
59
+ * Set display settings for tax in Magento
60
+ *
61
+ * @param void
62
+ * @return void
63
+ */
64
+ public function setDisplaySettings()
65
+ {
66
+ $settings = array(
67
+ 'tax/display/type',
68
+ 'tax/display/shipping',
69
+ 'tax/cart_display/price',
70
+ 'tax/cart_display/subtotal',
71
+ 'tax/cart_display/shipping'
72
+ );
 
 
 
73
 
74
+ foreach ($settings as $setting) {
75
+ $this->setConfig($setting, 1);
76
+ }
77
  }
 
78
 
79
+ /**
80
+ * Setup the TaxJar API user
81
+ *
82
+ * @param string $apiKey
83
+ * @return void
84
+ */
85
+ public function setApiSettings($apiKey)
86
+ {
87
+ $apiUser = Mage::getModel('api/user');
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
 
97
+ /**
98
+ * Set the API resources for our API user
99
+ *
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);
109
+ $apiRule->setRoleType('G');
110
+ $apiRule->setApiPermission('allow');
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);
118
+ $apiRule->setRoleType('G');
119
+ $apiRule->setApiPermission('deny');
120
+ $apiRule->save();
121
+ }
122
  }
 
123
 
124
+ /**
125
+ * Set the roles for our API User
126
+ *
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');
134
+ $parentApiRole->setTreeLevel(1);
135
+ $parentApiRole->setRoleType('G');
136
+ $parentApiRole->save();
137
+ $parentRoleId = $parentApiRole->getId();
138
 
139
+ $childApiRole = Mage::getModel('api/role');
140
+ $childApiRole->setRoleName('TaxJar');
141
+ $childApiRole->setTreeLevel(1);
142
+ $childApiRole->setParentId($parentRoleId);
143
+ $childApiRole->setRoleType('U');
144
+ $childApiRole->setUserId($apiUserId);
145
+ $childApiRole->save();
146
 
147
+ return $parentRoleId;
148
+ }
149
 
150
+ /**
151
+ * Set the API resources for our API user
152
+ *
153
+ * @param void
154
+ * @return void
155
+ */
156
+ private function createApiUser($apiKey)
157
+ {
158
+ $apiUser = Mage::getModel('api/user');
159
+ $apiUser->setUsername('taxjar');
160
+ $apiUser->setFirstname('TaxJar');
161
+ $apiUser->setLastname('Magento');
162
+ $apiUser->setEmail('support@taxjar.com');
163
+ $apiUser->setApiKey($apiKey);
164
+ $apiUser->setIsActive(1);
165
+ $apiUser->save();
166
 
167
+ return $apiUser->getUserId();
168
+ }
169
 
170
+ /**
171
+ * Store config
172
+ *
173
+ * @param string $path
174
+ * @param string $value
175
+ * @return void
176
+ */
177
+ private function setConfig($path, $value)
178
+ {
179
+ Mage::getConfig()->saveConfig($path, $value, 'default', 0);
180
+ }
181
 
182
+ /**
183
+ * Resources to allow for our API user
184
+ *
185
+ * @param void
186
+ * @return array
187
+ */
188
+ private function resourcesToAllow()
189
+ {
190
+ return array(
191
+ 'sales',
192
+ 'sales/order',
193
+ 'sales/order/change',
194
+ 'sales/order/info',
195
+ 'sales/order/shipment',
196
+ 'sales/order/shipment/create',
197
+ 'sales/order/shipment/comment',
198
+ 'sales/order/shipment/track',
199
+ 'sales/order/shipment/info',
200
+ 'sales/order/shipment/send',
201
+ 'sales/order/invoice',
202
+ 'sales/order/invoice/create',
203
+ 'sales/order/invoice/comment',
204
+ 'sales/order/invoice/capture',
205
+ 'sales/order/invoice/void',
206
+ 'sales/order/invoice/cancel',
207
+ 'sales/order/invoice/info',
208
+ 'sales/order/creditmemo',
209
+ 'sales/order/creditmemo/create',
210
+ 'sales/order/creditmemo/comment',
211
+ 'sales/order/creditmemo/cancel',
212
+ 'sales/order/creditmemo/info',
213
+ 'sales/order/creditmemo/list'
214
+ );
215
+ }
216
 
217
+ /**
218
+ * Resources to deny for our API user
219
+ *
220
+ * @param void
221
+ * @return array
222
+ */
223
+ private function resourcesToDeny()
224
+ {
225
+ return array(
226
+ 'core',
227
+ 'core/store',
228
+ 'core/store/info',
229
+ 'core/store/list',
230
+ 'core/magento',
231
+ 'core/magento/info',
232
+ 'directory',
233
+ 'directory/country',
234
+ 'directory/region',
235
+ 'customer',
236
+ 'customer/create',
237
+ 'customer/update',
238
+ 'customer/delete',
239
+ 'customer/info',
240
+ 'customer/address',
241
+ 'customer/address/create',
242
+ 'customer/address/update',
243
+ 'customer/address/delete',
244
+ 'customer/address/info',
245
+ 'catalog',
246
+ 'catalog/category',
247
+ 'catalog/category/create',
248
+ 'catalog/category/update',
249
+ 'catalog/category/move',
250
+ 'catalog/category/delete',
251
+ 'catalog/category/tree',
252
+ 'catalog/category/info',
253
+ 'catalog/category/attributes',
254
+ 'catalog/category/product',
255
+ 'catalog/category/product/assign',
256
+ 'catalog/category/product/update',
257
+ 'catalog/category/product/remove',
258
+ 'catalog/product',
259
+ 'catalog/product/create',
260
+ 'catalog/product/update',
261
+ 'catalog/product/delete',
262
+ 'catalog/product/update_tier_price',
263
+ 'catalog/product/info',
264
+ 'catalog/product/listOfAdditionalAttributes',
265
+ 'catalog/product/attributes',
266
+ 'catalog/product/attribute',
267
+ 'catalog/product/attribute/read',
268
+ 'catalog/product/attribute/write',
269
+ 'catalog/product/attribute/types',
270
+ 'catalog/product/attribute/create',
271
+ 'catalog/product/attribute/update',
272
+ 'catalog/product/attribute/remove',
273
+ 'catalog/product/attribute/info',
274
+ 'catalog/product/attribute/option',
275
+ 'catalog/product/attribute/option/add',
276
+ 'catalog/product/attribute/option/remove',
277
+ 'catalog/product/attribute/set',
278
+ 'catalog/product/attribute/set/list',
279
+ 'catalog/product/attribute/set/create',
280
+ 'catalog/product/attribute/set/remove',
281
+ 'catalog/product/attribute/set/attribute_add',
282
+ 'catalog/product/attribute/set/attribute_remove',
283
+ 'catalog/product/attribute/set/group_add',
284
+ 'catalog/product/attribute/set/group_rename',
285
+ 'catalog/product/attribute/set/group_remove',
286
+ 'catalog/product/link',
287
+ 'catalog/product/link/assign',
288
+ 'catalog/product/link/update',
289
+ 'catalog/product/link/remove',
290
+ 'catalog/product/media',
291
+ 'catalog/product/media/create',
292
+ 'catalog/product/media/update',
293
+ 'catalog/product/media/remove',
294
+ 'catalog/product/option',
295
+ 'catalog/product/option/add',
296
+ 'catalog/product/option/update',
297
+ 'catalog/product/option/types',
298
+ 'catalog/product/option/info',
299
+ 'catalog/product/option/list',
300
+ 'catalog/product/option/remove',
301
+ 'catalog/product/option/value',
302
+ 'catalog/product/option/value/list',
303
+ 'catalog/product/option/value/info',
304
+ 'catalog/product/option/value/add',
305
+ 'catalog/product/option/value/update',
306
+ 'catalog/product/option/value/remove',
307
+ 'catalog/product/tag',
308
+ 'catalog/product/tag/list',
309
+ 'catalog/product/tag/info',
310
+ 'catalog/product/tag/add',
311
+ 'catalog/product/tag/update',
312
+ 'catalog/product/tag/remove',
313
+ 'catalog/product/downloadable_link',
314
+ 'catalog/product/downloadable_link/add',
315
+ 'catalog/product/downloadable_link/list',
316
+ 'catalog/product/downloadable_link/remove',
317
+ 'cataloginventory',
318
+ 'cataloginventory/update',
319
+ 'cataloginventory/info',
320
+ 'cart',
321
+ 'cart/create',
322
+ 'cart/order',
323
+ 'cart/info',
324
+ 'cart/totals',
325
+ 'cart/license',
326
+ 'cart/product',
327
+ 'cart/product/add',
328
+ 'cart/product/update',
329
+ 'cart/product/remove',
330
+ 'cart/product/list',
331
+ 'cart/product/moveToCustomerQuote',
332
+ 'cart/customer',
333
+ 'cart/customer/set',
334
+ 'cart/customer/addresses',
335
+ 'cart/shipping',
336
+ 'cart/shipping/method',
337
+ 'cart/shipping/list',
338
+ 'cart/payment',
339
+ 'cart/payment/method',
340
+ 'cart/payment/list',
341
+ 'cart/coupon',
342
+ 'cart/coupon/add',
343
+ 'cart/coupon/remove',
344
+ 'giftmessage',
345
+ 'giftmessage/set',
346
+ 'all'
347
+ );
348
+ }
349
  }
app/code/community/Taxjar/SalesTax/Model/Debug.php CHANGED
@@ -1,43 +1,60 @@
1
  <?php
2
  /**
3
- * TaxJar Debug UI
 
 
 
 
 
 
 
4
  *
5
- * @author Taxjar (support@taxjar.com)
 
 
 
6
  */
7
- class Taxjar_SalesTax_Model_Debug {
8
- /**
9
- * Display debug information
10
- *
11
- * @param void
12
- * @return $string
13
- */
14
- public function getCommentText()
15
- {
16
- $debug = Mage::getStoreConfig('taxjar/config/debug');
17
 
18
- if ($debug) {
19
- 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();
20
- } else {
21
- 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>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
- }
24
 
25
- /**
26
- * Gather debug information
27
- *
28
- * @param void
29
- * @return $string
30
- */
31
- private function getDebugHtmlString()
32
- {
33
- $states = implode(',', unserialize(Mage::getStoreConfig('taxjar/config/states')));
34
- $apiUser = Mage::getModel('api/user');
35
- $existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
36
- $pluginVersion = '1.5.1';
37
- $phpMemory = @ini_get('memory_limit');
38
- $phpVersion = @phpversion();
39
- $magentoVersion = Mage::getVersion();
40
- $lastUpdated = Mage::getStoreConfig('taxjar/config/last_update');
41
- return "<ul> <li><strong>Additonal 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>";
42
- }
 
43
  }
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 Debug UI
20
+ * Get diagnostic info when enabled
21
+ */
22
+ class Taxjar_SalesTax_Model_Debug
23
+ {
24
+ /**
25
+ * Display debug information
26
+ *
27
+ * @param void
28
+ * @return string
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
+ }
39
  }
 
40
 
41
+ /**
42
+ * Gather debug information
43
+ *
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.0';
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
+ }
60
  }
app/code/community/Taxjar/SalesTax/Model/Import/Comment.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 imported states and help info
21
+ */
22
+ class Taxjar_SalesTax_Model_Import_Comment
23
+ {
24
+ /**
25
+ * Display Nexus states loaded and API Key setting
26
+ *
27
+ * @param void
28
+ * @return string
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
+
45
+ /**
46
+ * Get the number of rates loaded
47
+ *
48
+ * @param array $states
49
+ * @return array
50
+ */
51
+ private function getNumberOfRatesLoaded($states)
52
+ {
53
+ $rates = Mage::getModel('tax/calculation_rate');
54
+ $stateRatesLoadedCount = 0;
55
+ $ratesByState = array();
56
+
57
+ foreach (array_unique($states) as $state) {
58
+ $regionModel = Mage::getModel('directory/region')->loadByCode($state, 'US');
59
+ $regionId = $regionModel->getId();
60
+ $ratesByState[$state] = $rates->getCollection()->addFieldToFilter('tax_region_id', array('eq' => $regionId))->getSize();
61
+ }
62
+
63
+ $rateCalcs = array(
64
+ 'total_rates' => array_sum($ratesByState),
65
+ 'rates_loaded' => Mage::getModel('taxjar/import_rate')->getExistingRates()->getSize(),
66
+ 'rates_by_state' => $ratesByState
67
+ );
68
+
69
+ return $rateCalcs;
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
+
111
+ /**
112
+ * Build HTML list of states
113
+ *
114
+ * @param string $states
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';
132
+ } elseif ($taxRatesByState['rates_by_state'][$state] == 0 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
133
+ $class = 'error';
134
+ $totalForState = '<a href="https://app.taxjar.com/account#states" target="_blank">Click here</a> and add a zip code for this state to load rates.';
135
+ } else {
136
+ $class = 'success';
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
+
144
+ if ($taxRatesByState['rates_loaded'] != $taxRatesByState['total_rates']) {
145
+ $matches = 'error';
146
+ } else {
147
+ $matches = 'success';
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
+ }
app/code/community/Taxjar/SalesTax/Model/Import/Rate.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Rate Model
20
+ * Create new tax rates when importing rates
21
+ */
22
+ class Taxjar_SalesTax_Model_Import_Rate
23
+ {
24
+ private $cache;
25
+
26
+ public function __construct()
27
+ {
28
+ $this->cache = Mage::getSingleton('core/cache');
29
+ }
30
+
31
+ /**
32
+ * Attempt to create a new rate from JSON data
33
+ *
34
+ * @param string $rateJson
35
+ * @return array
36
+ */
37
+ public function create($rateJson)
38
+ {
39
+ try {
40
+ $zip = $rateJson['zip'];
41
+ $regionCode = $rateJson['state'];
42
+ $rate = $rateJson['rate'];
43
+
44
+ if (isset($rateJson['country'])) {
45
+ $countryCode = $rateJson['country'];
46
+ } else {
47
+ $countryCode = 'US';
48
+ }
49
+
50
+ if ($this->cache->load('regionId') && $regionCode == $this->cache->load('regionCode') && $countryCode == $this->cache->load('countryCode')) {
51
+ $regionId = $this->cache->load('regionId');
52
+ } else {
53
+ $regionId = Mage::getModel('directory/region')->loadByCode($regionCode, $countryCode)->getId();
54
+ $this->cache->save($regionId, 'regionId');
55
+ $this->cache->save($regionCode, 'regionCode');
56
+ $this->cache->save($countryCode, 'countryCode');
57
+ }
58
+
59
+ $rateModel = Mage::getModel('tax/calculation_rate');
60
+ $rateModel->setTaxCountryId($countryCode);
61
+ $rateModel->setTaxRegionId($regionId);
62
+ $rateModel->setTaxPostcode($zip);
63
+ $rateModel->setCode($countryCode . '-' . $regionCode . '-' . $zip);
64
+ $rateModel->setRate($rate);
65
+ $rateModel->save();
66
+
67
+ if ($rateJson['freight_taxable']) {
68
+ $shippingRateId = $rateModel->getId();
69
+ } else {
70
+ $shippingRateId = 0;
71
+ }
72
+
73
+ return array($rateModel->getId(), $shippingRateId);
74
+ } catch (Exception $e) {
75
+ // Mage::getSingleton('core/session')->addNotice("There was an error encountered while loading rate with code " . $rateModel->getCode() . ". This is most likely due to duplicate codes and can be safely ignored if lots of other rates were loaded. If the error persists, email support@taxjar.com with a screenshot of any Magento errors displayed.");
76
+ unset($rateModel);
77
+ return;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Get existing TaxJar rates based on configuration states
83
+ *
84
+ * @param void
85
+ * @return array
86
+ */
87
+ public function getExistingRates()
88
+ {
89
+ return Mage::getModel('tax/calculation_rate')
90
+ ->getCollection()
91
+ ->addFieldToFilter('tax_region_id', $this->getRegionFilter());
92
+ }
93
+
94
+ /**
95
+ * Get existing TaxJar rule calculations based on the rate ID
96
+ *
97
+ * @param string $rateId
98
+ * @return array
99
+ */
100
+ public function getCalculationsByRateId($rateId)
101
+ {
102
+ return Mage::getModel('tax/calculation')
103
+ ->getCollection()
104
+ ->addFieldToFilter('tax_calculation_rate_id', $rateId);
105
+ }
106
+
107
+ /**
108
+ * Get region filter for existing configuration states
109
+ *
110
+ * @param void
111
+ * @return array
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) {
119
+ $regionId = Mage::getModel('directory/region')->loadByCode($state, 'US')->getId();
120
+ $filter[] = array('finset' => array($regionId));
121
+ }
122
+
123
+ return $filter;
124
+ }
125
+ }
app/code/community/Taxjar/SalesTax/Model/Import/Rule.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Rule Model
20
+ * Create new tax rules when importing rates
21
+ */
22
+ class Taxjar_SalesTax_Model_Import_Rule
23
+ {
24
+ /**
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');
53
+ $ruleModel->setData($attributes);
54
+ $ruleModel->setCalculateSubtotal(0);
55
+ $ruleModel->save();
56
+ $ruleModel->saveCalculationData();
57
+ }
58
+ }
app/code/community/Taxjar/SalesTax/Model/Observer.php DELETED
@@ -1,189 +0,0 @@
1
- <?php
2
- /**
3
- * TaxJar Observer.
4
- *
5
- * @author Taxjar (support@taxjar.com)
6
- */
7
- class Taxjar_SalesTax_Model_Observer
8
- {
9
- /**
10
- * TaxJar observer
11
- *
12
- * @param Varien_Event_Observer $observer
13
- * @return void
14
- */
15
- public function execute($observer)
16
- {
17
- $session = Mage::getSingleton('adminhtml/session');
18
- $apiKey = Mage::getStoreConfig('taxjar/config/apikey');
19
- $apiKey = preg_replace('/\s+/', '', $apiKey);
20
-
21
- if ($apiKey) {
22
- $this->version = 'v2';
23
- $client = Mage::getModel('taxjar/client');
24
- $configuration = Mage::getModel('taxjar/configuration');
25
- $regionId = Mage::getStoreConfig('shipping/origin/region_id');
26
- $this->storeZip = Mage::getStoreConfig('shipping/origin/postcode');
27
- $this->regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
28
- $validZip = preg_match("/(\d{5}-\d{4})|(\d{5})/", $this->storeZip);
29
- $debug = Mage::getStoreConfig('taxjar/config/debug');
30
-
31
- if (isset($this->regionCode)) {
32
- $configJson = $client->getResource($apiKey, $this->apiUrl('config'));
33
- $configJson = $configJson['configuration'];
34
- } else {
35
- Mage::throwException("Please check that you have set a Region/State in Shipping Settings.");
36
- }
37
-
38
- if ($debug) {
39
- Mage::getSingleton('core/session')->addNotice("Debug mode enabled. Tax rates have not been altered.");
40
- return;
41
- }
42
-
43
- if ($configJson['wait_for_rates'] > 0) {
44
- $dateUpdated = Mage::getStoreConfig('taxjar/config/last_update');
45
- Mage::getSingleton('core/session')->addNotice("Your last rate update was too recent. Please wait at least 5 minutes and try again.");
46
- return;
47
- }
48
-
49
- if ($validZip === 1 && isset($this->storeZip) && trim($this->storeZip) !== '') {
50
- $ratesJson = $client->getResource($apiKey, $this->apiUrl('rates'));
51
- } else {
52
- Mage::throwException("Please check that your zip code is a valid US zip code in Shipping Settings.");
53
- }
54
-
55
- Mage::getModel('core/config')
56
- ->saveConfig('taxjar/config/states', serialize(explode(',', $configJson['states'])));
57
- $configuration->setTaxBasis($configJson);
58
- $configuration->setShippingTaxability($configJson);
59
- $configuration->setDisplaySettings();
60
- $configuration->setApiSettings($apiKey);
61
- Mage::getModel('core/config')
62
- ->saveConfig('taxjar/config/freight_taxable', $configJson['freight_taxable']);
63
- $this->purgeExisting();
64
-
65
- if (false !== file_put_contents($this->getTempFileName(), serialize($ratesJson))) {
66
- Mage::dispatchEvent('taxjar_salestax_import_rates');
67
- } else {
68
- // We need to be able to store the file...
69
- Mage::throwException("Could not write to your Magento temp directory. Please check permissions for " . Mage::getBaseDir('tmp') . ".");
70
- }
71
- } else {
72
- Mage::getSingleton('core/session')->addNotice("TaxJar has been uninstalled. All tax rates have been removed.");
73
- $this->purgeExisting();
74
- $this->setLastUpdateDate(NULL);
75
- }
76
- // Clearing the cache to avoid UI elements not loading
77
- Mage::app()->getCacheInstance()->flush();
78
- }
79
-
80
- /**
81
- * Read our file and import all the rates, triggered via taxjar_salestax_import_rates
82
- *
83
- * @param void
84
- * @return void
85
- */
86
- public function importRates()
87
- {
88
- // This process can take a while
89
- @set_time_limit(0);
90
- @ignore_user_abort(true);
91
-
92
- $this->newRates = array();
93
- $this->freightTaxableRates = array();
94
- $rate = Mage::getModel('taxjar/rate');
95
- $filename = $this->getTempFileName();
96
- $rule = Mage::getModel('taxjar/rule');
97
- $shippingTaxable = Mage::getStoreConfig('taxjar/config/freight_taxable');
98
- $ratesJson = unserialize(file_get_contents($filename));
99
-
100
- foreach ($ratesJson['rates'] as $rateJson) {
101
- $rateIdWithShippingId = $rate->create($rateJson);
102
-
103
- if ($rateIdWithShippingId[0]) {
104
- $this->newRates[] = $rateIdWithShippingId[0];
105
- }
106
-
107
- if ($rateIdWithShippingId[1]) {
108
- $this->freightTaxableRates[] = $rateIdWithShippingId[1];
109
- }
110
- }
111
-
112
- $this->setLastUpdateDate(date('m-d-Y'));
113
- $rule->create('Retail Customer-Taxable Goods-Rate 1', 2, 1, $this->newRates);
114
-
115
- if ($shippingTaxable) {
116
- $rule->create('Retail Customer-Shipping-Rate 1', 4, 2, $this->freightTaxableRates);
117
- }
118
-
119
- @unlink($filename);
120
- Mage::getSingleton('core/session')->addSuccess('TaxJar has added new rates to your database! Thanks for using TaxJar!');
121
- Mage::dispatchEvent('taxjar_salestax_import_rates_after');
122
- }
123
-
124
- /**
125
- * Build URL string
126
- *
127
- * @param $string
128
- * @return $string
129
- */
130
- private function apiUrl($type)
131
- {
132
- $apiHost = 'https://api.taxjar.com/';
133
- $prefix = $apiHost . $this->version . '/plugins/magento/';
134
-
135
- if ($type == 'config') {
136
- return $prefix . 'configuration/' . $this->regionCode;
137
- } elseif ($type == 'rates') {
138
- return $prefix . 'rates/' . $this->regionCode . '/' . $this->storeZip;
139
- }
140
- }
141
-
142
- /**
143
- * Purges the rates and rules
144
- *
145
- * @param void
146
- * @return void
147
- */
148
- private function purgeExisting()
149
- {
150
- $rates = Mage::getModel('taxjar/rate')->getExistingRates()->load();
151
-
152
- foreach ($rates as $rate) {
153
- try {
154
- $calculation = Mage::getModel('tax/calculation')->load($rate->getId(), 'tax_calculation_rate_id');
155
- $calculation->delete();
156
- } catch (Exception $e) {
157
- Mage::getSingleton('core/session')->addError("There was an error deleting from Magento model tax/calculation");
158
- }
159
-
160
- try {
161
- $rate->delete();
162
- } catch (Exception $e) {
163
- Mage::getSingleton('core/session')->addError("There was an error deleting from Magento model tax/calculation_rate");
164
- }
165
- }
166
- }
167
-
168
- /**
169
- * Set the last updated date
170
- *
171
- * @param $string || NULL
172
- * @return void
173
- */
174
- private function setLastUpdateDate($date)
175
- {
176
- Mage::getModel('core/config')->saveConfig('taxjar/config/last_update', $date);
177
- }
178
-
179
- /**
180
- * Set the filename
181
- *
182
- * @param void
183
- * @return $string
184
- */
185
- private function getTempFileName()
186
- {
187
- return Mage::getBaseDir('tmp') . DS . "tj_tmp.dat";
188
- }
189
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/Model/Observer/ImportRates.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_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
+ }
app/code/community/Taxjar/SalesTax/Model/Observer/SalesQuoteCollectTotalsBefore.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_SalesQuoteCollectTotalsBefore
19
+ {
20
+ public function execute(Varien_Event_Observer $observer)
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
+
28
+ return $this;
29
+ }
30
+ }
app/code/community/Taxjar/SalesTax/Model/Observer/SaveConfig.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 = 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) && trim($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/Rate.php DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
- /**
3
- * Create and parse rates from JSON obj
4
- *
5
- * @author Taxjar (support@taxjar.com)
6
- */
7
- class Taxjar_SalesTax_Model_Rate
8
- {
9
- private $cache;
10
-
11
- public function __construct()
12
- {
13
- $this->cache = Mage::getSingleton('core/cache');
14
- }
15
-
16
- /**
17
- * Try to create the rate
18
- *
19
- * @param JSON $string
20
- * @return array
21
- */
22
- public function create($rateJson)
23
- {
24
- try {
25
- $zip = $rateJson['zip'];
26
- $regionCode = $rateJson['state'];
27
- $rate = $rateJson['rate'];
28
-
29
- if (isset($rateJson['country'])) {
30
- $countryCode = $rateJson['country'];
31
- } else {
32
- $countryCode = 'US';
33
- }
34
-
35
- if ($this->cache->load('regionId') && $regionCode == $this->cache->load('regionCode') && $countryCode == $this->cache->load('countryCode')) {
36
- $regionId = $this->cache->load('regionId');
37
- } else {
38
- $regionId = Mage::getModel('directory/region')->loadByCode($regionCode, $countryCode)->getId();
39
- $this->cache->save($regionId, 'regionId');
40
- $this->cache->save($regionCode, 'regionCode');
41
- $this->cache->save($countryCode, 'countryCode');
42
- }
43
-
44
- $rateModel = Mage::getModel('tax/calculation_rate');
45
- $rateModel->setTaxCountryId($countryCode);
46
- $rateModel->setTaxRegionId($regionId);
47
- $rateModel->setTaxPostcode($zip);
48
- $rateModel->setCode($countryCode . '-' . $regionCode . '-' . $zip);
49
- $rateModel->setRate($rate);
50
- $rateModel->save();
51
-
52
- if ($rateJson['freight_taxable']) {
53
- $shippingRateId = $rateModel->getId();
54
- } else {
55
- $shippingRateId = 0;
56
- }
57
-
58
- return array($rateModel->getId(), $shippingRateId);
59
- } catch (Exception $e) {
60
- Mage::getSingleton('core/session')->addNotice("There was an error encountered while loading rate with code " . $rateModel->getCode() . ". This is most likely due to duplicate codes and can be safely ignored if lots of other rates were loaded. If the error persists, email support@taxjar.com with a screenshot of any Magento errors displayed.");
61
- unset($rateModel);
62
- return;
63
- }
64
- }
65
-
66
- /**
67
- * Get existing TaxJar calculations based on configuration states
68
- *
69
- * @param void
70
- * @return $array
71
- */
72
- public function getExistingRates()
73
- {
74
- return Mage::getModel('tax/calculation_rate')
75
- ->getCollection()
76
- ->addFieldToFilter('tax_region_id', $this->getRegionFilter());
77
- }
78
-
79
- /**
80
- * Get region filter for existing configuration states
81
- *
82
- * @param void
83
- * @return void
84
- */
85
- private function getRegionFilter()
86
- {
87
- $states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
88
- $filter = array();
89
-
90
- foreach (array_unique($states) as $state) {
91
- $regionId = Mage::getModel('directory/region')->loadByCode($state, 'US')->getId();
92
- $filter[] = array('finset' => array($regionId));
93
- }
94
-
95
- return $filter;
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/Model/Rule.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
- /**
3
- * Create tax rules
4
- *
5
- * @author Taxjar (support@taxjar.com)
6
- */
7
- class Taxjar_SalesTax_Model_Rule
8
- {
9
- /**
10
- * Display Nexus states loaded and API Key setting
11
- *
12
- * @param $string, $integer, $integer, $array
13
- * @return void
14
- */
15
- public function create($code, $productClass, $position, $newRates)
16
- {
17
- $rule = Mage::getModel('tax/calculation_rule')->load($code, 'code');
18
-
19
- $attributes = array(
20
- 'code' => $code,
21
- 'tax_customer_class' => array(3),
22
- 'tax_product_class' => array($productClass),
23
- 'priority' => 1,
24
- 'position' => $position
25
- );
26
-
27
- if (isset($rule)) {
28
- $attributes['tax_rate'] = array_merge($rule->getRates(), $newRates);
29
- $rule->delete();
30
- } else {
31
- $attributes['tax_rate'] = $newRates;
32
- }
33
-
34
- $ruleModel = Mage::getSingleton('tax/calculation_rule');
35
- $ruleModel->setData($attributes);
36
- $ruleModel->setCalculateSubtotal(0);
37
- $ruleModel->save();
38
- $ruleModel->saveCalculationData();
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Taxjar/SalesTax/Model/Sales/Total/Quote/Tax.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Tax totals calculation model
20
+ */
21
+ class Taxjar_SalesTax_Model_Sales_Total_Quote_Tax extends Mage_Tax_Model_Sales_Total_Quote_Tax
22
+ {
23
+ /**
24
+ * Collect tax totals for quote address
25
+ *
26
+ * @param Mage_Sales_Model_Quote_Address $address
27
+ * @return Mage_Tax_Model_Sales_Total_Quote
28
+ */
29
+ public function collect(Mage_Sales_Model_Quote_Address $address)
30
+ {
31
+ $this->_roundingDeltas = array();
32
+ $this->_baseRoundingDeltas = array();
33
+ $this->_hiddenTaxes = array();
34
+ $address->setShippingTaxAmount(0);
35
+ $address->setBaseShippingTaxAmount(0);
36
+
37
+ $this->_address = $address;
38
+ $smartCalcs = $this->_getSmartCalcs($address);
39
+ $smartCalcsResponse = $smartCalcs->getResponse();
40
+
41
+ if (isset($smartCalcsResponse['body']['tax']) && $smartCalcsResponse['status'] == 200) {
42
+ $store = $address->getQuote()->getStore();
43
+ $items = $this->_getAddressItems($address);
44
+ $rates = $smartCalcsResponse['body']['tax'];
45
+
46
+ $this->_addAmount($store->convertPrice($rates['amount_to_collect']));
47
+ $this->_addBaseAmount($rates['amount_to_collect']);
48
+
49
+ if (count($items) > 0) {
50
+ foreach ($items as $item) {
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
+ }
58
+ }
59
+ }
60
+ } else {
61
+ $this->_store = $address->getQuote()->getStore();
62
+ $customer = $address->getQuote()->getCustomer();
63
+ if ($customer) {
64
+ $this->_calculator->setCustomer($customer);
65
+ }
66
+
67
+ if (!$address->getAppliedTaxesReset()) {
68
+ $address->setAppliedTaxes(array());
69
+ }
70
+
71
+ $items = $this->_getAddressItems($address);
72
+ if (!count($items)) {
73
+ return $this;
74
+ }
75
+ $request = $this->_calculator->getRateRequest(
76
+ $address,
77
+ $address->getQuote()->getBillingAddress(),
78
+ $address->getQuote()->getCustomerTaxClassId(),
79
+ $this->_store
80
+ );
81
+
82
+ if ($this->_config->priceIncludesTax($this->_store)) {
83
+ if ($this->_helper->isCrossBorderTradeEnabled($this->_store)) {
84
+ $this->_areTaxRequestsSimilar = true;
85
+ } else {
86
+ $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests(
87
+ $this->_calculator->getRateOriginRequest($this->_store),
88
+ $request
89
+ );
90
+ }
91
+ }
92
+
93
+ switch ($this->_config->getAlgorithm($this->_store)) {
94
+ case Mage_Tax_Model_Calculation::CALC_UNIT_BASE:
95
+ $this->_unitBaseCalculation($address, $request);
96
+ break;
97
+ case Mage_Tax_Model_Calculation::CALC_ROW_BASE:
98
+ $this->_rowBaseCalculation($address, $request);
99
+ break;
100
+ case Mage_Tax_Model_Calculation::CALC_TOTAL_BASE:
101
+ $this->_totalBaseCalculation($address, $request);
102
+ break;
103
+ default:
104
+ break;
105
+ }
106
+
107
+ $this->_addAmount($address->getExtraTaxAmount());
108
+ $this->_addBaseAmount($address->getBaseExtraTaxAmount());
109
+ $this->_calculateShippingTax($address, $request);
110
+
111
+ $this->_processHiddenTaxes();
112
+
113
+ //round total amounts in address
114
+ $this->_roundTotals($address);
115
+ }
116
+
117
+ return $this;
118
+ }
119
+
120
+ /**
121
+ * Get SmartCalcs model
122
+ *
123
+ * @param Mage_Sales_Model_Quote_Address $address
124
+ * @return Taxjar_SalesTax_Model_SmartCalcs
125
+ */
126
+ protected function _getSmartCalcs(Mage_Sales_Model_Quote_Address $address)
127
+ {
128
+ return Mage::getModel(
129
+ 'taxjar/smartcalcs',
130
+ array('address' => $address)
131
+ );
132
+ }
133
+ }
app/code/community/Taxjar/SalesTax/Model/SmartCalcs.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * SmartCalcs Model
20
+ * Performs sales tax calculations at checkout
21
+ */
22
+ class Taxjar_SalesTax_Model_SmartCalcs
23
+ {
24
+ protected $_response;
25
+
26
+ public function __construct($params = array())
27
+ {
28
+ $this->initTaxForOrder($params['address']);
29
+ }
30
+
31
+ /**
32
+ * Tax calculation for order
33
+ *
34
+ * @param object $address
35
+ * @return void
36
+ */
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;
44
+ }
45
+
46
+ if (!$address->getRegionCode() || !$address->getPostcode()) {
47
+ return;
48
+ }
49
+
50
+ if (!$this->hasNexus($address->getRegionCode())) {
51
+ return;
52
+ }
53
+
54
+ if (!count($address->getAllItems())) {
55
+ return;
56
+ }
57
+
58
+ $fromAddress = array(
59
+ 'from_country' => Mage::getStoreConfig('shipping/origin/country_id', $storeId),
60
+ 'from_zip' => Mage::getStoreConfig('shipping/origin/postcode', $storeId),
61
+ 'from_state' => Mage::getModel('directory/region')->load(Mage::getStoreConfig('shipping/origin/region_id', $storeId))->getCode(),
62
+ 'from_city' => Mage::getStoreConfig('shipping/origin/city', $storeId),
63
+ 'from_street' => Mage::getStoreConfig('shipping/origin/street_line1', $storeId),
64
+ );
65
+
66
+ $toAddress = array(
67
+ 'to_country' => $address->getCountry(),
68
+ 'to_zip' => $address->getPostcode(),
69
+ 'to_state' => $address->getRegionCode(),
70
+ 'to_city' => $address->getCity(),
71
+ 'to_street' => $address->getData('street'),
72
+ );
73
+
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;
101
+ }
102
+ }
103
+
104
+ return $this;
105
+ }
106
+
107
+ /**
108
+ * Get the SmartCalcs API response
109
+ *
110
+ * @return array
111
+ */
112
+ public function getResponse()
113
+ {
114
+ if (isset($this->_response)) {
115
+ return array(
116
+ 'body' => json_decode($this->_response->getBody(), true),
117
+ 'status' => $this->_response->getStatus(),
118
+ );
119
+ } else {
120
+ return array(
121
+ 'status' => 204,
122
+ );
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Get a specific line item breakdown from a SmartCalcs API response
128
+ * Also builds a combined rate based on returned sales tax rates
129
+ *
130
+ * @return array
131
+ */
132
+ public function getResponseLineItem($productId)
133
+ {
134
+ if (isset($this->_response)) {
135
+ $responseBody = json_decode($this->_response->getBody(), true);
136
+
137
+ if (isset($responseBody['tax']['breakdown']['line_items'])) {
138
+ $lineItems = $responseBody['tax']['breakdown']['line_items'];
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
+ }
149
+ }
150
+
151
+ /**
152
+ * Verify if nexus is triggered for location
153
+ *
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;
163
+ } else {
164
+ return false;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Get order line items
170
+ *
171
+ * @param array $address
172
+ * @return array
173
+ */
174
+ private function getLineItems($address)
175
+ {
176
+ $lineItems = array();
177
+ $items = $address->getAllItems();
178
+
179
+ if (count($items) > 0) {
180
+ foreach ($items as $item) {
181
+ $id = $item->getProductId();
182
+ $quantity = $item->getQty();
183
+ $taxClass = Mage::getModel('tax/class')->load($item->getProduct()->getTaxClassId());
184
+ $taxCode = $taxClass->getTjSalestaxCode();
185
+ $unitPrice = (float) $item->getPrice();
186
+ $discount = (float) $item->getDiscountAmount();
187
+
188
+ array_push($lineItems, array(
189
+ 'id' => $id,
190
+ 'quantity' => $quantity,
191
+ 'product_tax_code' => $taxCode,
192
+ 'unit_price' => $unitPrice,
193
+ 'discount' => $discount,
194
+ ));
195
+ }
196
+ }
197
+
198
+ return $lineItems;
199
+ }
200
+
201
+ /**
202
+ * Verify if the order changed compared to session
203
+ *
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;
213
+ } else {
214
+ return true;
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Get prefixed session data from checkout/session
220
+ *
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
+ }
228
+
229
+ /**
230
+ * Set prefixed session data in checkout/session
231
+ *
232
+ * @param string $key
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
+ }
240
+
241
+ /**
242
+ * Unset prefixed session data in checkout/session
243
+ *
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
+ }
251
+ }
app/code/community/Taxjar/SalesTax/etc/adminhtml.xml CHANGED
@@ -1,23 +1,40 @@
1
- <?xml version="1.0" ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <config>
3
- <!-- repeated in config.xml for compatibility -->
4
- <acl>
5
- <resources>
6
- <admin>
7
- <children>
8
- <system>
9
- <children>
10
- <config>
11
- <children>
12
- <taxjar>
13
- <title>TaxJar Sales Tax Automation</title>
14
- </taxjar>
15
- </children>
16
- </config>
17
- </children>
18
- </system>
19
- </children>
20
- </admin>
21
- </resources>
22
- </acl>
23
  </config>
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
@@ -2,92 +2,132 @@
2
  <!--
3
  /**
4
  * Taxjar_SalesTax
5
- * www.taxjar.com
 
 
 
 
 
 
 
 
 
 
 
 
6
  -->
7
- <config>
8
- <modules>
9
- <Taxjar_SalesTax><version>1.5.1</version></Taxjar_SalesTax>
10
- </modules>
11
- <global>
12
- <helpers>
13
- <taxjar>
14
- <class>Taxjar_SalesTax_Helper</class>
15
- </taxjar>
16
- </helpers>
17
- <models>
18
- <taxjar>
19
- <class>Taxjar_SalesTax_Model</class>
20
- </taxjar>
21
- <tax_resource>
22
- <rewrite>
23
- <calculation>Taxjar_SalesTax_Model_Calculation</calculation>
24
- </rewrite>
25
- </tax_resource>
26
- </models>
27
- <blocks>
28
- <taxjar>
29
- <class>Taxjar_SalesTax_Block</class>
30
- </taxjar>
31
- </blocks>
32
- <events>
33
- <admin_system_config_changed_section_taxjar>
34
- <observers>
35
- <taxjar_salestax_model_observer>
36
- <type>singleton</type>
37
- <class>taxjar/observer</class>
38
- <method>execute</method>
39
- </taxjar_salestax_model_observer>
40
- </observers>
41
- </admin_system_config_changed_section_taxjar>
42
- <taxjar_salestax_import_rates>
43
- <observers>
44
- <taxjar_salestax_model_observer>
45
- <type>singleton</type>
46
- <class>taxjar/observer</class>
47
- <method>importRates</method>
48
- </taxjar_salestax_model_observer>
49
- </observers>
50
- </taxjar_salestax_import_rates>
51
- </events>
52
- </global>
53
- <frontend>
54
- <routers>
55
- <taxjar>
56
- <use>standard</use>
57
- <args>
58
- <module>Taxjar_SalesTax</module>
59
- <frontName>taxjar</frontName>
60
- </args>
61
- </taxjar>
62
- </routers>
63
- </frontend>
64
- <adminhtml>
65
- <acl>
66
- <resources>
67
- <admin>
68
- <children>
69
- <system>
70
- <children>
71
- <config>
72
- <children>
73
- <taxjar>
74
- <title>TaxJar Sales Tax Automation</title>
75
- </taxjar>
76
- </children>
77
- </config>
78
- </children>
79
- </system>
80
- </children>
81
- </admin>
82
- </resources>
83
- </acl>
84
- </adminhtml>
85
- <crontab>
86
- <jobs>
87
- <taxjar>
88
- <schedule><cron_expr>0 8 1 * *</cron_expr></schedule>
89
- <run><model>taxjar/observer::execute</model></run>
90
- </taxjar>
91
- </jobs>
92
- </crontab>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  </config>
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
+ <modules>
21
+ <Taxjar_SalesTax>
22
+ <version>1.6.0</version>
23
+ </Taxjar_SalesTax>
24
+ </modules>
25
+ <global>
26
+ <helpers>
27
+ <taxjar>
28
+ <class>Taxjar_SalesTax_Helper</class>
29
+ </taxjar>
30
+ </helpers>
31
+ <blocks>
32
+ <taxjar>
33
+ <class>Taxjar_SalesTax_Block</class>
34
+ </taxjar>
35
+ <adminhtml>
36
+ <rewrite>
37
+ <tax_class_grid>Taxjar_SalesTax_Block_Adminhtml_Tax_Class_Grid</tax_class_grid>
38
+ <tax_class_edit_form>Taxjar_SalesTax_Block_Adminhtml_Tax_Class_Edit_Form</tax_class_edit_form>
39
+ </rewrite>
40
+ </adminhtml>
41
+ </blocks>
42
+ <models>
43
+ <taxjar>
44
+ <class>Taxjar_SalesTax_Model</class>
45
+ </taxjar>
46
+ <tax_resource>
47
+ <rewrite>
48
+ <calculation>Taxjar_SalesTax_Model_Calculation</calculation>
49
+ </rewrite>
50
+ </tax_resource>
51
+ </models>
52
+ <resources>
53
+ <salestax_setup>
54
+ <setup>
55
+ <module>Taxjar_SalesTax</module>
56
+ </setup>
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>
72
+ <type>singleton</type>
73
+ <class>taxjar/observer_importRates</class>
74
+ <method>execute</method>
75
+ </taxjar>
76
+ </observers>
77
+ </taxjar_salestax_import_rates>
78
+ <sales_quote_collect_totals_before>
79
+ <observers>
80
+ <taxjar>
81
+ <type>singleton</type>
82
+ <class>taxjar/observer_salesQuoteCollectTotalsBefore</class>
83
+ <method>execute</method>
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>
124
+ <schedule>
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>
app/code/community/Taxjar/SalesTax/etc/system.xml CHANGED
@@ -1,56 +1,94 @@
1
  <?xml version="1.0"?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <config>
3
- <tabs>
4
- <taxjar translate="label" module="taxjar">
5
- <label>TaxJar</label>
6
- <sort_order>0</sort_order>
7
- </taxjar>
8
- </tabs>
9
- <sections>
10
- <taxjar translate="label" module="taxjar">
11
- <label>Sales Tax Automation</label>
12
- <tab>taxjar</tab>
13
- <frontend_type>text</frontend_type>
14
- <sort_order>1000</sort_order>
15
- <show_in_default>1</show_in_default>
16
- <show_in_website>1</show_in_website>
17
- <show_in_store>1</show_in_store>
18
- <groups>
19
- <config translate="label">
20
- <label>TaxJar Options</label>
21
- <frontend_type>text</frontend_type>
22
- <sort_order>1</sort_order>
23
- <show_in_default>1</show_in_default>
24
- <show_in_website>1</show_in_website>
25
- <show_in_store>1</show_in_store>
26
- <expanded>1</expanded>
27
- <fields>
28
- <apikey translate="label">
29
- <label>API Token</label>
30
- <comment>
31
- <model>taxjar/comment</model>
32
- </comment>
33
- <frontend_type>text</frontend_type>
34
- <sort_order>1</sort_order>
35
- <show_in_default>1</show_in_default>
36
- <show_in_website>1</show_in_website>
37
- <show_in_store>1</show_in_store>
38
- </apikey>
39
- <debug translate="label">
40
- <label>Debug Mode Enabled</label>
41
- <comment>
42
- <model>taxjar/debug</model>
43
- </comment>
44
- <source_model>adminhtml/system_config_source_yesno</source_model>
45
- <frontend_type>select</frontend_type>
46
- <sort_order>10</sort_order>
47
- <show_in_default>1</show_in_default>
48
- <show_in_website>1</show_in_website>
49
- <show_in_store>1</show_in_store>
50
- </debug>
51
- </fields>
52
- </config>
53
- </groups>
54
- </taxjar>
55
- </sections>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  </config>
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
+ <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>
59
+ <model>taxjar/debug</model>
60
+ </comment>
61
+ <source_model>adminhtml/system_config_source_yesno</source_model>
62
+ <frontend_type>select</frontend_type>
63
+ <sort_order>10</sort_order>
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>
app/code/community/Taxjar/SalesTax/sql/salestax_setup/install-1.6.0.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
+ $installer = $this;
19
+ $installer->startSetup();
20
+
21
+ try {
22
+ $table = $installer->getConnection()
23
+ ->addColumn($installer->getTable('tax/tax_class'), 'tj_salestax_code', array(
24
+ 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
25
+ 'length' => 255,
26
+ 'nullable' => false,
27
+ 'default' => '',
28
+ 'after' => 'class_type',
29
+ 'comment' => 'Class Tax Code for TaxJar'
30
+ ));
31
+ } catch (Exception $e) {
32
+ Mage::logException($e);
33
+ }
34
+
35
+ $installer->endSetup();
app/etc/modules/Taxjar_SalesTax.xml CHANGED
@@ -1,9 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <config>
2
  <modules>
3
  <Taxjar_SalesTax>
4
  <active>true</active>
5
  <codePool>community</codePool>
6
- <depends></depends>
7
  </Taxjar_SalesTax>
8
  </modules>
9
- </config>
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
  <modules>
21
  <Taxjar_SalesTax>
22
  <active>true</active>
23
  <codePool>community</codePool>
 
24
  </Taxjar_SalesTax>
25
  </modules>
26
+ </config>
package.xml CHANGED
@@ -1,18 +1,20 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Taxjar_Salestaxautomation</name>
4
- <version>1.5.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 install rates for multiple origin or destination-based states without affecting your store's checkout experience.</description>
11
- <notes>* Fix 500 server error for stores running older versions of PHP (&lt; 5.4).</notes>
 
 
12
  <authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
13
- <date>2016-02-11</date>
14
- <time>18:22:53</time>
15
- <contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Helper"><file name="Data.php" hash="a7b646cb1956bcd5e7375a5de0694281"/></dir><dir name="Model"><file name="Calculation.php" hash="5a99c13b14811a3e621544f74ce8271d"/><file name="Client.php" hash="e5627a4fd74ceebd8b16ed4e5293212d"/><file name="Comment.php" hash="c2a8732728c391c9fbd5aa77eb3a89a3"/><file name="Configuration.php" hash="2bf053b0031587d910354ab52d72fa8c"/><file name="Debug.php" hash="e546cd9819cc3324db9f17da2f500723"/><file name="Observer.php" hash="a7ee078445f16a8ce006953cbbb83b45"/><file name="Rate.php" hash="19ed81595406f70e0e49be45099ba114"/><file name="Rule.php" hash="cf583b79050e6941bdb4f6310cf2d385"/></dir><dir name="etc"><file name="adminhtml.xml" hash="9731dfa9d72fda332d244b5fc107d047"/><file name="config.xml" hash="3dcedc9f139f89ea81bc097001a8190e"/><file name="system.xml" hash="406ad8c2fc92abcdbed5b5e1d662b8b4"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Taxjar_SalesTax.xml" hash="afb27bfd2c9b05698b4c7bb0659f3432"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Taxjar_Salestaxautomation</name>
4
+ <version>1.6.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>* SmartCalcs integration at checkout for live sales tax calculations and higher accuracy.&#xD;
12
+ * Product tax code support for exemptions.&#xD;
13
+ * Fix rule and rate purging when uninstalling extension.</notes>
14
  <authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
15
+ <date>2016-04-09</date>
16
+ <time>23:47:05</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="8e9917de4d1938ba9d4c32acbeb7bf76"/><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="ccb4ed24c3c6cc81f2ae632e53fdfb73"/></dir><dir name="Sales"><dir name="Total"><dir name="Quote"><file name="Tax.php" hash="ad8eacbe4e897c37ce3a1f0b173e7a64"/></dir></dir></dir><file name="SmartCalcs.php" hash="ea6b6d96137197979bf70a2200339375"/></dir><dir name="etc"><file name="adminhtml.xml" hash="440972a63d83b2475f187f38172f54ca"/><file name="config.xml" hash="edfc2d29d8c0e4edddfe8e0c9c21110d"/><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>