Türchen 11: Gruppenpreise über die SOAP v2 API

Vor einiger Zeit stand ich vor der Aufgabe, Gruppenpreise über die SOAPv2 API von Magento 1.7.0.2 zu importieren.
Wie ich zu meiner Überraschung einige stackoverflow-Beiträge und Magento-Issues aus dem Bugtracker später herausfinden musste, unterstützt die SOAPv2 API den Import von Gruppenpreisen nicht. Nach einem ungläubigen Moment und ein paar weiteren Tests (der Schock saß noch immer tief ;-) ) war ich also bereit, meine eigene Lösung in Angriff zu nehmen.

Wie übergibt Magento die Gruppenpreise im Backend?

Das war die Frage, die ich mir dazu initial gestellt habe. Was brauche ich also alles, um Gruppenpreise zu speichern? Ich wurde fündig in app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php. Eine Debug-Ausgabe von $this->getRequest()->getPost() in der saveAction zeigt, dass die Gruppenpreise wie folgt übergeben werden:

["group_price"]=> array(2) {
[0]=> array(4) {
    ["website_id"]=> string(1) "0"
    ["cust_group"]=> string(1) "1"
    ["price"]=> string(5) "12.00"
    ["delete"]=> string(0) ""
}
[1]=> array(4) {
    ["website_id"]=> string(1) "0" 
    ["cust_group"]=> string(1) "0" 
    ["price"]=> string(5) "11.00" 
    ["delete"]=> string(0) "" } 
}

Notwendig sind also die Attribute website_id (Website), cust_group (Kundengruppe), price (Preis) und delete (Leerstring bzw. 1 im Falle des Löschens). Mein Aufruf über die SOAP API soll diesem Schema folgen.

Das Modul

Was ist zu tun? Ein eigenes Modul muss her. Meines heißt hier beispielsweise Avoe_Catalog.
Wir brauchen darin:

  • etc/config.xml
  • Model/Product/Api/V2.php
  • Model/Product/Attribute/Groupprice/Api/V2.php

Avoe/Catalog/etc/config.xml

Wir überschreiben die Product API mit folgenden Zeilen:
<global>
    <models>
    	<avoecatalog>
    		<class>Avoe_Catalog_Model</class>
    	</avoecatalog>
    	
        <catalog>
            <rewrite>
                <product_api_v2>Avoe_Catalog_Model_Product_Api_V2</product_api_v2>
            </rewrite>
        </catalog>          
    </models>

</global>

Avoe/Catalog/Model/Product/Api/V2.php

Klassendefinition
class Avoe_Catalog_Model_Product_Api_V2 extends Mage_Catalog_Model_Product_Api_V2 { ... }
In der Methode _prepareDataForSave habe ich, nach der Abfrage für die Staffelpreise (tier_price) folgende Abfrage ergänzt:
if (property_exists($productData, 'group_price')) {
             $groupPrices = Mage::getModel('avoecatalog/product_attribute_groupprice_api_V2')
                 ->prepareGroupPrices($product, $productData->group_price);
             $product->setData("group_price", $groupPrices);
}

Avoe/Catalog/Model/Product/Attribute/Groupprice/Api/V2.php

Die Datei ist eine Kopie von Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php
class Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2 extends Mage_Catalog_Model_Product_Attribute_Tierprice_Api
Den Umweg über die SOAPv2 API lasse ich hier weg, deshalb lautet meine Klassendefinition:
class Avoe_Catalog_Model_Product_Attribute_Groupprice_Api_V2 extends Mage_Catalog_Model_Api_Resource { ... }
Der Inhalt der Klasse ist, wie oberhalb erwähnt, eine Kopie von Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2 mit jenen Änderungen, dass ich $tierPrices gegen $groupPrices ersetzt habe sowie die Abfragen der if's entsprechend jenen der Gruppenpreis-Attribute (cust_group, pricem website_id) angepasst.

Aufruf an die SOAP-API

Der Demo-Aufruf lautet nun:
$newProductData = new stdClass();
$additionalAttrs = array();

$gp = array(
	"0" => array (
        	"website_id" => "0",
        	"cust_group" => "1",
        	"price" => "11.11",
        	"delete" => "1"
    	),
	"1" => array (
	        "website_id" => "0",
	        "cust_group" => "0",
	        "price" => "12.12"
	    )
	);

$gp = array("key" => "group_price", "value" => array(serialize($gp[0]),serialize($gp[1])));

$additionalAttrs['multi_data'][] = $gp;
$newProductData->additional_attributes = $additionalAttrs;

$result = $client->catalogProductUpdate($sessionId,$prodSku,$newProductData,"","sku");
Zugegeben, der Teil mit dem Aufruf von array(serialize($gp[0]),serialize($gp[1]))); als Value ist nicht besonders schön. Allerdings funktioniert das Auslesen der Werte auf dem Server sonst nicht mehr.

Warum?

Sehen wir uns dazu Teile der WSDL genauer an:
<complexType name="associativeMultiArray">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="typens:associativeMultiEntity[]"/>
</restriction>
</complexContent>
</complexType>

<complexType name="associativeMultiEntity">
<all>
<element name="key" type="xsd:string"/>
<element name="value" type="typens:ArrayOfString"/>
</all>
</complexType>

<complexType name="ArrayOfString">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
Der Aufruf erfolgt über multi_data (typ: associativeMultiArray lt. WSDL), also über ein Array von Attributen, welches wiederum mehrere Werte enthalten kann. Nicht zuletzt ergibt sich (wenn man den Typdefinitionen in der WSDL folgt) aufgrund der Definition von die Tatsache, dass hier Strings übergeben werden. Die Erweiterung, um dem Import und das Löschen der Gruppenpreise für die SOAPv2 API verfügbar zu machen ist also nicht allzu schwer, hat aber ein bisschen an Recherche im Core und in der WSDL gebraucht. Ich wünsche viel Erfolg bei der Erweiterung! Für den Fall das jemand von euch die API ebenfalls schon für Gruppenpreise erweitert haben sollte, bin ich gespannt auf eure Lösungen.


Ein Beitrag von Anna Völkl
Anna's avatar

Anna Völkl arbeitet in Wien bei der Online-Agentur LimeSoda und ist dort für Webshop-Projekte verantwortlich. Sie arbeitet seit 2011 mit Magento und ist Magento Certified Developer. Ihre Lieblingsthemen sind DevOps und IT-Sicherheit. Aus Zeitgründen bloggt sie nicht sehr häufig, twittert aber fleißig.

Alle Beiträge von Anna

Kommentare
Rajan am

Hi ,

Need you help please.

I have implemented this module and give me error SoapFault: Duplicate website group price customer group.

Use API v2 to work with Customer Group Prices | DL-UAT am

[…] for importing group prices with SOAPv2 for Magento CE 1.7.0.2 some time ago and wrote a a (german) blogpost about this (Google translate might help). I added the important parts with an english explanation […]

Use API v2 to work with CustomerI Group Prices | DL-UAT am

[…] for importing group prices with SOAPv2 for Magento CE 1.7.0.2 some time ago and wrote a a (german) blogpost about this (Google translate might help). I added the important parts with an english explanation […]

Dein Kommentar