Freitag, 18. August 2006 Druck-Ansicht
Bei vergünstigten Angeboten ist vielfach die Anzeige der Ersparnis als Betrag und in Prozent erwünscht. xt:Commerce bietet “von Haus aus” zumindest die Prozent-Anzeige beim Preisnachlass in Form eines Artikel-Rabatts - Näheres zum Thema “Preisnachlässe” ist diesen beiden Beiträgen zu entnehmen:
Um eine Ersparnis bei jeder Form eines Preisnachlasses ausgeben zu lassen, muss die Datei “xtcPrice.php” (im Ordner “includes”/”classes” bearbeitet werden. So können gleich zwei Aufgaben erledigt werden:
Wer eine solche Ersparnis-Anzeige nicht braucht, sondern nur das Wort “UVP” bei der Preis-Ausgabe vermeiden will, ist ziemlich schnell fertig: Entweder die Sprachdatei ändern - oder in der erwähnten Datei “xtcPrice.php” die Zeile 368 suchen …
$price = '<span class="productOldPrice">'.MSRP.$this->xtcFormat($pPrice, $format).'</span><br />'.YOUR_PRICE.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format);
… und dort MSRP durch INSTEAD austauschen. Damit wird anstelle von “UVP” das weitaus unverfänglichere Wörtchen “statt” ausgegeben.
Ob man allerdings wegen einer Änderung, die im Grunde genommen nur das “Vokabular” betrifft, gleich an einer Systemdatei herumbasteln möchte, ist Geschmacksache. Für Händler mit mehrsprachigen Shops, die vielleicht in Zukunft noch das ein oder andere Sprachpaket zusätzlich installieren möchten, ist die oben beschriebene Änderung jedoch vermutlich die einfachere Lösung.
Zunächst einmal muss man sich darüber Gedanken machen, welche Preisnachlässe in “xtcPrice.php” berücksichtigt werden. Das sind folgende Varianten:
Der Preisnachlass in Form von “Rabatt auf gesamte Bestellung” wird in “xtcPrice.php” nicht beachtet, dort “weiß” das System quasi noch nichts davon - und auch im Shop sieht man das Ergebnis erst am Gesamtwert des Warenkorbs. Ebenso sind die einzelnen Werte der “Staffelpreise” hier nicht relevant, denn in der “xtcPrice.php” wird die Ausgabe des Preises bei Kauf eines einzelnen Artikels bestimmt.
An der Art und Weise wie Preisnachlässe behandelt werden sollte nichts Wesentliches verändert werden - daher konzentriert sich die Suche nach der Ausgabe von Preisen auf die “Format-Funktionen”, die in der Datei “xtcPrice.php” (durch ein paar deutliche Kommentarzeilen 298 bis 304 gekennzeichnet) erst ab Zeile 306 beginnen.
Ein allgemeiner Hinweis vorweg: Geänderte Zeilen sind bei den folgenden Code-Beispielen mit Kommentar-Marken gekennzeichnet. Der Original-Code ist zudem nie gelöscht, sondern nur auskommentiert.
1) Preisformatierung - Nicht verändern!
Die Funktion “xtcFormat” übernimmt dabei ein paar “grundsätzliche” Aufgaben wie beispielsweise das Runden auf zwei Stellen nach dem Komma plus Ausgabe des eingestellten Währungs-Symbols. Die kann so bleiben, wie sie ist.
2) “Artikel-Rabatt” - Erweitern
An der nächsten Funktion “xtcFormatSpecialDiscount” (Zeile 334 bis 346) gibt’s etwas zu tun. Hier wird im Falle eines Artikel-Rabatts dieser im Vergleich mit dem normalen Artikelpreis ausgegeben.
function xtcFormatSpecialDiscount($pID, $discount, $pPrice, $format, $vpeStatus = 0) {
$sPrice = $pPrice - ($pPrice / 100) * $discount;
if ($format) {
$price = '<span class="productOldPrice">'.INSTEAD.$this->xtcFormat($pPrice, $format).'</span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format).'<br />'.YOU_SAVE.$discount.'%';
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
Dort kann man schon eine grundlegende Verfahrensweise erahnen - der Artikel-”Grund”-Preis steckt in der Variablen $pPrice, der reduzierte Preis in $sPrice
Die Berechnung der Ersparnis als Betrag ist kein Problem, hier muss lediglich eine Differenz gebildet und entsprechend der eingestellten Währung formatiert werden - und zwar mit der erwähnten Funktion “xtcFormat” - Der Code für diese Berechnung lautet also:
$this->xtcFormat($pPrice-$sPrice, $format)
Die Ersparnis in Prozent erfordert ein bisschen Dreisatz - Der Rechenweg ist: (Artikel-Preis minus Reduzierter-Preis) geteilt durch Artikel-Preis mal 100 - In PHP geschrieben also:
($pPrice-$sPrice) / $pPrice * 100
Um endlos viele Nachkommastellen auszuschließen, runden wir das Ganze und versehen die Ausgabe mit dem “Sie sparen”-Text sowie einem Prozent-Zeichen:
YOU_SAVE.round(($pPrice-$sPrice) / $pPrice * 100).' %'
Und was ist mit $discount? In diesem Falle entspricht der Discount dem Preisnachlass - Und um eine (passend zu den folgenden Preisnachlässen) einheitliche Anzeige zu gewährleisten, lassen wir diesen Discount (Artikel-Rabatt) auch nicht unerwähnt.
Damit ändert sich der gesamte Bereich wie folgt:
function xtcFormatSpecialDiscount($pID, $discount, $pPrice, $format, $vpeStatus = 0) {
$sPrice = $pPrice - ($pPrice / 100) * $discount;
if ($format) {
//$price = '<span class="productOldPrice">'.INSTEAD.$this->xtcFormat($pPrice, $format).'</span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format).'<br />'.YOU_SAVE.$discount.'%';
$price = '<span class="productOldPrice"><small>'.INSTEAD.'</small><del>'.$this->xtcFormat($pPrice, $format).'</del></span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format).'<br /><small>'.YOU_SAVE.round(($pPrice-$sPrice) / $pPrice * 100).' % /'.$this->xtcFormat($pPrice-$sPrice, $format);
// Ausgabe des gültigen Kundengruppen-Rabatts (sofern vorhanden)
if ($discount != 0)
{ $price .= '<br />'.BOX_LOGINBOX_DISCOUNT.': '.round($discount).' %'; }
$price .= '</small>';
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
BOX_LOGINBOX_DISCOUNT greift dabei auf eine global verfügbare Text-Variable zurück - In der Deutschen Sprachdatei wird bei deren Aufruf das Wort “Artikelrabatt” zurückgegeben. Passt an dieser Stelle optimal.
Die Details an der HTML-Ausgabe sind natürlich Geschmackssache - Ich halte es jedenfalls für sinnvoll, den nicht mehr gültigen, alten Preis unabhängig von CSS Style-Anweisungen schon gleich im HTML-Code mittels eines <DEL>-Tags durchzustreichen.
3) Sonderpreis - Erweitern
Liegt ein “Sonderpreis” vor, werden alle anderen angelegten Preisnachlässe ungültig. Entsprechend einfach ist die Original-Funktion “xtcFormatSpecial” - zu finden in den Zeilen 348 bis 359:
function xtcFormatSpecial($pID, $sPrice, $pPrice, $format, $vpeStatus = 0) {
if ($format) {
$price = '<span class="productOldPrice">'.INSTEAD.$this->xtcFormat($pPrice, $format).'</span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format);
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
Nachlässe via “Discount” brauchen nicht beachtet zu werden, denn sie werden von Sonderpreisen sowieso “überschrieben” - daher ergibt sich (in Anlehnung an die oben beschriebene Erweiterung) folgender, neuer Code:
function xtcFormatSpecial($pID, $sPrice, $pPrice, $format, $vpeStatus = 0) {
if ($format) {
//$price = '<span class="productOldPrice">'.INSTEAD.$this->xtcFormat($pPrice, $format).'</span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format);
$price = '<span class="productOldPrice"><small>'.INSTEAD.'</small><del>'.$this->xtcFormat($pPrice, $format).'</del></span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format).'<br /><small>'.YOU_SAVE.round(($pPrice-$sPrice) / $pPrice * 100).' % /'.$this->xtcFormat($pPrice-$sPrice, $format).'</small>';
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
4) Preisnachlass bei Staffelpreisen
Die Funktion “xtcFormatSpecialGraduated” (Zeile 361 bis 380) kombiniert alle vorliegenden Preisnachlässe mit Mengen-Staffelungen in folgender Weise:
function xtcFormatSpecialGraduated($pID, $sPrice, $pPrice, $format, $vpeStatus = 0, $pID) {
if ($pPrice == 0)
return $this->xtcFormat($sPrice, $format, 0, false, $vpeStatus);
if ($discount = $this->xtcCheckDiscount($pID))
$sPrice -= $sPrice / 100 * $discount;
if ($format) {
if ($sPrice != $pPrice) {
$price = '<span class="productOldPrice">'.MSRP.$this->xtcFormat($pPrice, $format).'</span><br />'.YOUR_PRICE.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format);
} else {
$price = FROM.$this->xtcFormat($sPrice, $format);
}
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
Einzelpreise “interessieren” sich jedoch nicht für Preis-Staffelungen. Gibt es einen Rabatt, wird er abgezogen - gibt es einen Sonderpreis, ist nur dieser gültig. Gibt es keins von beiden, gilt der Gruppenpreis für einen einzelnen Artikel. Gibt es nur Preisnachlass in Form von Mengenstaffelungen, bleibt der Einzelpreis wiederum unbeeinflusst …
Also unterscheidet sich die Ersparnis-Berechnung wieder einmal kaum von den oben erklärten Beispielen:
function xtcFormatSpecialGraduated($pID, $sPrice, $pPrice, $format, $vpeStatus = 0, $pID) {
if ($pPrice == 0)
return $this->xtcFormat($sPrice, $format, 0, false, $vpeStatus);
if ($discount = $this->xtcCheckDiscount($pID))
$sPrice -= $sPrice / 100 * $discount;
if ($format) {
if ($sPrice != $pPrice) {
//$price = '<span class="productOldPrice">'.MSRP.$this->xtcFormat($pPrice, $format).'</span><br />'.YOUR_PRICE.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format);
$price = '<span class="productOldPrice"><small>'.INSTEAD.'</small><del>'.$this->xtcFormat($pPrice, $format).'</del></span><br />'.ONLY.$this->checkAttributes($pID).$this->xtcFormat($sPrice, $format).'<br /><small>'.YOU_SAVE.round(($pPrice-$sPrice) / $pPrice * 100).' % /'.$this->xtcFormat($pPrice-$sPrice, $format);
// Ausgabe des gültigen Kundengruppen-Rabatts (sofern vorhanden)
if ($discount != 0)
{ $price .= '<br />'.BOX_LOGINBOX_DISCOUNT.': '.round($discount).' %'; }
$price .= '</small>';
} else {
$price = FROM.$this->xtcFormat($sPrice, $format);
}
if ($vpeStatus == 0) {
return $price;
} else {
return array ('formated' => $price, 'plain' => $sPrice);
}
} else {
return round($sPrice, $this->currencies[$this->actualCurr]['decimal_places']);
}
}
Die Datei “xtcPrice.php” gibt’s hier mit allen beschriebenen Veränderungen zum Download.
Anleitung: Runterladen, entpacken - und (natürlich nach vorheriger Sicherheitskopie) mit der entsprechenden Datei im Ordner “includes”/”classes” Ihres Shop-Systems austauschen.
Ich bitte zu beachten, dass dieser Austausch JEDEN angezeigten Preis in Ihrem Shop beeinflusst. Eventuell könnte die von mir vorgeschlagene HTML-Ausgabe für ungewünschte Ergebnisse in Ihrem Layout sorgen - Sollte dies der Fall sein, überarbeiten Sie bitte die entsprechend markierten Stellen im Quellcode nach Ihren Anforderungen.
Nach dem Einbau aller beschriebenen Änderungen bzw. nach dem Upload der zur Verfügung gestellten Datei verhalten sich alle Preis-Angaben des xt:Commerce-Shops überall (!) wie folgt:
Nicht mehr mit Reizen geizen: Jegliche Art eines Preisnachlasses sollte nun bei jedem Preis deutlich in “gesparte Prozent” und “gespartem Betrag” angezeigt werden.
Die angebotene Datei ist für xt:Commerce 3.04 SP1 erstellt und auch nur mit dieser Version getestet. Sollten Sie eine andere Version des Shops installiert haben, rate ich von der Verwendung ab. Einer Haftung für eventuelle System-Ausfälle widerspreche ich außerdem ausdrücklich.
Bitte beachten Sie unbedingt die allgemeinen Hinweise zur Verwendung hier veröffentlichter Code-Beispiele!
Wenn man eine Änderung von System-Dateien vermeiden möchte, kann man ähnliche Funktionen auch ausschließlich mit Template-Dateien realisieren. Eine solche Funktions-Erweiterung des Templates wird in diesem Beitrag vorgestellt.
Bookmarks, Feed und Links
Wenn Ihnen dieser Beitrag geholfen hat ...
Beiträge zu ähnlichen Themen:
Eine Antwort zu Preisnachlass? Anzeige der Ersparnis in Prozent und als Betrag
Kommentar schreiben