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