FOX - WooCommerce Currency Switcher Professional

Umgerechnete Preise in WooCommerce runden: ,99, ganze Zahlen, Stufen

Ein Wechselkurs macht aus einem glatten Preis von 49,00 schnell 45,37 oder 4.083,12, und das möchten nur wenige Shops anzeigen. FOX hat keine Einstellung zum Runden, weil jeder Shop ein anderes Muster wünscht, bietet aber zwei Filter, mit denen Sie umgerechnete Preise in WooCommerce nach Belieben runden: auf ganze Zahlen, auf Endungen wie ,99 oder ,95, auf Fünfer-, Zehner-, Hunderter- oder Tausenderschritte, jeweils pro Währung. Die meisten Snippets, die angeblich „nicht funktionieren“, scheitern an einem von wenigen Gründen: Es wird nur einer der beiden Filter verwendet, die Basiswährung wird mitgerundet, die Steuern kommen erst nach dem Runden hinzu, oder der Code läuft nicht in der Anfrage, die die Preise neu zeichnet. Diese Anleitung behandelt jeden dieser Fälle.

Zwei Filter, und warum Sie beide brauchen

FOX rechnet Preise an zwei Stellen um, und jede hat ihren eigenen Filter:

  • woocs_raw_woocommerce_price erhält jeden einzelnen umgerechneten Preis: einfache Produkte, jede Variante und, bei Mehrfach erlaubt (Is multiple allowed) = Nein (No), jeden in der gewählten Währung angezeigten Betrag.
  • woocs_woocommerce_variation_prices erhält die Preise, die WooCommerce für ein variables Produkt sammelt, um die Preisspanne zu bilden, das „45,37 – 61,20“ unter dem Titel. Er kommt bei Mehrfach erlaubt (Is multiple allowed) = Ja (Yes) zum Einsatz; bei Nein (No) wird die Spanne über den ersten Filter angezeigt.

Mit nur dem ersten Filter zeigt ein variables Produkt eine ungerundete Spanne und, sobald eine Variante gewählt ist, einen gerundeten Preis. Mit nur dem zweiten ist die Spanne gerundet, die gewählte Variante dagegen nicht. Hängen Sie dieselbe Funktion an beide.

Bei einer umgerechneten Währung erhalten beide Filter eine numerische Zeichenkette mit Punkt als Dezimaltrennzeichen, bereits auf die Einstellung Dezimalstellen (Decimal) aus dem Tab Währungen (Currencies) gerundet. Beide laufen außerdem für die Basiswährung, ohne Umrechnung, die Funktion muss also selbst entscheiden, welche Währungen sie anfasst.

Eine Rundungsfunktion als Ausgangspunkt

/*
 * Round converted prices per currency.
 * Child theme functions.php, or a snippets plugin set to run everywhere.
 */
function myshop_woocs_round_price($price) {
    global $WOOCS;
    if (!isset($WOOCS) || !is_numeric($price) || (float) $price <= 0) {
        return $price; // keep empty and free prices as they are
    }
    $p = (float) $price;

    switch ($WOOCS->current_currency) {
        case 'EUR':
        case 'GBP':
            $p = ceil($p) - 0.01;      // 45.37 -> 45.99
            break;
        case 'JPY':
            $p = ceil($p / 100) * 100; // 4,083 -> 4,100
            break;
        default:
            return $price;             // the base currency and all others stay exact
    }
    return $p > 0 ? $p : $price;
}
add_filter('woocs_raw_woocommerce_price', 'myshop_woocs_round_price');
add_filter('woocs_woocommerce_variation_prices', 'myshop_woocs_round_price');

Ersetzen Sie die Währungscodes und die Formeln durch Ihre eigenen. Dass die Basiswährung im switch fehlt, ist wichtig: Sonst würden auch die Preise gerundet, die Sie in Ihren Produkten eingetragen haben, und der eingegebene Betrag wäre nicht mehr der Betrag, den Sie berechnen.

Rundungsrezepte

Setzen Sie eine dieser Formeln anstelle der Zeilen im switch ein; $p ist der umgerechnete Preis.

ErgebnisFormel45,37 wird zu
Nächste ganze Zahlround($p)45
Ganze Zahl, immer auf- / abgerundetceil($p) / floor($p)46 / 45
Endung ,99, aufgerundetceil($p) - 0.0145,99
Endung ,99, nächstliegendround($p + 0.01) - 0.0144,99
Endung ,95, aufgerundetceil($p) - 0.0545,95
Nächste 0,50round($p * 2) / 245,50
Aufgerundet auf die nächste 5ceil($p / 5) * 550
Nächste 10 / 100 / 1000round($p, -1) / -2 / -350 / 0 / 0
Aufgerundet, Endung auf 9 (49, 149, 1.999)ceil($p / 10) * 10 - 149

Schritte von 100 oder 1000 ergeben nur bei Währungen Sinn, in denen die Preise so groß sind; die Null in der Tabelle ist die Warnung. Für Endungen wie ,99 muss die Währung zwei Dezimalstellen anzeigen: Ist Dezimalstellen (Decimal) auf 0 gesetzt, wird das Ergebnis als ganze Zahl angezeigt. Die kurzen FAQs zu 99 Cent, 50 Cent, ganzen Zahlen und 500er-Schritten zeigen Versionen für nur eine Währung.

Zwei Dinge sehen nach Runden aus, sind es aber nicht. Cent ausblenden (Hide cents) im Tab Währungen (Currencies) entfernt die Cent aus dem angezeigten Preis und lässt sie in der Warenkorbsumme stehen, ein als 45 angezeigtes Produkt wird also mit 45,37 berechnet. Preise ohne Cent (Prices without cents) im Tab Optionen (Options) berechnet die aufgeführten Währungen mit null Dezimalstellen neu, das ist echtes Runden auf ganze Zahlen; die Beschreibung der Option bittet darum, nach dem Aktivieren den Checkout zu testen, und dazu gehört auch eine Bestellung mit einem prozentualen Gutschein.

Festpreise, die Sie pro Währung eintragen, laufen ebenfalls durch woocs_raw_woocommerce_price. Eine Formel lässt einen Preis, der bereits zum Muster passt, unverändert, ein Festpreis von 19,99 bleibt also bei der ,99-Regel 19,99, aber aus einem Festpreis von 20 wird 19,99. Nehmen Sie solche Währungen aus dem switch heraus, wenn ihre Festpreise so bleiben sollen, wie Sie sie eingegeben haben.

Runden und Steuern

woocs_raw_woocommerce_price läuft auf dem Produktpreis, bevor WooCommerce die Steuer addiert oder abzieht. woocs_woocommerce_variation_prices ist anders: Zeigt der Shop Preise inklusive Steuer an, enthält die Spanne eines variablen Produkts, die der Filter erhält, die Steuer bereits. Was das bedeutet, hängt von Preise bei Eingabe inklusive Steuer (Prices entered with tax) und Preisanzeige im Shop (Display prices in the shop) unter WooCommerce → Einstellungen → Steuer ab.

Preise ohne Steuer eingegeben, mit Steuer angezeigt

WooCommerce addiert die Steuer auf Ihren gerundeten Nettopreis, und 45,99 plus 20 % wird als 55,19 angezeigt, während die nach der Steuer gerundete Spanne eines variablen Produkts auf ,99 endet. Damit jeder Preis, den der Kunde sieht, auf ,99 endet, runden Sie im ersten Filter den Bruttobetrag und rechnen ihn mit Ihrem Satz zurück, im zweiten Filter bleibt es bei der einfachen Formel. Das funktioniert, wenn für Ihre Kunden ein einziger Steuersatz gilt:

/*
 * .99 endings on prices shown with 20% tax. Child theme functions.php.
 */
add_filter('woocs_raw_woocommerce_price', function ($price) {
    global $WOOCS;
    if (!isset($WOOCS) || !is_numeric($price) || (float) $price <= 0
        || $WOOCS->current_currency === $WOOCS->default_currency) {
        return $price;
    }
    $tax = 1.20; // your tax rate
    return (ceil((float) $price * $tax) - 0.01) / $tax; // net price, shown with tax as .99
});

add_filter('woocs_woocommerce_variation_prices', function ($price) {
    global $WOOCS;
    if (!isset($WOOCS) || !is_numeric($price) || (float) $price <= 0
        || $WOOCS->current_currency === $WOOCS->default_currency) {
        return $price;
    }
    return ceil((float) $price) - 0.01; // the range already includes tax
});

Preise mit Steuer eingegeben

Beide Filter erhalten dann Bruttopreise, und Kunden, die mit Ihrem Basissteuersatz besteuert werden, sehen den gerundeten Preis unverändert. Bei einem Kunden in einem Land mit anderem Satz zieht WooCommerce Ihre Basissteuer ab und addiert seine, sodass aus 45,99 mit 20 % im Heimatland bei 17 % dann 44,84 werden. Wenn Sie überall denselben Bruttopreis wollen, gibt es dafür einen WooCommerce-Filter; die Marge schwankt dann stattdessen von Land zu Land:

add_filter('woocommerce_adjust_non_base_location_prices', '__return_false');

Wenn sich die Währung selbst nicht ändert, ist das übliches WooCommerce-Steuerverhalten und tritt genauso auf, wenn FOX deaktiviert ist.

Warenkorbsummen, Versand und ungefähre Preise

Bei Mehrfach erlaubt (Is multiple allowed) = Ja (Yes) wird der Warenkorb aus den gerundeten Produktpreisen berechnet, sodass Zeilensummen und Warenkorbsumme mit dem übereinstimmen, was der Kunde gesehen hat. Bei Nein (No) existieren umgerechnete Beträge nur auf dem Bildschirm: woocs_raw_woocommerce_price erhält jeden angezeigten Betrag, auch Zwischensummen des Warenkorbs, Versand- und Steuerzeilen, und rundet jeden einzeln, sodass die Zeilen nicht mehr zur Gesamtsumme passen müssen. Der Checkout zeigt dann die Basiswährung, die die obige Funktion unangetastet lässt. Stören Sie die gerundeten Warenkorbzeilen, geben Sie $price unverändert zurück, wenn is_cart() wahr ist.

Versandkosten sind keine Produktpreise und brauchen einen eigenen Filter. Bei Mehrfach erlaubt (Is multiple allowed) = Ja (Yes) rechnet FOX Versandtarife in woocommerce_package_rates mit Priorität 9999 um, das Runden muss also später laufen:

/*
 * Round converted shipping costs up to whole units, after FOX has converted them.
 * Child theme functions.php.
 */
add_filter('woocommerce_package_rates', function ($rates, $package) {
    global $WOOCS;
    if (!isset($WOOCS) || $WOOCS->current_currency === $WOOCS->default_currency) {
        return $rates;
    }
    foreach ($rates as $rate) {
        $cost = (float) $rate->get_cost();
        if ($cost <= 0) {
            continue; // free shipping stays free
        }
        $cost = ceil($cost);
        $rate->set_cost($cost);
        if (wc_tax_enabled() && !empty($rate->get_taxes()) && !WC()->customer->is_vat_exempt()) {
            $rate->set_taxes(WC_Tax::calc_shipping_tax($cost, WC_Tax::get_shipping_tax_rates()));
        }
    }
    return $rates;
}, 10000, 2);

WooCommerce speichert berechnete Tarife in der Kundensitzung. Ändern Sie beim Testen daher den Warenkorbinhalt oder die Adresse, um die neuen Kosten zu sehen.

Die ungefähren Beträge aus Ungefähren Preis anzeigen (Show approx. price) und Ungefähren Betrag anzeigen (Show approximate amount) werden direkt aus den Kursen berechnet und laufen nicht durch diese Filter, sie bleiben daher ungerundet.

Wenn das Runden nicht sichtbar wird

  • Alte Preise bei variablen Produkten. WooCommerce cacht die Preisspannen variabler Produkte. Löschen Sie sie nach dem Hinzufügen oder Ändern des Codes unter WooCommerce → Status → Werkzeuge → WooCommerce-Transients (WooCommerce transients) oder speichern Sie das Produkt, und leeren Sie den Seiten-Cache.
  • Beim ersten Laden gerundet, einen Moment später nicht mehr. Ist Ich verwende ein Cache-Plugin auf meiner Website (I am using cache plugin on my site) aktiviert, zeichnet FOX die Preise über admin-ajax.php neu. Ein Snippets-Plugin, das nur im Frontend läuft, läuft in dieser Anfrage nicht. Stellen Sie das Snippet so ein, dass es überall läuft, oder legen Sie den Code in die functions.php des Child-Themes.
  • Es ändert sich gar nichts. Lassen Sie die Funktion kurz eine Konstante wie 777 zurückgeben. Zeigen die Preise nicht 777, wird der Code nicht geladen, oder etwas anderes setzt die Preise: eine Preisvorlage eines Drittanbieters, ein Plugin für dynamische Preise oder Festpreise.
  • Fataler Fehler nach dem Einfügen. Von Webseiten kopierter Code enthält oft einen typografischen Gedankenstrich statt eines Minuszeichens, geschwungene Anführungszeichen oder &gt; statt >. Geben Sie diese Zeichen von Hand neu ein. Cannot redeclare bedeutet, dass derselbe Funktionsname zweimal eingefügt wurde; behalten Sie nur eine Kopie.
  • Preise wurden gerundet, die Sie nicht gerundet haben. Ein anderes Snippet oder Plugin verwendet denselben Filter. Durchsuchen Sie das Theme und die Snippets nach woocs_raw_woocommerce_price.

Checkliste

  • Eine Funktion, die an woocs_raw_woocommerce_price und an woocs_woocommerce_variation_prices hängt.
  • Die Basiswährung und jede Währung mit Festpreisen, die exakt bleiben sollen, ausgenommen.
  • Steuereinrichtung geprüft: Brutto-Runden oder woocommerce_adjust_non_base_location_prices, wo nötig.
  • Versand separat gerundet, mit einer Priorität über 9999.
  • WooCommerce-Transients und Seiten-Caches geleert, Code läuft in AJAX-Anfragen.

Werden die Preise mit einem Standard-Theme und nur WooCommerce und FOX als aktiven Plugins immer noch nicht gerundet, posten Sie Ihr Snippet und einen Produktlink im FOX-Support-Forum, und wir sehen es uns an.