From 5aaf9cd56553ecc04288fe77e07f0f6920c6fa45 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 18 Nov 2025 16:57:50 +0100 Subject: [PATCH] NEW Add hook on calcula_price() and get_default_tva() --- htdocs/core/lib/company.lib.php | 12 +++++-- htdocs/core/lib/functions.lib.php | 59 +++++++++++++++++++++---------- htdocs/core/lib/price.lib.php | 27 +++++++++----- htdocs/projet/agenda.php | 14 ++++---- htdocs/projet/messaging.php | 15 ++++---- test/phpunit/FunctionsLibTest.php | 18 +++++++++- 6 files changed, 99 insertions(+), 46 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 5c4498f8a5f..cfe83b82b7e 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -2153,6 +2153,9 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; + } if ($obj->type == 'action') { $contactaction = new ActionComm($db); @@ -2300,7 +2303,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr $out .= ''; $out .= ''; $out .= ''; - $out .= ''; + // Status + $out .= ''; + $out .= ''; + $out .= ''; // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { $out .= ''; @@ -2537,7 +2543,9 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = null, $nopr } // Status / Progression - $out .= '' . $actionstatic->LibStatut($histo[$key]['percent'], 2, 0, $histo[$key]['datestart']) . ''; + $out .= ''; + $out .= $actionstatic->LibStatut($histo[$key]['percent'], 2, 0, $histo[$key]['datestart']); + $out .= ''; // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a561315f90a..fa20a03ea75 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7823,8 +7823,8 @@ function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round /** - * Return localtax rate for a particular vat, when selling a product with vat $vatrate, from a $thirdparty_buyer to a $thirdparty_seller - * Note: This function applies same rules than get_default_tva + * Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate, from a $thirdparty_buyer to a $thirdparty_seller + * Note: This function get information into the table llx_tva using the VAT rate as key. * * @param float|string $vatrate Vat rate. Can be '8.5' or '8.5 (VATCODEX)' for example * @param int $local Local tax to search and return (1 or 2 return only tax rate 1 or tax rate 2) @@ -7832,7 +7832,7 @@ function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round * @param ?Societe $thirdparty_seller Object of selling third party ($mysoc if not defined) * @param int<0,1> $vatnpr If vat rate is NPR or not * @return int<0,0>|string 0 if not found, localtax rate if found (Can be '20', '-19:-15:-9') - * @see get_default_tva() + * @see get_default_tva(), get_default_localtax() */ function get_localtax($vatrate, $local, $thirdparty_buyer = null, $thirdparty_seller = null, $vatnpr = 0) { @@ -8250,6 +8250,7 @@ function get_product_vat_for_country($idprod, $thirdpartytouseforcountry, $idpro } dol_syslog("get_product_vat_for_country: ret=" . $ret); + return $ret; } @@ -8338,7 +8339,7 @@ function get_product_localtax_for_country($idprod, $local, $thirdpartytouseforco */ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod = 0, $idprodfournprice = 0) { - global $mysoc, $db; + global $mysoc, $db, $hookmanager; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; @@ -8359,6 +8360,9 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, dol_syslog("get_default_tva: seller use vat=" . $seller_use_vat . ", seller country=" . $seller_country_code . ", seller in cee=" . ((string) (int) $seller_in_cee) . ", buyer vat number=" . $thirdparty_buyer->tva_intra . " buyer country=" . $buyer_country_code . ", buyer state=" . $thirdparty_buyer->state_id . " buyer in cee=" . ((string) (int) $buyer_in_cee) . ", idprod=" . $idprod . ", idprodfournprice=" . $idprodfournprice . ", SERVICE_ARE_ECOMMERCE_200238EC=" . getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')); + $vatvalue = 0; + $vatrule = ''; + // If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm) // we use the buyer VAT. if (getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')) { @@ -8372,25 +8376,26 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, } if (!$isacompany) { - //print 'VATRULE 0'; - return get_product_vat_for_country($idprod, $thirdparty_buyer, $idprodfournprice); + $vatvalue = get_product_vat_for_country($idprod, $thirdparty_buyer, $idprodfournprice); + $vatrule = 'VATRULE 0'; } } } // If seller does not use VAT, default VAT is 0. End of rule. - if (!$seller_use_vat) { + if (empty($vatrule) && !$seller_use_vat) { //print 'VATRULE 1'; // TODO get the VAT Code of exemption asked into setup if country isInEEC (from an array list of possible // values like VATEX-EU-132-*, VATEX-FR-FRANCHISE, VATEX-EU-AE... // When we had recorded it, we also added a corresponding entry into table of vat code if it does not exists yet. // Here we test if entry for the VAT exemption code exists in llx_vat, we can return '0 (VATEX-EU-132-xx)' // If not, we add it and we return '0 (VATEX-EU-132-xx)' - return 0; + $vatvalue = 0; + $vatrule = 'VATRULE 1'; } // 'VATRULE 2' - Force VAT if a buyer department is defined on vat rates dictionary - if (!empty($thirdparty_buyer->state_id)) { + if (empty($vatrule) && !empty($thirdparty_buyer->state_id)) { $sql = "SELECT d.rowid, t.taux as vat_default_rate, t.code as vat_default_code "; $sql .= " FROM " . $db->prefix() . "c_tva as t"; $sql .= " INNER JOIN " . $db->prefix() . "c_departements as d ON t.fk_department_buyer = d.rowid"; @@ -8401,17 +8406,19 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, if ($res) { if ($db->num_rows($res)) { $obj = $db->fetch_object($res); - return $obj->vat_default_rate . ' (' . $obj->vat_default_code . ')'; + + $vatvalue = $obj->vat_default_rate . ' (' . $obj->vat_default_code . ')'; + $vatrule = 'VATRULE 2'; } $db->free($res); } } // If the (seller country = buyer country) then the default VAT = VAT of the product sold. End of rule. - if (($seller_country_code == $buyer_country_code) + if (empty($vatrule) && (($seller_country_code == $buyer_country_code) || (in_array($seller_country_code, array('FR', 'MC')) && in_array($buyer_country_code, array('FR', 'MC'))) || (in_array($seller_country_code, array('MQ', 'GP')) && in_array($buyer_country_code, array('MQ', 'GP'))) // We should be able to manage the case of MQ, GP, ... with a deicated vat rate at previous step. - ) { // Warning ->country_code not always defined + )) { // Warning ->country_code not always defined //print 'VATRULE 3'; $tmpvat = get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); @@ -8428,7 +8435,8 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, } } - return $tmpvat; + $vatvalue = $tmpvat; + $vatrule = 'VATRULE 3b'; } // If (seller and buyer in the European Community) and (property sold = new means of transport such as car, boat, plane) then VAT by default = 0 (VAT must be paid by the buyer to the tax center of his country and not to the seller). End of rule. @@ -8436,7 +8444,7 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, // If (seller and buyer in the European Community) and (buyer = individual) then VAT by default = VAT of the product sold. End of rule // If (seller and buyer in European Community) and (buyer = company) then VAT by default=0. End of rule - if (($seller_in_cee && $buyer_in_cee)) { + if (empty($vatrule) && ($seller_in_cee && $buyer_in_cee)) { $isacompany = $thirdparty_buyer->isACompany(); if ($isacompany && !getDolGlobalString('MAIN_USE_VAT_ZERO_FOR_COMPANIES_IN_EEC_EVEN_IF_VAT_ID_UNKNOWN')) { require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; @@ -8447,22 +8455,25 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, if (!$isacompany) { //print 'VATRULE 5'; - return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); + $vatvalue = get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); + $vatrule = 'VATRULE 5'; } else { //print 'VATRULE 6'; // TODO This is the case of VAT exemption 'VATEX-EU-IC' // If entry for the VAT exemption code exists in llx_vat, we can return '0 (VATEX-EU-IC)' // If not, we add it and we return '0 (VATEX-EU-IC)' - return 0; + $vatvalue = 0; + $vatrule = 'VATRULE 6'; } } // If (seller in the European Community and buyer outside the European Community and private buyer) then VAT by default = VAT of the product sold. End of rule // I don't see any use case that need this rule, this case is on only if MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC set - if (getDolGlobalString('MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC') && empty($buyer_in_cee)) { + if (empty($vatrule) && getDolGlobalString('MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC') && empty($buyer_in_cee)) { $isacompany = $thirdparty_buyer->isACompany(); if (!$isacompany) { - return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); + $vatvalue = get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); + $vatrule = 'VATRULE extra'; //print 'VATRULE extra'; } } @@ -8473,7 +8484,17 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, // TODO This is the case of VAT exemption 'VATEX-EU-G' // If entry for the VAT exemption code exists in llx_vat, we can return '0 (VATEX-xxx)' // If not, we add it and we return '0 (VATEX-xxx)' - return 0; + + // Allow an external module to bypass the calculation of prices + $parameters = array('vatvalue' => $vatvalue, 'vatrule' => $vatrule); + $tmpobject = null; $tmpaction = null; + $reshook = $hookmanager->executeHooks('get_default_tva', $parameters, $tmpobject, $tmpaction); // See description below + if ($reshook > 0 && !empty($hookmanager->resArray['vatvalue'])) { + $vatvalue = $hookmanager->resArray['vatvalue']; + $vatrule = $hookmanager->resArray['vatrule']; // For information + } + + return $vatvalue; } diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 14fbeead6b8..70ef9dba8f5 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -89,7 +89,7 @@ */ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = null, $localtaxes_array = [], $progress = 100, $multicurrency_tx = 1, $pu_devise = 0, $multicurrency_code = '') // @phpstan-ignore-line { - global $conf, $mysoc, $db; + global $conf, $mysoc, $db, $hookmanager; $result = array(); @@ -387,16 +387,16 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt // If rounding is not using base 10 (rare) if (getDolGlobalString('MAIN_ROUNDING_RULE_TOT')) { if ($price_base_type == 'HT') { - $result[0] = price2num(round((float) $result[0] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[1] = price2num(round((float) $result[1] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[9] = price2num(round((float) $result[9] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[10] = price2num(round((float) $result[10] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); + $result[0] = price2num(round((float) $result[0] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[1] = price2num(round((float) $result[1] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[9] = price2num(round((float) $result[9] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[10] = price2num(round((float) $result[10] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); $result[2] = price2num((float) $result[0] + (float) $result[1] + (float) $result[9] + (float) $result[10], 'MT'); } else { - $result[1] = price2num(round((float) $result[1] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[2] = price2num(round((float) $result[2] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[9] = price2num(round((float) $result[9] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); - $result[10] = price2num(round((float) $result[10] / (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 0) * (float) $conf->global->MAIN_ROUNDING_RULE_TOT, 'MT'); + $result[1] = price2num(round((float) $result[1] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[2] = price2num(round((float) $result[2] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[9] = price2num(round((float) $result[9] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); + $result[10] = price2num(round((float) $result[10] / getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 0) * getDolGlobalFloat('MAIN_ROUNDING_RULE_TOT'), 'MT'); $result[0] = price2num((float) $result[2] - (float) $result[1] - (float) $result[9] - (float) $result[10], 'MT'); } } @@ -453,7 +453,16 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt $result[25] = $result[9]; $result[26] = $result[10]; } + dol_syslog('Price.lib::calcul_price_total MAIN_ROUNDING_RULE_TOT='.getDolGlobalString('MAIN_ROUNDING_RULE_TOT').' pu='.$pu.' qty='.$qty.' price_base_type='.$price_base_type.' total_ht='.$result[0].'-total_vat='.$result[1].'-total_ttc='.$result[2]); + // Allow an external module to bypass the calculation of prices + $parameters = array('result' => $result); + $tmpobject = null; $tmpaction = null; + $reshook = $hookmanager->executeHooks('calcul_price_total', $parameters, $tmpobject, $tmpaction); // See description below + if ($reshook > 0 && !empty($hookmanager->resArray['result'])) { + return $hookmanager->resArray['result']; + } + return $result; } diff --git a/htdocs/projet/agenda.php b/htdocs/projet/agenda.php index 256cf2d74a2..049008a455b 100644 --- a/htdocs/projet/agenda.php +++ b/htdocs/projet/agenda.php @@ -26,11 +26,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -38,6 +33,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; // Load translation files required by the page $langs->load("projects"); @@ -77,18 +76,19 @@ $search_agenda_label = GETPOST('search_agenda_label'); $hookmanager->initHooks(array('projectcardinfo')); +$object = new Project($db); + // Security check $id = GETPOSTINT("id"); $socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment. -$result = restrictedArea($user, 'projet', $id, 'projet&project'); +restrictedArea($user, 'projet', $id, 'projet&project'); if (!$user->hasRight('projet', 'lire')) { accessforbidden(); } - /* * Actions */ diff --git a/htdocs/projet/messaging.php b/htdocs/projet/messaging.php index f5d2cafb6e8..4767b04eecc 100644 --- a/htdocs/projet/messaging.php +++ b/htdocs/projet/messaging.php @@ -26,11 +26,6 @@ // Load Dolibarr environment require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - /** * @var Conf $conf * @var DoliDB $db @@ -38,6 +33,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; * @var Translate $langs * @var User $user */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; // Load translation files required by the page $langs->load("projects"); @@ -77,11 +76,13 @@ $search_agenda_label = GETPOST('search_agenda_label'); $hookmanager->initHooks(array('projectcardinfo')); +$object = new Project($db); + // Security check $id = GETPOSTINT("id"); $socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment. -$result = restrictedArea($user, 'projet', $id, 'projet&project'); +restrictedArea($user, 'projet', $id, 'projet&project'); if (!$user->hasRight('projet', 'lire')) { accessforbidden(); @@ -93,8 +94,6 @@ if (!$user->hasRight('projet', 'lire')) { * Actions */ -$object = new Project($db); - if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); $object->fetch_thirdparty(); diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 5239a0059d6..0757c620ee7 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1378,26 +1378,32 @@ class FunctionsLibTest extends CommonClassTest // Not tested // Test RULE 1 + print __METHOD__." rule=RULE 1\n"; $vat = get_default_tva($companyfrnovat, $companymc, 0); $this->assertEquals(0, $vat, 'RULE 1'); // Test RULE 2 (FR-FR) + print __METHOD__." rule=RULE 2 FR-FR\n"; $vat = get_default_tva($companyfr, $companyfr, 0); $this->assertEquals(20, $vat, 'RULE 2'); // Test RULE 2 (FR-MC) + print __METHOD__." rule=RULE 2 FR-MC\n"; $vat = get_default_tva($companyfr, $companymc, 0); $this->assertEquals(20, $vat, 'RULE 2'); // Test RULE 3 (FR-DE company) + print __METHOD__." rule=RULE 3 FR-DE\n"; $vat = get_default_tva($companyfr, $companyit, 0); $this->assertEquals(0, $vat, 'RULE 3'); // Test RULE 4 (FR-DE not a company) + print __METHOD__." rule=RULE 4 FR-DE\n"; $vat = get_default_tva($companyfr, $notcompanyde, 0); $this->assertEquals(20, $vat, 'RULE 4'); // Test RULE 5 (FR-US) + print __METHOD__." rule=RULE 5 FR-US\n"; $vat = get_default_tva($companyfr, $companyus, 0); $this->assertEquals(0, $vat, 'RULE 5'); @@ -1406,22 +1412,27 @@ class FunctionsLibTest extends CommonClassTest $conf->global->SERVICE_ARE_ECOMMERCE_200238EC = 1; // Test RULE 1 (FR-US) + print __METHOD__." rule=RULE 1 ECOMMERCE_200238EC FR-US\n"; $vat = get_default_tva($companyfr, $companyus, 0); $this->assertEquals(0, $vat, 'RULE 1 ECOMMERCE_200238EC'); // Test RULE 2 (FR-FR) + print __METHOD__." rule=RULE 2 ECOMMERCE_200238EC FR-FR\n"; $vat = get_default_tva($companyfr, $companyfr, 0); $this->assertEquals(20, $vat, 'RULE 2 ECOMMERCE_200238EC'); // Test RULE 3 (FR-DE company) + print __METHOD__." rule=RULE 3 ECOMMERCE_200238EC FR-DE company\n"; $vat = get_default_tva($companyfr, $companyde, 0); $this->assertEquals(0, $vat, 'RULE 3 ECOMMERCE_200238EC'); // Test RULE 4 (FR-DE not a company) + print __METHOD__." rule=RULE 4 ECOMMERCE_200238EC FR-DE not company\n"; $vat = get_default_tva($companyfr, $notcompanyde, 0); $this->assertEquals(19, $vat, 'RULE 4 ECOMMERCE_200238EC'); // Test RULE 5 (FR-US) + print __METHOD__." rule=RULE 5 ECOMMERCE_200238EC FR-US\n"; $vat = get_default_tva($companyfr, $companyus, 0); $this->assertEquals(0, $vat, 'RULE 5 ECOMMERCE_200238EC'); } @@ -1480,24 +1491,28 @@ class FunctionsLibTest extends CommonClassTest $companyus->localtax2_assuj = 0; // Test RULE FR-MC + print __METHOD__." rule=FR-MC\n"; $vat1 = get_default_localtax($companyfrnovat, $companymc, 1, 0); $vat2 = get_default_localtax($companyfrnovat, $companymc, 2, 0); $this->assertEquals(0, $vat1); $this->assertEquals(0, $vat2); // Test RULE ES-ES + print __METHOD__." rule=ES-ES\n"; $vat1 = get_default_localtax($companyes, $companyes, 1, 0); $vat2 = get_default_localtax($companyes, $companyes, 2, 0); $this->assertEquals($vat1, 5.2); $this->assertStringStartsWith((string) $vat2, '-19:-15:-9'); // Can be -19 (old version) or '-19:-15:-9' (new setup) // Test RULE ES-IT + print __METHOD__." rule=ES-IT company\n"; $vat1 = get_default_localtax($companyes, $companyit, 1, 0); $vat2 = get_default_localtax($companyes, $companyit, 2, 0); $this->assertEquals(0, $vat1); $this->assertEquals(0, $vat2); - // Test RULE ES-IT + // Test RULE ES-not IT + print __METHOD__." rule=ES-IT not company\n"; $vat1 = get_default_localtax($companyes, $notcompanyit, 1, 0); $vat2 = get_default_localtax($companyes, $notcompanyit, 2, 0); $this->assertEquals(0, $vat1); @@ -1507,6 +1522,7 @@ class FunctionsLibTest extends CommonClassTest // Not tested // Test RULE ES-US + print __METHOD__." rule=ES-US\n"; $vat1 = get_default_localtax($companyes, $companyus, 1, 0); $vat2 = get_default_localtax($companyes, $companyus, 2, 0); $this->assertEquals(0, $vat1);