Dienstag, 5. August 2008 Druck-Ansicht
Eine nette Funktion von xt:Commerce ist die “Erweiterte Suche” (Advanced Search), in der man neben gewünschten Kategorien, Herstellern etc. auch Preisbereiche angeben kann, aus denen die Ergebnisse kommen sollen.
Allerdings werden die Steuern der Artikel dabei nicht berücksichtigt. Gibt man also ein, man möchte alle Artikel bis maximal 100,- € angezeigt bekommen, sieht man als Kunde defacto alles, was exklusive der Steuern 100,- € und weniger kostet.
Im Regelfall werden daher alle Produkte bis 119,- € (statt bis 100,- €) gefunden.
Vadder Staat langt mit der vielgeliebten “Märchensteuer” seit jeher kräftigst zu, und so macht diese “kleine Ungenauigkeit” bei den Steuern (für die meisten Produkte) immerhin knapp ein Fünftel aus. Da darf man den Preisfilter von xt:C schon guten Gewissens als “etwas unpräzise” bezeichnen.
In der Datei “advanced_search_result.php” wird die Datenbank-Abfrage für die Suche zusammengesetzt. Dort müssen wir also ansetzen.
1) Brauchen wir den Steuersatz?
Die “tax_rate” brauchen wir nur dann, wenn a) nach Preisen gefragt wird und b) die jeweilige Kundengruppe ihre Preise inklusive Steuern sehen soll.
Da sich die Datenbank-Abfrage, sobald wir die “tax_rate” benötigen, ändern (und ein bisschen verkomplizieren) wird, führen wir eine Kontroll-Variable $NeedTax ein, die zunächst einmal den Wert ‘false’ hat.
Ein geeigneter Punkt sind die Zeilen, in denen festgestellt wird, ob nach einem Preis gefragt wurde. Im Original Zeile 140 bis 149:
if ($_GET['pfrom'] || $_GET['pto']) {
$rate = xtc_get_currencies_values($_SESSION['currency']);
$rate = $rate['value'];
if ($rate && $_GET['pfrom'] != '') {
$pfrom = $_GET['pfrom'] / $rate;
}
if ($rate && $_GET['pto'] != '') {
$pto = $_GET['pto'] / $rate;
}
}
Diese Zeilen ändern wir wie folgt:
$NeedTax = false;
if ($_GET['pfrom'] || $_GET['pto']) {
$rate = xtc_get_currencies_values($_SESSION['currency']);
$rate = $rate['value'];
if ($rate && $_GET['pfrom'] != '') {
$pfrom = $_GET['pfrom'] / $rate;
}
if ($rate && $_GET['pto'] != '') {
$pto = $_GET['pto'] / $rate;
}
if($_SESSION['customers_status']['customers_status_show_price_tax']) {
$NeedTax = true;
}
}
2) Der Preisfilter …
Als Nächstes ist der Preisfilter dran. Im Original wird nur der Artikelpreis bzw. der Sonderpreis (wenn vorhanden) ermittelt und mit den Werten aus $_GET['pfrom'] und $_GET['pto'] (”Preis von, Preis bis”) verglichen.
In der Original-Datei sind es die Zeilen 151 bis 162, nach unserer Änderung werden die Nummern ein bisschen verrutscht sein …
![]()
Aber zur Not hat man ja noch die Sicherheitskopie (Die hat man doch? Wink mit dem Zaunpfahl - Schnell eine machen!)
//price filters
if (($pfrom != '') && (is_numeric($pfrom))) {
$pfrom_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) >= ".$pfrom.") ";
} else {
unset ($pfrom_check);
}
if (($pto != '') && (is_numeric($pto))) {
$pto_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) <= ".$pto." ) ";
} else {
unset ($pto_check);
}
Diese Zeilen ändern wir - um die ‘tax_rate’ mit einzuberechnen - wie folgt:
//price filters
if (($pfrom != '') && (is_numeric($pfrom))) {
if($NeedTax)
$pfrom_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) >= round((".$pfrom."/(1+tax_rate/100)),".PRICE_PRECISION.") ) ";
else
$pfrom_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) >= round(".$pfrom.",".PRICE_PRECISION.") ) ";
} else {
unset ($pfrom_check);
}
if (($pto != '') && (is_numeric($pto))) {
if($NeedTax)
$pto_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) <= round((".$pto."/(1+tax_rate/100)),".PRICE_PRECISION.") ) ";
else
$pto_check = " AND (IF(s.status = '1' AND p.products_id = s.products_id, s.specials_new_products_price, p.products_price) <= round(".$pto.",".PRICE_PRECISION.") ) ";
} else {
unset ($pto_check);
}
Als “Rundungsgenauigkeit” benutzen wir die Konstante PRICE_PRECISION, die (im Admin-Bereich eingestellt) für die Genauigkeit in Sachen Steuerberechnung genutzt wird.
Und, ja diese Rechnung stimmt:
Natürlich ist der Endpreis gleich dem Artikelpreis MAL eins-plus-tax_rate-durch-hundert.
Da an dieser Stelle aber nur der Artikelpreis bekannt ist, müssen wir die “Preis-von”- und die “Preis-bis”-Angabe DURCH eins-plus-tax_rate-durch-hundert teilen, um sie korrekt mit dem Grundpreis vergleichen zu können.
3) Der letzte Schritt: $from_str und $tax_where
Gegen Ende hat die Original “advanced_search_result.php” noch einen kleinen Fehler drin - Die Konstante DISPLAY_PRICE_WITH_TAX ist irgendwie immer leer.
Daher muss dieser Absatz - im Original Zeile 184 bis 193 - korrigiert werden:
if ((DISPLAY_PRICE_WITH_TAX == 'true') && ((isset ($_GET['pfrom']) && xtc_not_null($_GET['pfrom'])) || (isset ($_GET['pto']) && xtc_not_null($_GET['pto'])))) {
if (!isset ($_SESSION['customer_country_id'])) {
$_SESSION['customer_country_id'] = STORE_COUNTRY;
$_SESSION['customer_zone_id'] = STORE_ZONE;
}
$from_str .= " LEFT OUTER JOIN ".TABLE_TAX_RATES." tr ON (p.products_tax_class_id = tr.tax_class_id) LEFT OUTER JOIN ".TABLE_ZONES_TO_GEO_ZONES." gz ON (tr.tax_zone_id = gz.geo_zone_id) ";
$tax_where = " AND (gz.zone_country_id IS NULL OR gz.zone_country_id = '0' OR gz.zone_country_id = '".(int) $_SESSION['customer_country_id']."') AND (gz.zone_id is null OR gz.zone_id = '0' OR gz.zone_id = '".(int) $_SESSION['customer_zone_id']."')";
} else {
unset ($tax_where);
}
Am besten wir nutzen dazu $NeedTax - und dann sieht das Ganze in etwa so aus:
if($NeedTax) {
if (!isset ($_SESSION['customer_country_id'])) {
$_SESSION['customer_country_id'] = STORE_COUNTRY;
$_SESSION['customer_zone_id'] = STORE_ZONE;
}
$from_str .= " LEFT OUTER JOIN ".TABLE_TAX_RATES." tr ON (p.products_tax_class_id = tr.tax_class_id) LEFT OUTER JOIN ".TABLE_ZONES_TO_GEO_ZONES." gz ON (tr.tax_zone_id = gz.geo_zone_id) ";
$tax_where = " AND (gz.zone_country_id IS NULL OR gz.zone_country_id = '0' OR gz.zone_country_id = '".(int) $_SESSION['customer_country_id']."') AND (gz.zone_id is null OR gz.zone_id = '0' OR gz.zone_id = '".(int) $_SESSION['customer_zone_id']."')";
} else {
unset ($tax_where);
}
Wer diese Änderungen nicht selbst nachtragen möchte, kann sich hier die veränderte “advanced_search_result.php” (als ZIP-File) kostenlos herunterladen.
Hinweis: Diese Version ist eine bis auf die oben beschriebenen Bearbeitungen) unveränderte Original-Datei.
Tipp: Alle Änderungen im Code sind mit
(Änderungs-Anfang) // GUNNAR: irgendein Kommentar und
(Änderungs-Ende) //--> gekennzeichnet.
Der Original-Code ist nie komplett entfernt, sondern lediglich auskommentiert worden. So hat man’s beim Einbau einiger Erweiterungen (z.B. Sortier-Funktionen u.ä.) ein bisschen leichter.
Bookmarks, Feed und Links
Wenn Ihnen dieser Beitrag geholfen hat ...
Beiträge zu ähnlichen Themen:
12 Antworten zu xt:Commerce - Advanced Search, Preisfilter mit Steuern
Kommentar schreiben