Version Notes
* Existing sales tax rates and rules are no longer overwritten.
* Rates imported from TaxJar are appended to the default rules for taxable goods and shipping.
* Codebase improved to more closely follow Magento standards.
Download this release
Release Info
| Developer | TaxJar |
| Extension | Taxjar_Salestaxautomation |
| Version | 1.5.0 |
| Comparing to | |
| See all releases | |
Code changes from version 1.4.4 to 1.5.0
- app/code/community/Taxjar/SalesTax/Helper/Data.php +3 -3
- app/code/community/Taxjar/SalesTax/Model/Calculation.php +29 -32
- app/code/community/Taxjar/SalesTax/Model/Client.php +14 -17
- app/code/community/Taxjar/SalesTax/Model/Comment.php +38 -39
- app/code/community/Taxjar/SalesTax/Model/Configuration.php +30 -28
- app/code/community/Taxjar/SalesTax/Model/Debug.php +8 -11
- app/code/community/Taxjar/SalesTax/Model/Observer.php +60 -61
- app/code/community/Taxjar/SalesTax/Model/Rate.php +45 -17
- app/code/community/Taxjar/SalesTax/Model/Rule.php +21 -16
- app/code/community/Taxjar/SalesTax/etc/adminhtml.xml +1 -1
- app/code/community/Taxjar/SalesTax/etc/config.xml +1 -2
- app/code/community/Taxjar/SalesTax/etc/system.xml +1 -1
- app/etc/modules/Taxjar_SalesTax.xml +2 -2
- package.xml +7 -5
app/code/community/Taxjar/SalesTax/Helper/Data.php
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar helper
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Helper_Data extends Mage_Core_Helper_Abstract
|
|
|
|
| 9 |
|
| 10 |
-
}
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar helper
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Helper_Data extends Mage_Core_Helper_Abstract
|
| 8 |
+
{
|
| 9 |
|
| 10 |
+
}
|
app/code/community/Taxjar/SalesTax/Model/Calculation.php
CHANGED
|
@@ -1,40 +1,37 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar Zip+4 Rate Calculation Support for US
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Calculation extends Mage_Tax_Model_Resource_Calculation
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
}
|
| 36 |
-
return $rates;
|
| 37 |
}
|
| 38 |
-
|
|
|
|
| 39 |
}
|
| 40 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar Zip+4 Rate Calculation Support for US
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Calculation extends Mage_Tax_Model_Resource_Calculation
|
| 8 |
+
{
|
| 9 |
+
/**
|
| 10 |
+
* Returns tax rates for request and when US only uses five digit zip code lookups
|
| 11 |
+
*
|
| 12 |
+
* @param Varien_Object $request
|
| 13 |
+
* @return array
|
| 14 |
+
*/
|
| 15 |
+
protected function _getRates($request)
|
| 16 |
+
{
|
| 17 |
+
// Grab each current value
|
| 18 |
+
$countryId = $request->getCountryId();
|
| 19 |
+
$currentPostcode = $request->getPostcode();
|
| 20 |
+
if ($countryId == 'US') {
|
| 21 |
+
// Trim whitespace
|
| 22 |
+
$newPostcode = preg_replace('/\s+/', '', $request->getPostcode());
|
| 23 |
+
// Snatch only the first five characters
|
| 24 |
+
$newPostcode = substr($newPostcode, 0, 5);
|
| 25 |
+
// Replace the request's zip code with one that now has 5 digits
|
| 26 |
+
$request->setPostcode($newPostcode);
|
| 27 |
+
// Find rates by the new 5-digit zip
|
| 28 |
+
$rates = parent::_getRates($request);
|
| 29 |
+
// Reset the request's postcode to what it was
|
| 30 |
+
$request->setPostcode($currentPostcode);
|
| 31 |
+
} else {
|
| 32 |
+
// Non-US should just work normally
|
| 33 |
+
$rates = parent::_getRates($request);
|
|
|
|
|
|
|
| 34 |
}
|
| 35 |
+
return $rates;
|
| 36 |
+
}
|
| 37 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Client.php
CHANGED
|
@@ -1,31 +1,29 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar HTTP Client
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Client
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* Connect to the API
|
| 12 |
*
|
| 13 |
* @param $string, $string
|
| 14 |
* @return JSON $string
|
| 15 |
*/
|
| 16 |
-
public function getResource(
|
| 17 |
-
|
|
|
|
| 18 |
|
| 19 |
-
if (
|
| 20 |
$json = $response->getBody();
|
| 21 |
|
| 22 |
return json_decode($json, true);
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
if ( $response->getStatus() == 403 ) {
|
| 26 |
Mage::throwException('Your last rate update was too recent. Please wait at least 5 minutes and try again.');
|
| 27 |
-
}
|
| 28 |
-
else {
|
| 29 |
Mage::throwException('Could not connect to TaxJar.');
|
| 30 |
}
|
| 31 |
}
|
|
@@ -37,13 +35,12 @@ class Taxjar_SalesTax_Model_Client {
|
|
| 37 |
* @param $string, $string
|
| 38 |
* @return Varien_Http_Client $response
|
| 39 |
*/
|
| 40 |
-
private function getClient(
|
| 41 |
-
|
| 42 |
-
$client
|
| 43 |
-
$client->
|
|
|
|
| 44 |
|
| 45 |
return $client;
|
| 46 |
}
|
| 47 |
-
|
| 48 |
}
|
| 49 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar HTTP Client
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Client
|
| 8 |
+
{
|
| 9 |
/**
|
| 10 |
* Connect to the API
|
| 11 |
*
|
| 12 |
* @param $string, $string
|
| 13 |
* @return JSON $string
|
| 14 |
*/
|
| 15 |
+
public function getResource($apiKey, $url)
|
| 16 |
+
{
|
| 17 |
+
$response = $this->getClient($apiKey, $url)->request();
|
| 18 |
|
| 19 |
+
if ($response->isSuccessful()) {
|
| 20 |
$json = $response->getBody();
|
| 21 |
|
| 22 |
return json_decode($json, true);
|
| 23 |
+
} else {
|
| 24 |
+
if ($response->getStatus() == 403) {
|
|
|
|
| 25 |
Mage::throwException('Your last rate update was too recent. Please wait at least 5 minutes and try again.');
|
| 26 |
+
} else {
|
|
|
|
| 27 |
Mage::throwException('Could not connect to TaxJar.');
|
| 28 |
}
|
| 29 |
}
|
| 35 |
* @param $string, $string
|
| 36 |
* @return Varien_Http_Client $response
|
| 37 |
*/
|
| 38 |
+
private function getClient($apiKey, $url)
|
| 39 |
+
{
|
| 40 |
+
$client = new Varien_Http_Client($url);
|
| 41 |
+
$client->setMethod(Varien_Http_Client::GET);
|
| 42 |
+
$client->setHeaders('Authorization', 'Token token="' . $apiKey . '"');
|
| 43 |
|
| 44 |
return $client;
|
| 45 |
}
|
|
|
|
| 46 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Comment.php
CHANGED
|
@@ -1,32 +1,30 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar Extension UI
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Comment
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* Display Nexus states loaded and API Key setting
|
| 12 |
*
|
| 13 |
* @param void
|
| 14 |
* @return $string
|
| 15 |
*/
|
| 16 |
-
public function getCommentText()
|
| 17 |
-
|
| 18 |
-
$
|
| 19 |
-
$
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
$
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
| 25 |
}
|
| 26 |
-
else {
|
| 27 |
-
return $this->buildNotYetInstalledHtml( $this->fullStateName( $regionCode ) );
|
| 28 |
-
}
|
| 29 |
-
|
| 30 |
}
|
| 31 |
|
| 32 |
/**
|
|
@@ -35,19 +33,21 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 35 |
* @param void
|
| 36 |
* @return $array
|
| 37 |
*/
|
| 38 |
-
private function getNumberOfRatesLoaded(
|
|
|
|
| 39 |
$rates = Mage::getModel("tax/calculation_rate");
|
| 40 |
$stateRatesLoadedCount = 0;
|
| 41 |
$ratesByState = array();
|
| 42 |
-
|
|
|
|
| 43 |
$regionModel = Mage::getModel('directory/region')->loadByCode($state, 'US');
|
| 44 |
$regionId = $regionModel->getId();
|
| 45 |
-
$ratesByState[$state] = $rates->getCollection()->addFieldToFilter(
|
| 46 |
}
|
| 47 |
|
| 48 |
$rateCalcs = array(
|
| 49 |
"total_rates" => array_sum($ratesByState),
|
| 50 |
-
"rates_loaded" => Mage::getModel(
|
| 51 |
"rates_by_state" => $ratesByState
|
| 52 |
);
|
| 53 |
|
|
@@ -60,8 +60,9 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 60 |
* @param $string
|
| 61 |
* @return $string
|
| 62 |
*/
|
| 63 |
-
private function fullStateName(
|
| 64 |
-
|
|
|
|
| 65 |
return $regionModel->getDefaultName();
|
| 66 |
}
|
| 67 |
|
|
@@ -71,7 +72,8 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 71 |
* @param $string, $string
|
| 72 |
* @return $string
|
| 73 |
*/
|
| 74 |
-
private function buildInstalledHtml(
|
|
|
|
| 75 |
$htmlString = "<p class='note'><span>TaxJar is installed. Check the <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/tax_rule/index') . "'>Manage Tax Rules section</a> to verify all installed states.</span></p><br/><p>TaxJar has <em>automatically</em> added rates for the following states to your Magento installation:<br/><ul class='messages'>". $statesHtml . "</ul>To manage your TaxJar states <a href='https://app.taxjar.com/account#states' target='_blank'>click here</a>.</p><p>Your sales tax rates were last updated on: <ul class='messages'><li class='info-msg'><ul><li><span style='font-size: 1.4em;'>" . $lastUpdate . "</span></li></ul></li></ul><small>Rates may be automatically or manually updated again once per month. For more information on how your tax settings are changed, <a href='http://taxjar.com/magento/tax-settings' target='_blank'>click here</a>. Contact <a href='mailto:support@taxjar.com'>support@taxjar.com</a> with the email address registered to your TaxJar account if you need assistance.</small></p><p><small>If you would like to uninstall TaxJar, remove the API Token from the box above, then save the config. This will remove all tax rates in your Magento store. You can then uninstall in the Magento Connect Manager.<small></p><p><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</p>";
|
| 76 |
return $htmlString;
|
| 77 |
}
|
|
@@ -82,7 +84,8 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 82 |
* @param $string
|
| 83 |
* @return $string
|
| 84 |
*/
|
| 85 |
-
private function buildNotYetInstalledHtml(
|
|
|
|
| 86 |
$htmlString = "<p class='note'><span>Enter your TaxJar API Token</span></p><br/><p>Enter your TaxJar API Token to import current sales tax rates for all zip codes in <b>" . $regionName . "</b>, your state of origin as set in <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit/section/shipping') . "'>Shipping Settings</a>. We will also retrieve all other states from your TaxJar account. To get an API Token, go to <a href='https://app.taxjar.com/account' target='_blank'>TaxJar's Account Screen.</a></p><p>For more information on how your tax settings are changed, <a href='http://taxjar.com/magento/tax-settings' target='_blank'>click here</a>.</p><p><small><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</small></p>";
|
| 87 |
return $htmlString;
|
| 88 |
}
|
|
@@ -93,25 +96,24 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 93 |
* @param $string, $string
|
| 94 |
* @return $string
|
| 95 |
*/
|
| 96 |
-
private function buildStatesHtml(
|
|
|
|
| 97 |
$states[] = $regionCode;
|
| 98 |
$statesHtml = '';
|
| 99 |
|
| 100 |
-
sort(
|
| 101 |
|
| 102 |
-
$taxRatesByState = $this->getNumberOfRatesLoaded(
|
| 103 |
|
| 104 |
-
foreach (
|
| 105 |
-
if (
|
| 106 |
-
if (
|
| 107 |
$totalForState = 'Origin-based rates set';
|
| 108 |
$class = 'success';
|
| 109 |
-
}
|
| 110 |
-
elseif ( $taxRatesByState["rates_by_state"][$state] == 0 && ( $taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'] ) ) {
|
| 111 |
$class = 'error';
|
| 112 |
$totalForState = '<a href="https://app.taxjar.com/account#states" target="_blank">Click here</a> and add a zip code for this state to load rates.';
|
| 113 |
-
}
|
| 114 |
-
else {
|
| 115 |
$class = 'success';
|
| 116 |
$totalForState = $taxRatesByState["rates_by_state"][$state] . " rates";
|
| 117 |
}
|
|
@@ -119,10 +121,9 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 119 |
}
|
| 120 |
};
|
| 121 |
|
| 122 |
-
if (
|
| 123 |
$matches = 'error';
|
| 124 |
-
}
|
| 125 |
-
else {
|
| 126 |
$matches = 'success';
|
| 127 |
}
|
| 128 |
|
|
@@ -130,6 +131,4 @@ class Taxjar_SalesTax_Model_Comment {
|
|
| 130 |
|
| 131 |
return $statesHtml;
|
| 132 |
}
|
| 133 |
-
|
| 134 |
}
|
| 135 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar Extension UI
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Comment
|
| 8 |
+
{
|
| 9 |
/**
|
| 10 |
* Display Nexus states loaded and API Key setting
|
| 11 |
*
|
| 12 |
* @param void
|
| 13 |
* @return $string
|
| 14 |
*/
|
| 15 |
+
public function getCommentText()
|
| 16 |
+
{
|
| 17 |
+
$regionId = Mage::getStoreConfig('shipping/origin/region_id');
|
| 18 |
+
$regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
|
| 19 |
+
$lastUpdate = Mage::getStoreConfig('taxjar/config/last_update');
|
| 20 |
+
|
| 21 |
+
if (!empty($lastUpdate)) {
|
| 22 |
+
$states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
|
| 23 |
+
$statesHtml = $this->buildStatesHtml($states, $regionCode);
|
| 24 |
+
return $this->buildInstalledHtml($statesHtml, $lastUpdate);
|
| 25 |
+
} else {
|
| 26 |
+
return $this->buildNotYetInstalledHtml($this->fullStateName($regionCode));
|
| 27 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
| 29 |
|
| 30 |
/**
|
| 33 |
* @param void
|
| 34 |
* @return $array
|
| 35 |
*/
|
| 36 |
+
private function getNumberOfRatesLoaded($states)
|
| 37 |
+
{
|
| 38 |
$rates = Mage::getModel("tax/calculation_rate");
|
| 39 |
$stateRatesLoadedCount = 0;
|
| 40 |
$ratesByState = array();
|
| 41 |
+
|
| 42 |
+
foreach (array_unique($states) as $state) {
|
| 43 |
$regionModel = Mage::getModel('directory/region')->loadByCode($state, 'US');
|
| 44 |
$regionId = $regionModel->getId();
|
| 45 |
+
$ratesByState[$state] = $rates->getCollection()->addFieldToFilter('tax_region_id', array('eq' => $regionId))->getSize();
|
| 46 |
}
|
| 47 |
|
| 48 |
$rateCalcs = array(
|
| 49 |
"total_rates" => array_sum($ratesByState),
|
| 50 |
+
"rates_loaded" => Mage::getModel('taxjar/rate')->getExistingRates()->getSize(),
|
| 51 |
"rates_by_state" => $ratesByState
|
| 52 |
);
|
| 53 |
|
| 60 |
* @param $string
|
| 61 |
* @return $string
|
| 62 |
*/
|
| 63 |
+
private function fullStateName($stateCode)
|
| 64 |
+
{
|
| 65 |
+
$regionModel = Mage::getModel('directory/region')->loadByCode($stateCode, 'US');
|
| 66 |
return $regionModel->getDefaultName();
|
| 67 |
}
|
| 68 |
|
| 72 |
* @param $string, $string
|
| 73 |
* @return $string
|
| 74 |
*/
|
| 75 |
+
private function buildInstalledHtml($statesHtml, $lastUpdate)
|
| 76 |
+
{
|
| 77 |
$htmlString = "<p class='note'><span>TaxJar is installed. Check the <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/tax_rule/index') . "'>Manage Tax Rules section</a> to verify all installed states.</span></p><br/><p>TaxJar has <em>automatically</em> added rates for the following states to your Magento installation:<br/><ul class='messages'>". $statesHtml . "</ul>To manage your TaxJar states <a href='https://app.taxjar.com/account#states' target='_blank'>click here</a>.</p><p>Your sales tax rates were last updated on: <ul class='messages'><li class='info-msg'><ul><li><span style='font-size: 1.4em;'>" . $lastUpdate . "</span></li></ul></li></ul><small>Rates may be automatically or manually updated again once per month. For more information on how your tax settings are changed, <a href='http://taxjar.com/magento/tax-settings' target='_blank'>click here</a>. Contact <a href='mailto:support@taxjar.com'>support@taxjar.com</a> with the email address registered to your TaxJar account if you need assistance.</small></p><p><small>If you would like to uninstall TaxJar, remove the API Token from the box above, then save the config. This will remove all tax rates in your Magento store. You can then uninstall in the Magento Connect Manager.<small></p><p><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</p>";
|
| 78 |
return $htmlString;
|
| 79 |
}
|
| 84 |
* @param $string
|
| 85 |
* @return $string
|
| 86 |
*/
|
| 87 |
+
private function buildNotYetInstalledHtml($regionName)
|
| 88 |
+
{
|
| 89 |
$htmlString = "<p class='note'><span>Enter your TaxJar API Token</span></p><br/><p>Enter your TaxJar API Token to import current sales tax rates for all zip codes in <b>" . $regionName . "</b>, your state of origin as set in <a href='" . Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit/section/shipping') . "'>Shipping Settings</a>. We will also retrieve all other states from your TaxJar account. To get an API Token, go to <a href='https://app.taxjar.com/account' target='_blank'>TaxJar's Account Screen.</a></p><p>For more information on how your tax settings are changed, <a href='http://taxjar.com/magento/tax-settings' target='_blank'>click here</a>.</p><p><small><strong>Important Notice</strong>: Your API key may be used to install rates on only <em>one</em> Magento installation at a time.</small></p>";
|
| 90 |
return $htmlString;
|
| 91 |
}
|
| 96 |
* @param $string, $string
|
| 97 |
* @return $string
|
| 98 |
*/
|
| 99 |
+
private function buildStatesHtml($states, $regionCode)
|
| 100 |
+
{
|
| 101 |
$states[] = $regionCode;
|
| 102 |
$statesHtml = '';
|
| 103 |
|
| 104 |
+
sort($states);
|
| 105 |
|
| 106 |
+
$taxRatesByState = $this->getNumberOfRatesLoaded($states);
|
| 107 |
|
| 108 |
+
foreach (array_unique($states) as $state) {
|
| 109 |
+
if (($stateName = $this->fullStateName($state)) && !empty($stateName)) {
|
| 110 |
+
if ($taxRatesByState["rates_by_state"][$state] == 1 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
|
| 111 |
$totalForState = 'Origin-based rates set';
|
| 112 |
$class = 'success';
|
| 113 |
+
} elseif ($taxRatesByState["rates_by_state"][$state] == 0 && ($taxRatesByState['rates_loaded'] == $taxRatesByState['total_rates'])) {
|
|
|
|
| 114 |
$class = 'error';
|
| 115 |
$totalForState = '<a href="https://app.taxjar.com/account#states" target="_blank">Click here</a> and add a zip code for this state to load rates.';
|
| 116 |
+
} else {
|
|
|
|
| 117 |
$class = 'success';
|
| 118 |
$totalForState = $taxRatesByState["rates_by_state"][$state] . " rates";
|
| 119 |
}
|
| 121 |
}
|
| 122 |
};
|
| 123 |
|
| 124 |
+
if ($taxRatesByState['rates_loaded'] != $taxRatesByState['total_rates']) {
|
| 125 |
$matches = 'error';
|
| 126 |
+
} else {
|
|
|
|
| 127 |
$matches = 'success';
|
| 128 |
}
|
| 129 |
|
| 131 |
|
| 132 |
return $statesHtml;
|
| 133 |
}
|
|
|
|
| 134 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Configuration.php
CHANGED
|
@@ -1,22 +1,22 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar configuration setter
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Configuration
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* Sets shipping taxability in Magento
|
| 12 |
*
|
| 13 |
* @param JSON $string
|
| 14 |
* @return void
|
| 15 |
*/
|
| 16 |
-
public function setShippingTaxability(
|
|
|
|
| 17 |
$taxClass = 0;
|
| 18 |
|
| 19 |
-
if(
|
| 20 |
$taxClass = 4;
|
| 21 |
}
|
| 22 |
|
|
@@ -29,10 +29,11 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 29 |
* @param JSON $string
|
| 30 |
* @return void
|
| 31 |
*/
|
| 32 |
-
public function setTaxBasis(
|
|
|
|
| 33 |
$basis = 'shipping';
|
| 34 |
|
| 35 |
-
if(
|
| 36 |
$basis = 'origin';
|
| 37 |
}
|
| 38 |
|
|
@@ -45,7 +46,8 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 45 |
* @param void
|
| 46 |
* @return void
|
| 47 |
*/
|
| 48 |
-
public function setDisplaySettings()
|
|
|
|
| 49 |
$settings = array(
|
| 50 |
'tax/display/type',
|
| 51 |
'tax/display/shipping',
|
|
@@ -54,10 +56,9 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 54 |
'tax/cart_display/shipping'
|
| 55 |
);
|
| 56 |
|
| 57 |
-
foreach(
|
| 58 |
$this->setConfig($setting, 1);
|
| 59 |
}
|
| 60 |
-
|
| 61 |
}
|
| 62 |
|
| 63 |
/**
|
|
@@ -66,16 +67,16 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 66 |
* @param $string
|
| 67 |
* @return void
|
| 68 |
*/
|
| 69 |
-
public function setApiSettings(
|
| 70 |
-
|
|
|
|
| 71 |
$existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
|
| 72 |
|
| 73 |
-
if(
|
| 74 |
$apiUserId = $this->createApiUser($apiKey);
|
| 75 |
$parentRoleId = $this->createApiRoles($apiUserId);
|
| 76 |
$this->createApiRules($parentRoleId);
|
| 77 |
}
|
| 78 |
-
|
| 79 |
}
|
| 80 |
|
| 81 |
/**
|
|
@@ -84,9 +85,9 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 84 |
* @param void
|
| 85 |
* @return void
|
| 86 |
*/
|
| 87 |
-
private function createApiRules(
|
| 88 |
-
|
| 89 |
-
foreach(
|
| 90 |
$apiRule = Mage::getModel('api/rules');
|
| 91 |
$apiRule->setRoleId($parentRoleId);
|
| 92 |
$apiRule->setResourceId($resource);
|
|
@@ -95,7 +96,7 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 95 |
$apiRule->save();
|
| 96 |
}
|
| 97 |
|
| 98 |
-
foreach(
|
| 99 |
$apiRule = Mage::getModel('api/rules');
|
| 100 |
$apiRule->setRoleId($parentRoleId);
|
| 101 |
$apiRule->setResourceId($resource);
|
|
@@ -103,7 +104,6 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 103 |
$apiRule->setApiPermission('deny');
|
| 104 |
$apiRule->save();
|
| 105 |
}
|
| 106 |
-
|
| 107 |
}
|
| 108 |
|
| 109 |
/**
|
|
@@ -112,7 +112,8 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 112 |
* @param $integer
|
| 113 |
* @return $integer
|
| 114 |
*/
|
| 115 |
-
private function createApiRoles(
|
|
|
|
| 116 |
$parentApiRole = Mage::getModel('api/role');
|
| 117 |
$parentApiRole->setRoleName('taxjar_api');
|
| 118 |
$parentApiRole->setTreeLevel(1);
|
|
@@ -137,7 +138,8 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 137 |
* @param void
|
| 138 |
* @return void
|
| 139 |
*/
|
| 140 |
-
private function createApiUser(
|
|
|
|
| 141 |
$apiUser = Mage::getModel('api/user');
|
| 142 |
$apiUser->setUsername('taxjar');
|
| 143 |
$apiUser->setFirstname('TaxJar');
|
|
@@ -156,9 +158,9 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 156 |
* @param $string, $mixed
|
| 157 |
* @return void
|
| 158 |
*/
|
| 159 |
-
private function setConfig(
|
| 160 |
-
|
| 161 |
-
|
| 162 |
}
|
| 163 |
|
| 164 |
/**
|
|
@@ -167,7 +169,8 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 167 |
* @param void
|
| 168 |
* @return $array
|
| 169 |
*/
|
| 170 |
-
private function resourcesToAllow()
|
|
|
|
| 171 |
return array(
|
| 172 |
'sales',
|
| 173 |
'sales/order',
|
|
@@ -201,7 +204,8 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 201 |
* @param void
|
| 202 |
* @return $array
|
| 203 |
*/
|
| 204 |
-
private function resourcesToDeny()
|
|
|
|
| 205 |
return array(
|
| 206 |
'core',
|
| 207 |
'core/store',
|
|
@@ -326,6 +330,4 @@ class Taxjar_SalesTax_Model_Configuration {
|
|
| 326 |
'all'
|
| 327 |
);
|
| 328 |
}
|
| 329 |
-
|
| 330 |
}
|
| 331 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar configuration setter
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Configuration
|
| 8 |
+
{
|
| 9 |
/**
|
| 10 |
* Sets shipping taxability in Magento
|
| 11 |
*
|
| 12 |
* @param JSON $string
|
| 13 |
* @return void
|
| 14 |
*/
|
| 15 |
+
public function setShippingTaxability($configJson)
|
| 16 |
+
{
|
| 17 |
$taxClass = 0;
|
| 18 |
|
| 19 |
+
if ($configJson['freight_taxable']) {
|
| 20 |
$taxClass = 4;
|
| 21 |
}
|
| 22 |
|
| 29 |
* @param JSON $string
|
| 30 |
* @return void
|
| 31 |
*/
|
| 32 |
+
public function setTaxBasis($configJson)
|
| 33 |
+
{
|
| 34 |
$basis = 'shipping';
|
| 35 |
|
| 36 |
+
if ($configJson['tax_source'] === 'origin') {
|
| 37 |
$basis = 'origin';
|
| 38 |
}
|
| 39 |
|
| 46 |
* @param void
|
| 47 |
* @return void
|
| 48 |
*/
|
| 49 |
+
public function setDisplaySettings()
|
| 50 |
+
{
|
| 51 |
$settings = array(
|
| 52 |
'tax/display/type',
|
| 53 |
'tax/display/shipping',
|
| 56 |
'tax/cart_display/shipping'
|
| 57 |
);
|
| 58 |
|
| 59 |
+
foreach ($settings as $setting) {
|
| 60 |
$this->setConfig($setting, 1);
|
| 61 |
}
|
|
|
|
| 62 |
}
|
| 63 |
|
| 64 |
/**
|
| 67 |
* @param $string
|
| 68 |
* @return void
|
| 69 |
*/
|
| 70 |
+
public function setApiSettings($apiKey)
|
| 71 |
+
{
|
| 72 |
+
$apiUser = Mage::getModel('api/user');
|
| 73 |
$existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
|
| 74 |
|
| 75 |
+
if (!$existingUserId) {
|
| 76 |
$apiUserId = $this->createApiUser($apiKey);
|
| 77 |
$parentRoleId = $this->createApiRoles($apiUserId);
|
| 78 |
$this->createApiRules($parentRoleId);
|
| 79 |
}
|
|
|
|
| 80 |
}
|
| 81 |
|
| 82 |
/**
|
| 85 |
* @param void
|
| 86 |
* @return void
|
| 87 |
*/
|
| 88 |
+
private function createApiRules($parentRoleId)
|
| 89 |
+
{
|
| 90 |
+
foreach ($this->resourcesToAllow() as $resource) {
|
| 91 |
$apiRule = Mage::getModel('api/rules');
|
| 92 |
$apiRule->setRoleId($parentRoleId);
|
| 93 |
$apiRule->setResourceId($resource);
|
| 96 |
$apiRule->save();
|
| 97 |
}
|
| 98 |
|
| 99 |
+
foreach ($this->resourcesToDeny() as $resource) {
|
| 100 |
$apiRule = Mage::getModel('api/rules');
|
| 101 |
$apiRule->setRoleId($parentRoleId);
|
| 102 |
$apiRule->setResourceId($resource);
|
| 104 |
$apiRule->setApiPermission('deny');
|
| 105 |
$apiRule->save();
|
| 106 |
}
|
|
|
|
| 107 |
}
|
| 108 |
|
| 109 |
/**
|
| 112 |
* @param $integer
|
| 113 |
* @return $integer
|
| 114 |
*/
|
| 115 |
+
private function createApiRoles($apiUserId)
|
| 116 |
+
{
|
| 117 |
$parentApiRole = Mage::getModel('api/role');
|
| 118 |
$parentApiRole->setRoleName('taxjar_api');
|
| 119 |
$parentApiRole->setTreeLevel(1);
|
| 138 |
* @param void
|
| 139 |
* @return void
|
| 140 |
*/
|
| 141 |
+
private function createApiUser($apiKey)
|
| 142 |
+
{
|
| 143 |
$apiUser = Mage::getModel('api/user');
|
| 144 |
$apiUser->setUsername('taxjar');
|
| 145 |
$apiUser->setFirstname('TaxJar');
|
| 158 |
* @param $string, $mixed
|
| 159 |
* @return void
|
| 160 |
*/
|
| 161 |
+
private function setConfig($path, $value)
|
| 162 |
+
{
|
| 163 |
+
Mage::getConfig()->saveConfig($path, $value, 'default', 0);
|
| 164 |
}
|
| 165 |
|
| 166 |
/**
|
| 169 |
* @param void
|
| 170 |
* @return $array
|
| 171 |
*/
|
| 172 |
+
private function resourcesToAllow()
|
| 173 |
+
{
|
| 174 |
return array(
|
| 175 |
'sales',
|
| 176 |
'sales/order',
|
| 204 |
* @param void
|
| 205 |
* @return $array
|
| 206 |
*/
|
| 207 |
+
private function resourcesToDeny()
|
| 208 |
+
{
|
| 209 |
return array(
|
| 210 |
'core',
|
| 211 |
'core/store',
|
| 330 |
'all'
|
| 331 |
);
|
| 332 |
}
|
|
|
|
| 333 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Debug.php
CHANGED
|
@@ -1,25 +1,23 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar Debug UI
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
class Taxjar_SalesTax_Model_Debug {
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* Display debug information
|
| 12 |
*
|
| 13 |
* @param void
|
| 14 |
* @return $string
|
| 15 |
*/
|
| 16 |
-
public function getCommentText()
|
|
|
|
| 17 |
$debug = Mage::getStoreConfig('taxjar/config/debug');
|
| 18 |
|
| 19 |
-
if (
|
| 20 |
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();
|
| 21 |
-
}
|
| 22 |
-
else {
|
| 23 |
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>";
|
| 24 |
}
|
| 25 |
}
|
|
@@ -30,17 +28,16 @@ class Taxjar_SalesTax_Model_Debug {
|
|
| 30 |
* @param void
|
| 31 |
* @return $string
|
| 32 |
*/
|
| 33 |
-
private function getDebugHtmlString()
|
| 34 |
-
|
|
|
|
| 35 |
$apiUser = Mage::getModel('api/user');
|
| 36 |
$existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
|
| 37 |
-
$pluginVersion = '1.
|
| 38 |
$phpMemory = @ini_get('memory_limit');
|
| 39 |
$phpVersion = @phpversion();
|
| 40 |
$magentoVersion = Mage::getVersion();
|
| 41 |
$lastUpdated = Mage::getStoreConfig('taxjar/config/last_update');
|
| 42 |
return "<ul> <li><strong>Additonal States:</strong> ". $states ."</li> <li><strong>API User ID:</strong> ". $existingUserId ."</li><li><strong>Memory:</strong> ". $phpMemory ."</li> <li><strong>TaxJar Version:</strong> ". $pluginVersion ."</li> <li><strong>PHP Version</strong> ". $phpVersion ."</li> <li><strong>Magento Version:</strong> ". $magentoVersion ."</li> <li><strong>Last Updated:</strong> ". $lastUpdated ."</li> </ul><br/><p><small><strong>Include the above information when emailing TaxJar support at support@taxjar.com</strong><small></p>";
|
| 43 |
}
|
| 44 |
-
|
| 45 |
}
|
| 46 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar Debug UI
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
class Taxjar_SalesTax_Model_Debug {
|
|
|
|
| 8 |
/**
|
| 9 |
* Display debug information
|
| 10 |
*
|
| 11 |
* @param void
|
| 12 |
* @return $string
|
| 13 |
*/
|
| 14 |
+
public function getCommentText()
|
| 15 |
+
{
|
| 16 |
$debug = Mage::getStoreConfig('taxjar/config/debug');
|
| 17 |
|
| 18 |
+
if ($debug) {
|
| 19 |
return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p><br/>" . $this->getDebugHtmlString();
|
| 20 |
+
} else {
|
|
|
|
| 21 |
return "<p class='note'><span>If enabled, does not alter your tax rates or database and instead prints debug messages for use with TaxJar support.</span></p>";
|
| 22 |
}
|
| 23 |
}
|
| 28 |
* @param void
|
| 29 |
* @return $string
|
| 30 |
*/
|
| 31 |
+
private function getDebugHtmlString()
|
| 32 |
+
{
|
| 33 |
+
$states = implode(',', unserialize(Mage::getStoreConfig('taxjar/config/states')));
|
| 34 |
$apiUser = Mage::getModel('api/user');
|
| 35 |
$existingUserId = $apiUser->load('taxjar', 'username')->getUserId();
|
| 36 |
+
$pluginVersion = '1.5.0';
|
| 37 |
$phpMemory = @ini_get('memory_limit');
|
| 38 |
$phpVersion = @phpversion();
|
| 39 |
$magentoVersion = Mage::getVersion();
|
| 40 |
$lastUpdated = Mage::getStoreConfig('taxjar/config/last_update');
|
| 41 |
return "<ul> <li><strong>Additonal States:</strong> ". $states ."</li> <li><strong>API User ID:</strong> ". $existingUserId ."</li><li><strong>Memory:</strong> ". $phpMemory ."</li> <li><strong>TaxJar Version:</strong> ". $pluginVersion ."</li> <li><strong>PHP Version</strong> ". $phpVersion ."</li> <li><strong>Magento Version:</strong> ". $magentoVersion ."</li> <li><strong>Last Updated:</strong> ". $lastUpdated ."</li> </ul><br/><p><small><strong>Include the above information when emailing TaxJar support at support@taxjar.com</strong><small></p>";
|
| 42 |
}
|
|
|
|
| 43 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Observer.php
CHANGED
|
@@ -1,79 +1,74 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* TaxJar Observer.
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Observer
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* TaxJar observer
|
| 12 |
*
|
| 13 |
* @param Varien_Event_Observer $observer
|
| 14 |
* @return void
|
| 15 |
*/
|
| 16 |
-
public function execute(
|
| 17 |
-
|
|
|
|
| 18 |
$apiKey = Mage::getStoreConfig('taxjar/config/apikey');
|
| 19 |
-
$apiKey = preg_replace(
|
| 20 |
|
| 21 |
-
if (
|
| 22 |
$this->version = 'v2';
|
| 23 |
$client = Mage::getModel('taxjar/client');
|
| 24 |
$configuration = Mage::getModel('taxjar/configuration');
|
| 25 |
$regionId = Mage::getStoreConfig('shipping/origin/region_id');
|
| 26 |
$this->storeZip = Mage::getStoreConfig('shipping/origin/postcode');
|
| 27 |
-
$this->regionCode = Mage::getModel('directory/region')->load(
|
| 28 |
-
$validZip = preg_match(
|
| 29 |
$debug = Mage::getStoreConfig('taxjar/config/debug');
|
| 30 |
|
| 31 |
-
if(
|
| 32 |
-
$configJson = $client->getResource(
|
| 33 |
$configJson = $configJson['configuration'];
|
| 34 |
-
}
|
| 35 |
-
else {
|
| 36 |
Mage::throwException("Please check that you have set a Region/State in Shipping Settings.");
|
| 37 |
}
|
| 38 |
|
| 39 |
-
if (
|
| 40 |
Mage::getSingleton('core/session')->addNotice("Debug mode enabled. Tax rates have not been altered.");
|
| 41 |
return;
|
| 42 |
}
|
| 43 |
|
| 44 |
-
if(
|
| 45 |
$dateUpdated = Mage::getStoreConfig('taxjar/config/last_update');
|
| 46 |
Mage::getSingleton('core/session')->addNotice("Your last rate update was too recent. Please wait at least 5 minutes and try again.");
|
| 47 |
return;
|
| 48 |
}
|
| 49 |
|
| 50 |
-
if(
|
| 51 |
-
$ratesJson = $client->getResource(
|
| 52 |
-
}
|
| 53 |
-
else {
|
| 54 |
Mage::throwException("Please check that your zip code is a valid US zip code in Shipping Settings.");
|
| 55 |
}
|
| 56 |
|
| 57 |
Mage::getModel('core/config')
|
| 58 |
-
->saveConfig('taxjar/config/states', serialize(
|
| 59 |
$configuration->setTaxBasis($configJson);
|
| 60 |
$configuration->setShippingTaxability($configJson);
|
| 61 |
$configuration->setDisplaySettings();
|
| 62 |
$configuration->setApiSettings($apiKey);
|
| 63 |
Mage::getModel('core/config')
|
| 64 |
-
->saveConfig(
|
| 65 |
$this->purgeExisting();
|
| 66 |
|
| 67 |
-
if (
|
| 68 |
Mage::dispatchEvent('taxjar_salestax_import_rates');
|
| 69 |
-
}
|
| 70 |
-
else {
|
| 71 |
// We need to be able to store the file...
|
| 72 |
Mage::throwException("Could not write to your Magento temp directory. Please check permissions for " . Mage::getBaseDir('tmp') . ".");
|
| 73 |
}
|
| 74 |
-
|
| 75 |
-
}
|
| 76 |
-
else {
|
| 77 |
Mage::getSingleton('core/session')->addNotice("TaxJar has been uninstalled. All tax rates have been removed.");
|
| 78 |
$this->purgeExisting();
|
| 79 |
$this->setLastUpdateDate(NULL);
|
|
@@ -88,10 +83,11 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 88 |
* @param void
|
| 89 |
* @return void
|
| 90 |
*/
|
| 91 |
-
public function importRates()
|
|
|
|
| 92 |
// This process can take a while
|
| 93 |
-
@set_time_limit(
|
| 94 |
-
@ignore_user_abort(
|
| 95 |
|
| 96 |
$this->newRates = array();
|
| 97 |
$this->freightTaxableRates = array();
|
|
@@ -99,29 +95,29 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 99 |
$filename = $this->getTempFileName();
|
| 100 |
$rule = Mage::getModel('taxjar/rule');
|
| 101 |
$shippingTaxable = Mage::getStoreConfig('taxjar/config/freight_taxable');
|
| 102 |
-
$ratesJson = unserialize(
|
| 103 |
|
| 104 |
-
foreach(
|
| 105 |
-
$rateIdWithShippingId = $rate->create(
|
| 106 |
|
| 107 |
-
if (
|
| 108 |
$this->newRates[] = $rateIdWithShippingId[0];
|
| 109 |
}
|
| 110 |
|
| 111 |
-
if (
|
| 112 |
$this->freightTaxableRates[] = $rateIdWithShippingId[1];
|
| 113 |
}
|
| 114 |
}
|
| 115 |
|
| 116 |
-
$this->setLastUpdateDate(
|
| 117 |
-
$rule->create(
|
| 118 |
|
| 119 |
-
if (
|
| 120 |
-
$rule->create(
|
| 121 |
}
|
| 122 |
|
| 123 |
-
@unlink(
|
| 124 |
-
Mage::getSingleton('core/session')->addSuccess(
|
| 125 |
Mage::dispatchEvent('taxjar_salestax_import_rates_after');
|
| 126 |
}
|
| 127 |
|
|
@@ -131,14 +127,14 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 131 |
* @param $string
|
| 132 |
* @return $string
|
| 133 |
*/
|
| 134 |
-
private function apiUrl(
|
|
|
|
| 135 |
$apiHost = 'https://api.taxjar.com/';
|
| 136 |
$prefix = $apiHost . $this->version . '/plugins/magento/';
|
| 137 |
|
| 138 |
-
if (
|
| 139 |
return $prefix . 'configuration/' . $this->regionCode;
|
| 140 |
-
}
|
| 141 |
-
elseif ( $type == 'rates' ) {
|
| 142 |
return $prefix . 'rates/' . $this->regionCode . '/' . $this->storeZip;
|
| 143 |
}
|
| 144 |
}
|
|
@@ -149,19 +145,22 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 149 |
* @param void
|
| 150 |
* @return void
|
| 151 |
*/
|
| 152 |
-
private function purgeExisting()
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
foreach( $paths as $path ) {
|
| 156 |
-
$existingRecords = Mage::getModel($path)->getCollection();
|
| 157 |
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
}
|
| 166 |
}
|
| 167 |
}
|
|
@@ -172,7 +171,8 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 172 |
* @param $string || NULL
|
| 173 |
* @return void
|
| 174 |
*/
|
| 175 |
-
private function setLastUpdateDate(
|
|
|
|
| 176 |
Mage::getModel('core/config')->saveConfig('taxjar/config/last_update', $date);
|
| 177 |
}
|
| 178 |
|
|
@@ -182,9 +182,8 @@ class Taxjar_SalesTax_Model_Observer {
|
|
| 182 |
* @param void
|
| 183 |
* @return $string
|
| 184 |
*/
|
| 185 |
-
private function getTempFileName()
|
|
|
|
| 186 |
return Mage::getBaseDir('tmp') . DS . "tj_tmp.dat";
|
| 187 |
}
|
| 188 |
-
|
| 189 |
}
|
| 190 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* TaxJar Observer.
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Observer
|
| 8 |
+
{
|
| 9 |
/**
|
| 10 |
* TaxJar observer
|
| 11 |
*
|
| 12 |
* @param Varien_Event_Observer $observer
|
| 13 |
* @return void
|
| 14 |
*/
|
| 15 |
+
public function execute($observer)
|
| 16 |
+
{
|
| 17 |
+
$session = Mage::getSingleton('adminhtml/session');
|
| 18 |
$apiKey = Mage::getStoreConfig('taxjar/config/apikey');
|
| 19 |
+
$apiKey = preg_replace('/\s+/', '', $apiKey);
|
| 20 |
|
| 21 |
+
if ($apiKey) {
|
| 22 |
$this->version = 'v2';
|
| 23 |
$client = Mage::getModel('taxjar/client');
|
| 24 |
$configuration = Mage::getModel('taxjar/configuration');
|
| 25 |
$regionId = Mage::getStoreConfig('shipping/origin/region_id');
|
| 26 |
$this->storeZip = Mage::getStoreConfig('shipping/origin/postcode');
|
| 27 |
+
$this->regionCode = Mage::getModel('directory/region')->load($regionId)->getCode();
|
| 28 |
+
$validZip = preg_match("/(\d{5}-\d{4})|(\d{5})/", $this->storeZip);
|
| 29 |
$debug = Mage::getStoreConfig('taxjar/config/debug');
|
| 30 |
|
| 31 |
+
if (isset($this->regionCode)) {
|
| 32 |
+
$configJson = $client->getResource($apiKey, $this->apiUrl('config'));
|
| 33 |
$configJson = $configJson['configuration'];
|
| 34 |
+
} else {
|
|
|
|
| 35 |
Mage::throwException("Please check that you have set a Region/State in Shipping Settings.");
|
| 36 |
}
|
| 37 |
|
| 38 |
+
if ($debug) {
|
| 39 |
Mage::getSingleton('core/session')->addNotice("Debug mode enabled. Tax rates have not been altered.");
|
| 40 |
return;
|
| 41 |
}
|
| 42 |
|
| 43 |
+
if ($configJson['wait_for_rates'] > 0) {
|
| 44 |
$dateUpdated = Mage::getStoreConfig('taxjar/config/last_update');
|
| 45 |
Mage::getSingleton('core/session')->addNotice("Your last rate update was too recent. Please wait at least 5 minutes and try again.");
|
| 46 |
return;
|
| 47 |
}
|
| 48 |
|
| 49 |
+
if ($validZip === 1 && isset($this->storeZip) && trim($this->storeZip) !== '') {
|
| 50 |
+
$ratesJson = $client->getResource($apiKey, $this->apiUrl('rates'));
|
| 51 |
+
} else {
|
|
|
|
| 52 |
Mage::throwException("Please check that your zip code is a valid US zip code in Shipping Settings.");
|
| 53 |
}
|
| 54 |
|
| 55 |
Mage::getModel('core/config')
|
| 56 |
+
->saveConfig('taxjar/config/states', serialize(explode(',', $configJson['states'])));
|
| 57 |
$configuration->setTaxBasis($configJson);
|
| 58 |
$configuration->setShippingTaxability($configJson);
|
| 59 |
$configuration->setDisplaySettings();
|
| 60 |
$configuration->setApiSettings($apiKey);
|
| 61 |
Mage::getModel('core/config')
|
| 62 |
+
->saveConfig('taxjar/config/freight_taxable', $configJson['freight_taxable']);
|
| 63 |
$this->purgeExisting();
|
| 64 |
|
| 65 |
+
if (false !== file_put_contents($this->getTempFileName(), serialize($ratesJson))) {
|
| 66 |
Mage::dispatchEvent('taxjar_salestax_import_rates');
|
| 67 |
+
} else {
|
|
|
|
| 68 |
// We need to be able to store the file...
|
| 69 |
Mage::throwException("Could not write to your Magento temp directory. Please check permissions for " . Mage::getBaseDir('tmp') . ".");
|
| 70 |
}
|
| 71 |
+
} else {
|
|
|
|
|
|
|
| 72 |
Mage::getSingleton('core/session')->addNotice("TaxJar has been uninstalled. All tax rates have been removed.");
|
| 73 |
$this->purgeExisting();
|
| 74 |
$this->setLastUpdateDate(NULL);
|
| 83 |
* @param void
|
| 84 |
* @return void
|
| 85 |
*/
|
| 86 |
+
public function importRates()
|
| 87 |
+
{
|
| 88 |
// This process can take a while
|
| 89 |
+
@set_time_limit(0);
|
| 90 |
+
@ignore_user_abort(true);
|
| 91 |
|
| 92 |
$this->newRates = array();
|
| 93 |
$this->freightTaxableRates = array();
|
| 95 |
$filename = $this->getTempFileName();
|
| 96 |
$rule = Mage::getModel('taxjar/rule');
|
| 97 |
$shippingTaxable = Mage::getStoreConfig('taxjar/config/freight_taxable');
|
| 98 |
+
$ratesJson = unserialize(file_get_contents($filename));
|
| 99 |
|
| 100 |
+
foreach ($ratesJson['rates'] as $rateJson) {
|
| 101 |
+
$rateIdWithShippingId = $rate->create($rateJson);
|
| 102 |
|
| 103 |
+
if ($rateIdWithShippingId[0]) {
|
| 104 |
$this->newRates[] = $rateIdWithShippingId[0];
|
| 105 |
}
|
| 106 |
|
| 107 |
+
if ($rateIdWithShippingId[1]) {
|
| 108 |
$this->freightTaxableRates[] = $rateIdWithShippingId[1];
|
| 109 |
}
|
| 110 |
}
|
| 111 |
|
| 112 |
+
$this->setLastUpdateDate(date('m-d-Y'));
|
| 113 |
+
$rule->create('Retail Customer-Taxable Goods-Rate 1', 2, 1, $this->newRates);
|
| 114 |
|
| 115 |
+
if ($shippingTaxable) {
|
| 116 |
+
$rule->create('Retail Customer-Shipping-Rate 1', 4, 2, $this->freightTaxableRates);
|
| 117 |
}
|
| 118 |
|
| 119 |
+
@unlink($filename);
|
| 120 |
+
Mage::getSingleton('core/session')->addSuccess('TaxJar has added new rates to your database! Thanks for using TaxJar!');
|
| 121 |
Mage::dispatchEvent('taxjar_salestax_import_rates_after');
|
| 122 |
}
|
| 123 |
|
| 127 |
* @param $string
|
| 128 |
* @return $string
|
| 129 |
*/
|
| 130 |
+
private function apiUrl($type)
|
| 131 |
+
{
|
| 132 |
$apiHost = 'https://api.taxjar.com/';
|
| 133 |
$prefix = $apiHost . $this->version . '/plugins/magento/';
|
| 134 |
|
| 135 |
+
if ($type == 'config') {
|
| 136 |
return $prefix . 'configuration/' . $this->regionCode;
|
| 137 |
+
} elseif ($type == 'rates') {
|
|
|
|
| 138 |
return $prefix . 'rates/' . $this->regionCode . '/' . $this->storeZip;
|
| 139 |
}
|
| 140 |
}
|
| 145 |
* @param void
|
| 146 |
* @return void
|
| 147 |
*/
|
| 148 |
+
private function purgeExisting()
|
| 149 |
+
{
|
| 150 |
+
$rates = Mage::getModel('taxjar/rate')->getExistingRates()->load();
|
|
|
|
|
|
|
| 151 |
|
| 152 |
+
foreach ($rates as $rate) {
|
| 153 |
+
try {
|
| 154 |
+
$calculation = Mage::getModel('tax/calculation')->load($rate->getId(), 'tax_calculation_rate_id');
|
| 155 |
+
$calculation->delete();
|
| 156 |
+
} catch (Exception $e) {
|
| 157 |
+
Mage::getSingleton('core/session')->addError("There was an error deleting from Magento model tax/calculation");
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
try {
|
| 161 |
+
$rate->delete();
|
| 162 |
+
} catch (Exception $e) {
|
| 163 |
+
Mage::getSingleton('core/session')->addError("There was an error deleting from Magento model tax/calculation_rate");
|
| 164 |
}
|
| 165 |
}
|
| 166 |
}
|
| 171 |
* @param $string || NULL
|
| 172 |
* @return void
|
| 173 |
*/
|
| 174 |
+
private function setLastUpdateDate($date)
|
| 175 |
+
{
|
| 176 |
Mage::getModel('core/config')->saveConfig('taxjar/config/last_update', $date);
|
| 177 |
}
|
| 178 |
|
| 182 |
* @param void
|
| 183 |
* @return $string
|
| 184 |
*/
|
| 185 |
+
private function getTempFileName()
|
| 186 |
+
{
|
| 187 |
return Mage::getBaseDir('tmp') . DS . "tj_tmp.dat";
|
| 188 |
}
|
|
|
|
| 189 |
}
|
|
|
app/code/community/Taxjar/SalesTax/Model/Rate.php
CHANGED
|
@@ -1,15 +1,15 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* Create and parse rates from JSON obj
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Rate
|
| 9 |
-
|
| 10 |
private $cache;
|
| 11 |
|
| 12 |
-
public function __construct()
|
|
|
|
| 13 |
$this->cache = Mage::getSingleton('core/cache');
|
| 14 |
}
|
| 15 |
|
|
@@ -19,16 +19,16 @@ class Taxjar_SalesTax_Model_Rate {
|
|
| 19 |
* @param JSON $string
|
| 20 |
* @return array
|
| 21 |
*/
|
| 22 |
-
public function create(
|
|
|
|
| 23 |
try {
|
| 24 |
$zip = $rateJson['zip'];
|
| 25 |
$regionCode = $rateJson['state'];
|
| 26 |
$rate = $rateJson['rate'];
|
| 27 |
|
| 28 |
-
if (
|
| 29 |
$countryCode = $rateJson['country'];
|
| 30 |
-
}
|
| 31 |
-
else {
|
| 32 |
$countryCode = 'US';
|
| 33 |
}
|
| 34 |
|
|
@@ -49,21 +49,49 @@ class Taxjar_SalesTax_Model_Rate {
|
|
| 49 |
$rateModel->setRate($rate);
|
| 50 |
$rateModel->save();
|
| 51 |
|
| 52 |
-
if (
|
| 53 |
$shippingRateId = $rateModel->getId();
|
| 54 |
-
}
|
| 55 |
-
else {
|
| 56 |
$shippingRateId = 0;
|
| 57 |
}
|
| 58 |
|
| 59 |
-
return array(
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
unset( $rateModel );
|
| 64 |
return;
|
| 65 |
}
|
| 66 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* Create and parse rates from JSON obj
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Rate
|
| 8 |
+
{
|
| 9 |
private $cache;
|
| 10 |
|
| 11 |
+
public function __construct()
|
| 12 |
+
{
|
| 13 |
$this->cache = Mage::getSingleton('core/cache');
|
| 14 |
}
|
| 15 |
|
| 19 |
* @param JSON $string
|
| 20 |
* @return array
|
| 21 |
*/
|
| 22 |
+
public function create($rateJson)
|
| 23 |
+
{
|
| 24 |
try {
|
| 25 |
$zip = $rateJson['zip'];
|
| 26 |
$regionCode = $rateJson['state'];
|
| 27 |
$rate = $rateJson['rate'];
|
| 28 |
|
| 29 |
+
if (isset($rateJson['country'])) {
|
| 30 |
$countryCode = $rateJson['country'];
|
| 31 |
+
} else {
|
|
|
|
| 32 |
$countryCode = 'US';
|
| 33 |
}
|
| 34 |
|
| 49 |
$rateModel->setRate($rate);
|
| 50 |
$rateModel->save();
|
| 51 |
|
| 52 |
+
if ($rateJson['freight_taxable']) {
|
| 53 |
$shippingRateId = $rateModel->getId();
|
| 54 |
+
} else {
|
|
|
|
| 55 |
$shippingRateId = 0;
|
| 56 |
}
|
| 57 |
|
| 58 |
+
return array($rateModel->getId(), $shippingRateId);
|
| 59 |
+
} catch (Exception $e) {
|
| 60 |
+
Mage::getSingleton('core/session')->addNotice("There was an error encountered while loading rate with code " . $rateModel->getCode() . ". This is most likely due to duplicate codes and can be safely ignored if lots of other rates were loaded. If the error persists, email support@taxjar.com with a screenshot of any Magento errors displayed.");
|
| 61 |
+
unset($rateModel);
|
|
|
|
| 62 |
return;
|
| 63 |
}
|
| 64 |
}
|
| 65 |
+
|
| 66 |
+
/**
|
| 67 |
+
* Get existing TaxJar calculations based on configuration states
|
| 68 |
+
*
|
| 69 |
+
* @param void
|
| 70 |
+
* @return $array
|
| 71 |
+
*/
|
| 72 |
+
public function getExistingRates()
|
| 73 |
+
{
|
| 74 |
+
return Mage::getModel('tax/calculation_rate')
|
| 75 |
+
->getCollection()
|
| 76 |
+
->addFieldToFilter('tax_region_id', $this->getRegionFilter());
|
| 77 |
+
}
|
| 78 |
|
| 79 |
+
/**
|
| 80 |
+
* Get region filter for existing configuration states
|
| 81 |
+
*
|
| 82 |
+
* @param void
|
| 83 |
+
* @return void
|
| 84 |
+
*/
|
| 85 |
+
private function getRegionFilter()
|
| 86 |
+
{
|
| 87 |
+
$states = unserialize(Mage::getStoreConfig('taxjar/config/states'));
|
| 88 |
+
$filter = [];
|
| 89 |
|
| 90 |
+
foreach (array_unique($states) as $state) {
|
| 91 |
+
$regionId = Mage::getModel('directory/region')->loadByCode($state, 'US')->getId();
|
| 92 |
+
$filter[] = array('finset' => array($regionId));
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
return $filter;
|
| 96 |
+
}
|
| 97 |
+
}
|
app/code/community/Taxjar/SalesTax/Model/Rule.php
CHANGED
|
@@ -1,35 +1,40 @@
|
|
| 1 |
<?php
|
| 2 |
-
|
| 3 |
/**
|
| 4 |
* Create tax rules
|
| 5 |
*
|
| 6 |
* @author Taxjar (support@taxjar.com)
|
| 7 |
*/
|
| 8 |
-
class Taxjar_SalesTax_Model_Rule
|
| 9 |
-
|
| 10 |
/**
|
| 11 |
* Display Nexus states loaded and API Key setting
|
| 12 |
*
|
| 13 |
* @param $string, $integer, $integer, $array
|
| 14 |
* @return void
|
| 15 |
*/
|
| 16 |
-
public function create(
|
| 17 |
-
|
| 18 |
-
|
|
|
|
| 19 |
$attributes = array(
|
| 20 |
-
'code' => $code,
|
| 21 |
-
'tax_customer_class' => array(
|
| 22 |
-
'tax_product_class' => array(
|
| 23 |
-
'tax_rate' => $newRates,
|
| 24 |
'priority' => 1,
|
| 25 |
'position' => $position
|
| 26 |
);
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
$ruleModel->save();
|
| 31 |
$ruleModel->saveCalculationData();
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
}
|
| 35 |
-
|
| 1 |
<?php
|
|
|
|
| 2 |
/**
|
| 3 |
* Create tax rules
|
| 4 |
*
|
| 5 |
* @author Taxjar (support@taxjar.com)
|
| 6 |
*/
|
| 7 |
+
class Taxjar_SalesTax_Model_Rule
|
| 8 |
+
{
|
| 9 |
/**
|
| 10 |
* Display Nexus states loaded and API Key setting
|
| 11 |
*
|
| 12 |
* @param $string, $integer, $integer, $array
|
| 13 |
* @return void
|
| 14 |
*/
|
| 15 |
+
public function create($code, $productClass, $position, $newRates)
|
| 16 |
+
{
|
| 17 |
+
$rule = Mage::getModel('tax/calculation_rule')->load($code, 'code');
|
| 18 |
+
|
| 19 |
$attributes = array(
|
| 20 |
+
'code' => $code,
|
| 21 |
+
'tax_customer_class' => array(3),
|
| 22 |
+
'tax_product_class' => array($productClass),
|
|
|
|
| 23 |
'priority' => 1,
|
| 24 |
'position' => $position
|
| 25 |
);
|
| 26 |
+
|
| 27 |
+
if (isset($rule)) {
|
| 28 |
+
$attributes['tax_rate'] = array_merge($rule->getRates(), $newRates);
|
| 29 |
+
$rule->delete();
|
| 30 |
+
} else {
|
| 31 |
+
$attributes['tax_rate'] = $newRates;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
$ruleModel = Mage::getSingleton('tax/calculation_rule');
|
| 35 |
+
$ruleModel->setData($attributes);
|
| 36 |
+
$ruleModel->setCalculateSubtotal(0);
|
| 37 |
$ruleModel->save();
|
| 38 |
$ruleModel->saveCalculationData();
|
| 39 |
+
}
|
|
|
|
| 40 |
}
|
|
|
app/code/community/Taxjar/SalesTax/etc/adminhtml.xml
CHANGED
|
@@ -20,4 +20,4 @@
|
|
| 20 |
</admin>
|
| 21 |
</resources>
|
| 22 |
</acl>
|
| 23 |
-
</config>
|
| 20 |
</admin>
|
| 21 |
</resources>
|
| 22 |
</acl>
|
| 23 |
+
</config>
|
app/code/community/Taxjar/SalesTax/etc/config.xml
CHANGED
|
@@ -6,7 +6,7 @@
|
|
| 6 |
-->
|
| 7 |
<config>
|
| 8 |
<modules>
|
| 9 |
-
<Taxjar_SalesTax><version>1.
|
| 10 |
</modules>
|
| 11 |
<global>
|
| 12 |
<helpers>
|
|
@@ -90,5 +90,4 @@
|
|
| 90 |
</taxjar>
|
| 91 |
</jobs>
|
| 92 |
</crontab>
|
| 93 |
-
|
| 94 |
</config>
|
| 6 |
-->
|
| 7 |
<config>
|
| 8 |
<modules>
|
| 9 |
+
<Taxjar_SalesTax><version>1.5.0</version></Taxjar_SalesTax>
|
| 10 |
</modules>
|
| 11 |
<global>
|
| 12 |
<helpers>
|
| 90 |
</taxjar>
|
| 91 |
</jobs>
|
| 92 |
</crontab>
|
|
|
|
| 93 |
</config>
|
app/code/community/Taxjar/SalesTax/etc/system.xml
CHANGED
|
@@ -53,4 +53,4 @@
|
|
| 53 |
</groups>
|
| 54 |
</taxjar>
|
| 55 |
</sections>
|
| 56 |
-
</config>
|
| 53 |
</groups>
|
| 54 |
</taxjar>
|
| 55 |
</sections>
|
| 56 |
+
</config>
|
app/etc/modules/Taxjar_SalesTax.xml
CHANGED
|
@@ -5,5 +5,5 @@
|
|
| 5 |
<codePool>community</codePool>
|
| 6 |
<depends></depends>
|
| 7 |
</Taxjar_SalesTax>
|
| 8 |
-
</modules>
|
| 9 |
-
</config>
|
| 5 |
<codePool>community</codePool>
|
| 6 |
<depends></depends>
|
| 7 |
</Taxjar_SalesTax>
|
| 8 |
+
</modules>
|
| 9 |
+
</config>
|
package.xml
CHANGED
|
@@ -1,18 +1,20 @@
|
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Taxjar_Salestaxautomation</name>
|
| 4 |
-
<version>1.
|
| 5 |
<stability>stable</stability>
|
| 6 |
<license>MIT</license>
|
| 7 |
<channel>community</channel>
|
| 8 |
<extends/>
|
| 9 |
<summary>Easily collect sales tax without altering your Magento store’s checkout experience or performance.</summary>
|
| 10 |
<description>TaxJar for Magento allows you to install rates for multiple origin or destination-based states without affecting your store's checkout experience.</description>
|
| 11 |
-
<notes>*
|
|
|
|
|
|
|
| 12 |
<authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
|
| 13 |
-
<date>2016-01
|
| 14 |
-
<time>18:
|
| 15 |
-
<contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Helper"><file name="Data.php" hash="
|
| 16 |
<compatible/>
|
| 17 |
<dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies>
|
| 18 |
</package>
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Taxjar_Salestaxautomation</name>
|
| 4 |
+
<version>1.5.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 install rates for multiple origin or destination-based states without affecting your store's checkout experience.</description>
|
| 11 |
+
<notes>* Existing sales tax rates and rules are no longer overwritten.
|
| 12 |
+
* Rates imported from TaxJar are appended to the default rules for taxable goods and shipping.
|
| 13 |
+
* Codebase improved to more closely follow Magento standards.</notes>
|
| 14 |
<authors><author><name>TaxJar</name><user>taxjar</user><email>support@taxjar.com</email></author></authors>
|
| 15 |
+
<date>2016-02-01</date>
|
| 16 |
+
<time>18:40:50</time>
|
| 17 |
+
<contents><target name="magecommunity"><dir name="Taxjar"><dir name="SalesTax"><dir name="Helper"><file name="Data.php" hash="a7b646cb1956bcd5e7375a5de0694281"/></dir><dir name="Model"><file name="Calculation.php" hash="5a99c13b14811a3e621544f74ce8271d"/><file name="Client.php" hash="e5627a4fd74ceebd8b16ed4e5293212d"/><file name="Comment.php" hash="c2a8732728c391c9fbd5aa77eb3a89a3"/><file name="Configuration.php" hash="2bf053b0031587d910354ab52d72fa8c"/><file name="Debug.php" hash="b26f2ccfa32572ef309188f5e92fbbe0"/><file name="Observer.php" hash="a7ee078445f16a8ce006953cbbb83b45"/><file name="Rate.php" hash="8ff3497bf6fb1717439bf36a0e6c0705"/><file name="Rule.php" hash="cf583b79050e6941bdb4f6310cf2d385"/></dir><dir name="etc"><file name="adminhtml.xml" hash="9731dfa9d72fda332d244b5fc107d047"/><file name="config.xml" hash="f108d4d7594edda3672d7c30749229b3"/><file name="system.xml" hash="406ad8c2fc92abcdbed5b5e1d662b8b4"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Taxjar_SalesTax.xml" hash="afb27bfd2c9b05698b4c7bb0659f3432"/></dir></target></contents>
|
| 18 |
<compatible/>
|
| 19 |
<dependencies><required><php><min>5.0.0</min><max>6.0.0</max></php></required></dependencies>
|
| 20 |
</package>
|
