Neueste Blog-Einträge
Kurzinfo

Andreas von Studnitz
- Diplom-Informatiker
- 6 Jahre Entwicklungs- und Projektleitungserfahrung in einer Internet-Agentur
- Magento-Freelancer
- Magento Certified Developer
- 4 Jahre Magento-Erfahrung
Kontakt
Telefon:
02408 937 965 1 oder
0170 486 0 464
E-Mail:
avs(at)avs-webentwicklung.de
Twitter: twitter.com/avstudnitz
Magento: Verbergen anderer Versandarten bei Versandkostenfreiheit - the right way
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.

Schade, dass das Event für jede Collection abgefeuert wird.
Führt das nicht zu Performance-Einbußen?
Kommentar hinzufügen