Kurzinfo


Andreas von Studnitz

mehr »

Andreas von Studnitz arbeitet seit 2012 als Geschäftsführer und Entwickler für die Magento-Agentur integer_net GmbH. Aktuelle Informationen finden Sie unter www.integer-net.de

Kontakt

Telefon:
0170 486 0 464

E-Mail:
avs(at)avs-webentwicklung.de

Twitter: twitter.com/avstudnitz

mehr »

< Magento: Import von Kategorieverknüpfungen zu Produkten

Magento: Verbergen anderer Versandarten bei Versandkostenfreiheit - the right way

06.02.2012 20:44

In Magento kann Versandkostenfreiheit ab x Euro eingestellt werden. Hierfür gibt es eine eigene Versandart namens "Freeshipping". Häufig ist es sinnvoll, dass, wenn der Kunde diese Grenze erreicht hat, alle anderen Versandarten ausgeblendet werden.

Im Magento-Standard geht dies leider nicht. Im Internet kursieren einige Lösungen dazu, die häufig nur das Template anpassen, in anderen Fälle Blöcke oder Models "rewriten". All diese Lösungen sind qualitativ nicht hochwertig, da es bei Rewrites Konflikte geben kann (und erfahrungsgemäß auch immer wieder gibt) und im Template höchstens die Ausgabe entfernt wird, und nicht an der Quelle in den Prozess eingegriffen wird. Dazu kommt, dass Templates häufig auch von Themes überschrieben werden.

Mit Erfahrung und manchmal etwas Suchen lässt sich für sehr viele Anforderungen eine Lösung ohne Rewrites finden, so auch hier, wenn auch diese nicht offensichtlich ist. 

Der Ansatz ist, die Collection Mage_Sales_Model_Resource_Quote_Address_Rate_Collection zu überwachen. Hierfür wird das Event core_collection_abstract_load_after überwacht, das nach dem Laden beliebiger Collections anschlägt. Folgender Code muss also in die config.xml eines eigenen Moduls:

<frontend>
...
<events>
<core_collection_abstract_load_after>
<observers>
<mymodule_collection_load_after>
<type>singleton</type>
<class>mymodule/observer</class>
<method>afterLoadCollection</method>
</mymodule_collection_load_after>
</observers>
</core_collection_abstract_load_after>
</events>
</frontend>

Die Methode afterLoadCollection in der genannten Klasse (z.B. unter app/code/local/MyCompany/MyModule/Model/Observer.php) sieht dann wie folgt aus:

/**
 * If Freeshipping method is allowed, disallow all other shipping methods
 *
 * @param Varien_Event_Observer $observer
 * @return void
 */
public function afterLoadCollection($observer)
{
    $collection = $observer->getCollection();
    
    if (!$collection instanceof Mage_Sales_Model_Resource_Quote_Address_Rate_Collection) return;

    if (!$this->_isFreeshippingIncluded($collection)) return;

    $shippingAddress = Mage::getSingleton('checkout/session')
        ->getQuote()
        ->getShippingAddress();

    $shippingAddress->setLimitCarrier('freeshipping');
}

/**
 * Checks if freeshipping method is included in collection fo available shipping methods
 *
 * @param Mage_Sales_Model_Resource_Quote_Address_Rate_Collection $rateCollection
 * @return boolean
 */
protected function _isFreeshippingIncluded($rateCollection)
{
    foreach ($rateCollection as $rate) {

        /** @var $rate Mage_Sales_Model_Quote_Address_Rate */
        if ($rate->getMethod() == 'freeshipping') {
            return true;
        }
    }
    return false;
}

Es werden also nur Collections vom Typ Mage_Sales_Model_Resource_Quote_Address_Rate_Collection überwacht. Anschließend wird überprüft, ob die Methode "freeshipping" enthalten ist. Nur wenn dies der Fall ist, wird auf die Versandadresse die Methode setLimitCarrier angewendet, die die verfügbaren Versandarten einschränkt.

 

Kommentare

Alexander Menk, 07.02.12 09:40:
Interessante Lösung.

Schade, dass das Event für jede Collection abgefeuert wird.
Führt das nicht zu Performance-Einbußen?
Akimo , 21.02.12 18:00:
Das event scheint mir besser: sales_quote_address_load_after. Im eventhandler sollte man noch prüfen, ob es die Lieferadresse ist.
Kommentar hinzufügen












Den Code eingeben: *


* - Pflichtfeld