From 6a1f536e3d43f9a1d39e8d14c982147bb4da820b Mon Sep 17 00:00:00 2001 From: Inform-All Date: Wed, 19 Jun 2024 15:10:42 +0200 Subject: [PATCH] Update to 2.1.2 with new override and selection of tax rule --- config.xml | 9 +- override/classes/Product.php | 54 +++++++ override/classes/tax/TaxRulesTaxManager.php | 64 -------- override/classes/tax/index.php | 34 ----- upgrade/upgrade-2.1.0.php | 2 +- upgrade/upgrade-2.1.2.php | 25 ++++ vatchecker.php | 155 ++++++++++++++------ views/templates/admin/create.tpl | 13 ++ 8 files changed, 208 insertions(+), 148 deletions(-) create mode 100644 override/classes/Product.php delete mode 100644 override/classes/tax/TaxRulesTaxManager.php delete mode 100644 override/classes/tax/index.php create mode 100644 upgrade/upgrade-2.1.2.php create mode 100644 views/templates/admin/create.tpl diff --git a/config.xml b/config.xml index 74fbd40..1df6ab9 100644 --- a/config.xml +++ b/config.xml @@ -1,12 +1,11 @@ vatchecker - - - + + + 1 1 - - + \ No newline at end of file diff --git a/override/classes/Product.php b/override/classes/Product.php new file mode 100644 index 0000000..3ec5212 --- /dev/null +++ b/override/classes/Product.php @@ -0,0 +1,54 @@ +cart->id_address_delivery)) + { + $delivery_address = new Address( $context->cart->id_address_delivery ); + }else{ + $delivery_address = false; + } + + $key = 'product_id_tax_rules_group_' . (int) $id_product . '_' . (int) $context->shop->id; + + if ( $delivery_address ) { + /** @var Vatchecker $vatchecker */ + $vatchecker = Module::getInstanceByName( 'vatchecker' ); + if ( $vatchecker && $vatchecker->canOrderWithoutVat( $delivery_address ) ) { + // VatChecker module is used. + $skipProduct = Db::getInstance()->getRow( + 'SELECT `id_product` + FROM `' . _DB_PREFIX_ . 'vatchecker_excluded_products` + WHERE `id_product` =' . (int) $id_product + ); + if ( empty($skipProduct) ) { + $taxRuleGroupId = Configuration::get( 'VATCHECKER_TAXRATE_RULE' ); + if ( ! Cache::isStored( $key ) ) { + Cache::store( $key, (int) $taxRuleGroupId ); + } + + return (int) $taxRuleGroupId; + } + } + } + + if ( ! Cache::isStored( $key ) ) { + $result = Db::getInstance( _PS_USE_SQL_SLAVE_ )->getValue( + ' + SELECT `id_tax_rules_group` + FROM `' . _DB_PREFIX_ . 'product_shop` + WHERE `id_product` = ' . (int) $id_product . ' AND id_shop=' . (int) $context->shop->id + ); + Cache::store( $key, (int) $result ); + + return (int) $result; + } + + return Cache::retrieve( $key ); + } +} diff --git a/override/classes/tax/TaxRulesTaxManager.php b/override/classes/tax/TaxRulesTaxManager.php deleted file mode 100644 index d028cfe..0000000 --- a/override/classes/tax/TaxRulesTaxManager.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -/** - * @inheritDoc - */ -class TaxRulesTaxManager extends TaxRulesTaxManagerCore -{ - /** - * Return the tax calculator associated to this address. - * - * @return TaxCalculator - */ - public function getTaxCalculator() - { - static $tax_enabled = null; - - if ( isset( $this->tax_calculator ) ) { - return $this->tax_calculator; - } - - if ( null === $tax_enabled ) { - $tax_enabled = Configuration::get( 'PS_TAX' ); - } - - if ( $tax_enabled && $this->address ) { - /** @var Vatchecker $vatchecker */ - $vatchecker = Module::getInstanceByName('vatchecker'); - if ( $vatchecker && $vatchecker->canOrderWithoutVat( $this->address ) ) { - // Disable TAX. - $tax_enabled = false; - } - } - - if ( ! $tax_enabled ) { - return new TaxCalculator( array() ); - } - - return parent::getTaxCalculator(); - } -} diff --git a/override/classes/tax/index.php b/override/classes/tax/index.php deleted file mode 100644 index cb2bde5..0000000 --- a/override/classes/tax/index.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2007-2020 PrestaShop SA - * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/upgrade/upgrade-2.1.0.php b/upgrade/upgrade-2.1.0.php index 264265e..b41fdb9 100644 --- a/upgrade/upgrade-2.1.0.php +++ b/upgrade/upgrade-2.1.0.php @@ -4,7 +4,7 @@ } /** - * This function updates your module from previous versions to the version 1.1, + * This function updates your module from previous versions to the version 2.1.0, * usefull when you modify your database, or register a new hook ... * Don't forget to create one file per version. */ diff --git a/upgrade/upgrade-2.1.2.php b/upgrade/upgrade-2.1.2.php new file mode 100644 index 0000000..5254c1e --- /dev/null +++ b/upgrade/upgrade-2.1.2.php @@ -0,0 +1,25 @@ +uninstallOverrides(); + $module->installOverrides(); + Configuration::updateValue('VATCHECKER_TAXRATE_RULE', null ); + $module->registerHook('displayAdminProductsMainStepLeftColumnMiddle'); + $module->registerHook('actionProductUpdate'); + + return Db::getInstance()->Execute( + 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'vatchecker_excluded_products' . '` ( + `id_product` INTEGER UNSIGNED NOT NULL, + PRIMARY KEY(`id_product`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8' + ); +} diff --git a/vatchecker.php b/vatchecker.php index c67e357..cae01fd 100644 --- a/vatchecker.php +++ b/vatchecker.php @@ -94,38 +94,35 @@ public function __construct() { $this->name = 'vatchecker'; $this->tab = 'billing_invoicing'; - $this->version = '2.1.1'; + $this->version = '2.1.2'; $this->author = 'Inform-All & Keraweb'; $this->need_instance = 1; - /** - * Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6) - */ $this->bootstrap = true; parent::__construct(); $this->displayName = $this->l( 'VAT Checker' ); - $this->description = $this->l( 'The module verifies whether a customer possesses a valid VAT EU number through the VIES VAT online service. Upon validation, it automatically applies a 0% tax rate to customers from the EU who are not from the same country as the shop.' ); - + $this->description = $this->l( + 'The module verifies whether a customer possesses a valid VAT EU number through the VIES VAT online service. Upon validation, it automatically applies a 0% tax rate to customers from the EU who are not from the same country as the shop.' + ); $this->ps_versions_compliancy = [ 'min' => '1.7', 'max' => _PS_VERSION_ ]; } - /** - * Don't forget to create update methods if needed: - * http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update - */ public function install() { Configuration::updateValue( 'VATCHECKER_LIVE_MODE', true ); Configuration::updateValue( 'VATCHECKER_ALLOW_OFFLINE', true ); Configuration::updateValue( 'VATCHECKER_CUSTOMER_GROUP', false ); - Configuration::updateValue('VATCHECKER_EU_COUNTRIES', null ); - Configuration::updateValue('VATCHECKER_ORIGIN_COUNTRY', null ); + Configuration::updateValue( 'VATCHECKER_EU_COUNTRIES', null ); + Configuration::updateValue( 'VATCHECKER_ORIGIN_COUNTRY', null ); + Configuration::updateValue( 'VATCHECKER_TAXRATE_RULE', null ); return parent::install() && $this->installDB() + && $this->registerHook( 'displayAdminProductsExtra' ) + && $this->registerHook( 'actionProductUpdate' ) && $this->registerHook( 'displayHeader' ) && $this->registerHook( 'displayBeforeBodyClosingTag' ) && $this->registerHook( 'actionValidateCustomerAddressForm' ); @@ -150,7 +147,16 @@ public function installDB() PRIMARY KEY(`id_vatchecker`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8'; - return Db::getInstance()->execute( $sql ); + if ( ! Db::getInstance()->execute( $sql ) ) { + return false; + } + + $sql2 = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'vatchecker_excluded_products' . '` ( + `id_product` INTEGER UNSIGNED NOT NULL, + PRIMARY KEY(`id_product`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8'; + + return Db::getInstance()->execute( $sql2 ); } public function uninstall() @@ -244,6 +250,7 @@ protected function getConfigFormValues() 'VATCHECKER_LIVE_MODE' => Configuration::get( 'VATCHECKER_LIVE_MODE', null, null, null, true ), 'VATCHECKER_ALLOW_OFFLINE' => Configuration::get( 'VATCHECKER_ALLOW_OFFLINE', null, null, null, true ), 'VATCHECKER_ORIGIN_COUNTRY' => Configuration::get( 'VATCHECKER_ORIGIN_COUNTRY', null, null, null, '0' ), + 'VATCHECKER_TAXRATE_RULE' => Configuration::get( 'VATCHECKER_TAXRATE_RULE', null, null, null, '0' ), 'VATCHECKER_CUSTOMER_GROUP' => Configuration::get( 'VATCHECKER_CUSTOMER_GROUP', null, null, null, false ), ]; @@ -337,32 +344,36 @@ protected function getConfigForm() ], ], [ - 'type' => 'radio', - 'label' => $this->l( 'Offline validation' ), - 'name' => 'VATCHECKER_ALLOW_OFFLINE', + 'type' => 'radio', + 'label' => $this->l( 'Offline validation' ), + 'name' => 'VATCHECKER_ALLOW_OFFLINE', 'required' => false, - 'desc' => $this->l( 'What should be done when the VIES VAT service is offline?' ), - 'values' => [ + 'desc' => $this->l( 'What should be done when the VIES VAT service is offline?' ), + 'values' => [ [ - 'id' => 'invalid', + 'id' => 'invalid', 'value' => 0, - 'label' => $this->l('Always mark VAT as invalid') + 'label' => $this->l( 'Always mark VAT as invalid' ), ], [ - 'id' => 'valid', + 'id' => 'valid', 'value' => 1, - 'label' => $this->l('Always mark VAT as valid') + 'label' => $this->l( 'Always mark VAT as valid' ), ], [ - 'id' => 'exists_invalid', + 'id' => 'exists_invalid', 'value' => 2, - 'label' => $this->l('Use previous validation value, if not previously validated mark VAT as invalid') + 'label' => $this->l( + 'Use previous validation value, if not previously validated mark VAT as invalid' + ), ], [ - 'id' => 'exists_valid', + 'id' => 'exists_valid', 'value' => 3, - 'label' => $this->l('Use previous validation value, if not previously validated mark VAT as valid') - ] + 'label' => $this->l( + 'Use previous validation value, if not previously validated mark VAT as valid' + ), + ], ], ], [ @@ -394,7 +405,9 @@ protected function getConfigForm() [ 'type' => 'select', 'label' => $this->l( 'Business customer group' ), - 'desc' => $this->l( 'If a customer has a validated VAT EU number, assign them to the selected group. (OPTIONAL)' ), + 'desc' => $this->l( + 'If a customer has a validated VAT EU number, assign them to the selected group. (OPTIONAL)' + ), 'name' => 'VATCHECKER_CUSTOMER_GROUP', 'required' => true, 'options' => [ @@ -404,7 +417,18 @@ protected function getConfigForm() ], 'data' => 'Disabled', ], - + [ + 'col' => 3, + 'type' => 'select', + 'desc' => $this->l( 'Go to International > Taxes and create a new rule with 0% tax' ), + 'name' => 'VATCHECKER_TAXRATE_RULE', + 'label' => $this->l( 'Your 0% tax rate rule' ), + 'options' => [ + 'query' => TaxRulesGroup::getTaxRulesGroups(), + 'id' => 'id_tax_rules_group', + 'name' => 'name', + ], + ], ], 'submit' => [ 'title' => $this->l( 'Save' ), @@ -649,11 +673,7 @@ private function setVatValidation( $record ) $table = _DB_PREFIX_ . 'vatchecker'; // Required fields. - if ( - empty( $record['id_address'] ) || - empty( $record['id_country'] ) || - empty( $record['vat_number'] ) - ) { + if ( empty( $record['id_address'] ) || empty( $record['id_country'] ) || empty( $record['vat_number'] ) ) { return false; } @@ -828,9 +848,12 @@ protected function checkVies( $countryCode, $vatNumber ) //$return['error'] = $this->l( $e->getMessage() ); $return['error'] = $this->l( 'EU VIES server not responding' ); - $return['valid'] = $this->VIESOfflineLogicHander($params); + $return['valid'] = $this->VIESOfflineLogicHander( $params ); - PrestaShopLogger::addLog( 'VAT check failed! (params: ' . implode( ', ', $params ) . ' , error: ' . $e->getMessage() . ')', ERROR_SEVERITY ); + PrestaShopLogger::addLog( + 'VAT check failed! (params: ' . implode( ', ', $params ) . ' , error: ' . $e->getMessage() . ')', + ERROR_SEVERITY + ); } $cache[ $cache_key ] = $return; @@ -838,19 +861,22 @@ protected function checkVies( $countryCode, $vatNumber ) return $return; } - public function VIESOfflineLogicHander($params) + public function VIESOfflineLogicHander( $params ) { switch ( Configuration::get( 'VATCHECKER_ALLOW_OFFLINE' ) ) { case 1: case true: return true; case 2: - $previous = $this->getPreviousValidation($params); - return (!empty($previous)) ? $previous->valid : false; + $previous = $this->getPreviousValidation( $params ); + + return ( ! empty( $previous ) ) ? $previous->valid : false; case 3: - $previous = $this->getPreviousValidation($params); - return (!empty($previous)) ? $previous->valid : true; + $previous = $this->getPreviousValidation( $params ); + + return ( ! empty( $previous ) ) ? $previous->valid : true; } + return false; } @@ -865,7 +891,7 @@ public function VIESOfflineLogicHander($params) */ private function getPreviousValidation( $params ) { - $table = _DB_PREFIX_ . 'vatchecker'; + $table = _DB_PREFIX_ . 'vatchecker'; $countryId = Country::getByIso( $params['countryCode'] ); $sql = "SELECT * FROM {$table} @@ -942,8 +968,8 @@ public function isEUCountry( $countryCode ) { $key = 'iso_code'; if ( is_numeric( $countryCode ) ) { - $countryCode = intval($countryCode); - $key = 'id_country'; + $countryCode = intval( $countryCode ); + $key = 'id_country'; } foreach ( $this->getEUCountries() as $country ) { if ( $country[ $key ] === $countryCode ) { @@ -1072,4 +1098,45 @@ public function getAddress( $address ) return null; } + + public function hookDisplayAdminProductsExtra( array $params ): string + { + $id = $params['id_product']; + + $result = Db::getInstance()->getRow( + 'SELECT `id_product` + FROM `' . _DB_PREFIX_ . 'vatchecker_excluded_products` + WHERE `id_product` =' . (int) $id + ); + + if ( $result ) { + $skip = true; + } else { + $skip = false; + } + + $this->context->smarty->assign( 'vatcheckerExclude', $skip ); + + return $this->display( __FILE__, 'views/templates/admin/create.tpl' ); + } + + public function hookActionProductUpdate( array $params ) + { + $product_id = $params['id_product']; + $newValue = Tools::getValue( 'vatchecker_exclude' ); + + if ($newValue === false ) { + return Db::getInstance()->delete( 'vatchecker_excluded_products', 'id_product = ' . (int) $product_id ); + } else { + return Db::getInstance()->insert( + 'vatchecker_excluded_products', + [ + 'id_product' => (int) $product_id, + ], + false, + true, + Db::INSERT_IGNORE + ); + } + } } diff --git a/views/templates/admin/create.tpl b/views/templates/admin/create.tpl new file mode 100644 index 0000000..f5e02df --- /dev/null +++ b/views/templates/admin/create.tpl @@ -0,0 +1,13 @@ +
+
+
+
+
+

{l s='Exclude 0% tax' mod='vatchecker'}

+

{l s='This selection allows you to always force VAT on this product even if a customer has a valid VAT number.' mod='vatchecker'}

+ +
+
+
+
+