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
- app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Edit/Form.php +40 -0
- app/code/community/Taxjar/SalesTax/Block/Adminhtml/Tax/Class/Grid.php +38 -0
- app/code/community/Taxjar/SalesTax/Helper/Data.php +144 -2
- app/code/community/Taxjar/SalesTax/Model/Calculation.php +45 -29
- app/code/community/Taxjar/SalesTax/Model/Categories.php +51 -0
- app/code/community/Taxjar/SalesTax/Model/Client.php +51 -34
- app/code/community/Taxjar/SalesTax/Model/Comment.php +0 -134
- app/code/community/Taxjar/SalesTax/Model/Configuration.php +319 -303
- app/code/community/Taxjar/SalesTax/Model/Debug.php +52 -35
- app/code/community/Taxjar/SalesTax/Model/Import/Comment.php +154 -0
- app/code/community/Taxjar/SalesTax/Model/Import/Rate.php +125 -0
- app/code/community/Taxjar/SalesTax/Model/Import/Rule.php +58 -0
- app/code/community/Taxjar/SalesTax/Model/Observer.php +0 -189
- app/code/community/Taxjar/SalesTax/Model/Observer/ImportRates.php +79 -0
- app/code/community/Taxjar/SalesTax/Model/Observer/SalesQuoteCollectTotalsBefore.php +30 -0
- app/code/community/Taxjar/SalesTax/Model/Observer/SaveConfig.php +162 -0
- app/code/community/Taxjar/SalesTax/Model/Rate.php +0 -97
- app/code/community/Taxjar/SalesTax/Model/Rule.php +0 -40
- app/code/community/Taxjar/SalesTax/Model/Sales/Total/Quote/Tax.php +133 -0
- app/code/community/Taxjar/SalesTax/Model/SmartCalcs.php +251 -0
- app/code/community/Taxjar/SalesTax/etc/adminhtml.xml +38 -21
- app/code/community/Taxjar/SalesTax/etc/config.xml +127 -87
- app/code/community/Taxjar/SalesTax/etc/system.xml +91 -53
- app/code/community/Taxjar/SalesTax/sql/salestax_setup/install-1.6.0.php +35 -0
- app/etc/modules/Taxjar_SalesTax.xml +19 -2
- 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 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
*
|
| 5 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
*/
|
| 7 |
class Taxjar_SalesTax_Model_Calculation extends Mage_Tax_Model_Resource_Calculation
|
| 8 |
{
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
if ($response->isSuccessful()) {
|
| 20 |
-
$json = $response->getBody();
|
| 21 |
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
| 43 |
|
| 44 |
-
|
| 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> ' . $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 |
-
*
|
| 4 |
*
|
| 5 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
*/
|
| 7 |
class Taxjar_SalesTax_Model_Configuration
|
| 8 |
{
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
-
|
| 20 |
-
$taxClass = 4;
|
| 21 |
}
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
* @param JSON $string
|
| 30 |
-
* @return void
|
| 31 |
-
*/
|
| 32 |
-
public function setTaxBasis($configJson)
|
| 33 |
-
{
|
| 34 |
-
$basis = 'shipping';
|
| 35 |
|
| 36 |
-
|
| 37 |
-
$basis = 'origin';
|
| 38 |
}
|
| 39 |
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
'tax/cart_display/subtotal',
|
| 56 |
-
'tax/cart_display/shipping'
|
| 57 |
-
);
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
|
|
|
| 61 |
}
|
| 62 |
-
}
|
| 63 |
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
|
|
|
| 79 |
}
|
| 80 |
-
}
|
| 81 |
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
|
|
|
| 106 |
}
|
| 107 |
-
}
|
| 108 |
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
|
| 132 |
-
|
| 133 |
-
|
| 134 |
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
|
| 152 |
-
|
| 153 |
-
|
| 154 |
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
|
|
|
| 165 |
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 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 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
*
|
| 5 |
-
* @
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
}
|
| 23 |
-
}
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 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> ' . $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 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 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 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
-->
|
| 7 |
-
<config>
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
<
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
<stability>stable</stability>
|
| 6 |
<license>MIT</license>
|
| 7 |
<channel>community</channel>
|
| 8 |
<extends/>
|
| 9 |
<summary>Easily collect sales tax without altering your Magento store’s checkout experience or performance.</summary>
|
| 10 |
-
<description>TaxJar for Magento allows you to
|
| 11 |
-
<notes>*
|
|
|
|
|
|
|
| 12 |
<authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
|
| 13 |
-
<date>2016-
|
| 14 |
-
<time>
|
| 15 |
-
<contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Helper"><file name="Data.php" hash="
|
| 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’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.
|
| 12 |
+
* Product tax code support for exemptions.
|
| 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>
|
