Magento-API: Bestellte Produkte mit parent_item_id abfragen

Bestellungen können in Magento über die API ausgelesen und von einer externen Software (z. B. Warenwirtschaft, Fakturierung) importiert werden.

Wenn in einer Bestellung jedoch zusammengesetzte Produkte wie Bündelartikel (bundle product) enthalten sind, wird die Spalte parent_item_id bei der API-Abfrage der Bestellposten standardmäßig nicht übermittelt. Diese Spalte ist aber entscheidend, um einzelne Teilprodukte dem Hauptprodukt zuordnen zu können!

Dies hängt damit zusammen, dass jedes Attribut für die Ausgabe explizit in der WSDL-Definitionsdatei angegeben werden muss. In der mitgelieferten WSDL-Definition für Bestellposten wurde die Spalte parent_item_id offenbar vergessen. In der aktuellen Magento-Version 1.9.0.1 (vom 16.05.2014) ist das immer noch der Fall.

Durch eine Anpassung der WSDL-Definition, kann die Spalte parent_item_id (und weitere Spalten, die in der SQL-Tabelle sales_flat_order_item zu finden sind) nachträglich eingefügt und über die API ausgegeben werden.

Dazu wird die Datei app/code/core/Mage/Sales/etc/wsdl.xml direkt im core-Verzeichnis angepasst! Die angepasste Datei app/code/local/Mage/Sales/etc/wsdl.xml im local-Code-Pool wird von Magento (nach Löschung des gesamten Magento-Caches) leider ignoriert. Wenn es eine elegantere Methode für diese Anpassung gibt, freuen wir uns über Ihre Kommentare.

Die fehlende Spalte parent_item_id wird ähnlich wie andere Spalten (z. B. item_id) hinzugefügt.

<complexType name="salesOrderItemEntity">
    <all>
        ...
        <element name="parent_item_id" type="xsd:string" minOccurs="0" />
        ...

Der guten Ordnung halber haben wir die Spalte parent_item_id genau dort eingefügt, wo sie in der ursprünglichen Tabelle sales_flat_order_item zu finden ist, zwischen order_id und quote_item_id:

<complexType name="salesOrderItemEntity">
    <all>
        <element name="item_id" type="xsd:string" minOccurs="0" />
        <element name="order_id" type="xsd:string" minOccurs="0" />
        <element name="parent_item_id" type="xsd:string" minOccurs="0" />
        <element name="quote_item_id" type="xsd:string" minOccurs="0" />
        <element name="created_at" type="xsd:string" minOccurs="0" />
        <element name="updated_at" type="xsd:string" minOccurs="0" />
        <element name="product_id" type="xsd:string" minOccurs="0" />
        <element name="product_type" type="xsd:string" minOccurs="0" />
        <element name="product_options" type="xsd:string" minOccurs="0" />
        <element name="weight" type="xsd:string" minOccurs="0" />
        <element name="is_virtual" type="xsd:string" minOccurs="0" />
        <element name="sku" type="xsd:string" minOccurs="0" />
        <element name="name" type="xsd:string" minOccurs="0" />
        <element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
        <element name="free_shipping" type="xsd:string" minOccurs="0" />
        <element name="is_qty_decimal" type="xsd:string" minOccurs="0" />
        <element name="no_discount" type="xsd:string" minOccurs="0" />
        <element name="qty_canceled" type="xsd:string" minOccurs="0" />
        <element name="qty_invoiced" type="xsd:string" minOccurs="0" />
        <element name="qty_ordered" type="xsd:string" minOccurs="0" />
        <element name="qty_refunded" type="xsd:string" minOccurs="0" />
        <element name="qty_shipped" type="xsd:string" minOccurs="0" />
        <element name="cost" type="xsd:string" minOccurs="0" />
        <element name="price" type="xsd:string" minOccurs="0" />
        <element name="base_price" type="xsd:string" minOccurs="0" />
        <element name="original_price" type="xsd:string" minOccurs="0" />
        <element name="base_original_price" type="xsd:string" minOccurs="0" />
        <element name="tax_percent" type="xsd:string" minOccurs="0" />
        <element name="tax_amount" type="xsd:string" minOccurs="0" />
        <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
        <element name="tax_invoiced" type="xsd:string" minOccurs="0" />
        <element name="base_tax_invoiced" type="xsd:string" minOccurs="0" />
        <element name="discount_percent" type="xsd:string" minOccurs="0" />
        <element name="discount_amount" type="xsd:string" minOccurs="0" />
        <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
        <element name="discount_invoiced" type="xsd:string" minOccurs="0" />
        <element name="base_discount_invoiced" type="xsd:string" minOccurs="0" />
        <element name="amount_refunded" type="xsd:string" minOccurs="0" />
        <element name="base_amount_refunded" type="xsd:string" minOccurs="0" />
        <element name="row_total" type="xsd:string" minOccurs="0" />
        <element name="base_row_total" type="xsd:string" minOccurs="0" />
        <element name="row_invoiced" type="xsd:string" minOccurs="0" />
        <element name="base_row_invoiced" type="xsd:string" minOccurs="0" />
        <element name="row_weight" type="xsd:string" minOccurs="0" />
        <element name="gift_message_id" type="xsd:string" minOccurs="0" />
        <element name="gift_message" type="xsd:string" minOccurs="0" />
        <element name="gift_message_available" type="xsd:string" minOccurs="0" />
        <element name="base_tax_before_discount" type="xsd:string" minOccurs="0" />
        <element name="tax_before_discount" type="xsd:string" minOccurs="0" />
        <element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
        <element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
        <element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
        <element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
        <element name="base_weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
        <element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
        <element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
        <element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
        <element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
    </all>
</complexType>

Nach dieser Anpassung muss neben dem Magento-Cache „Konfiguration“ in System > Cache-Verwaltung, noch der WSDL-Cache geleert werden, sofern dieser aktiviert war. Die Einstellung dazu finden Sie in System > Konfiguration > Services: Magento Core API:

Für bessere Performance der API-Abfragen empfehlen wir den WSDL-Cache zu aktivieren bzw. aktiviert zu lassen. Der WSDL-Cache wird durch Deaktivierung im Magento-Backend nicht gelöscht! Dazu müssen die Dateien im Systemverzeichnis des WSDL-Cache über die Kommandozeile entfernt werden. Je nach Serverkonfiguration, kann der WSDL-Cache sich in einem anderen Verzeichnis befinden, das über phpinfo() herausgefunden werden kann:

In unserer Serverumgebung befindet sich der WSDL-Cache in /tmp (STRG+F nach soap.wsdl_cache_dir) und kann wie folgt geleert werden:

cd /tmp
rm -rf *

Mit dem folgenden Beispielcode kann ein PHP-Client einzelne Produkte einer Bestellung ausgeben:

<pre><?php
$client = new SoapClient('http://beispiel.de/index.php/api/v2_soap/?wsdl');
$session = $client->login('api-user', 'geheim123');

$result = $client->salesOrderInfo($session, '1000000001');
$items = $result->items;
foreach($items as $item) {
    print 'item_id:'.$item->item_id."\n";
    print 'product_type:'.$item->product_type."\n";
    if(isset($item->parent_item_id)) print 'parent_item_id:'.$item->parent_item_id."\n";
    print 'name:'.$item->name."\n";
    print "--------------------------\n";
}

In der Beispielausgabe ist das erste Produkte mit der item_id=10 ein Bündelprodukt, welches such aus den unterstehenden einfachen Produkten zusammensetzt, was über die parent_item_id=10 nachvollziehbar ist:

item_id:10
product_type:bundle
name:Beispiel-Bündelprodukt
--------------------------
item_id:5
product_type:simple
parent_item_id:10
name:Einfaches-Produkt-1
--------------------------
item_id:12
product_type:simple
parent_item_id:10
name:Einfaches-Produkt-2
--------------------------
item_id:7
product_type:simple
parent_item_id:10
name:Einfaches-Produkt-3

2 Gedanken zu „Magento-API: Bestellte Produkte mit parent_item_id abfragen“

  1. Sehr hilfreicher Artikel! Auf der Suche nach der Lösung eines anderen Problems, haben wir Deinen Artikel gefunden und dadurch gleich ein Problem auf unserer ToDo Liste streichen können! 🙂 Vielen Dank für deinen wirklich sehr nützlichen Beitrag, gerade wenn man mit dieser Problematik zu kämpfen hat.

    Vielleicht kannst Du uns bei der folgenden Aufgabenstellung weiterhelfen:
    Wir haben ein Produkt-Attribut mit dem Namen“ Product Processing Status“ angelegt:
    1. Artikelstatus bei Bestelleingang ist immer:“Artikel nicht auf Lager. Artikel wird für Sie bestellt“
    Kunde legt Bestellung mit Artikel an. Den Verarbeitungsstatus seines Artikels soll er in seinem Kundenkonto in der Bestellung einsehen können.
    2. Artikel für Kunde trifft bei uns an: Artikel Status neu setzen: „Artikel eingegangen und wird an Sie versendet.“

    Und hier haben wir wieder ein ähnliches Problem:
    SOAP V2 kann Attribute innerhalb der Artikelverwaltung wunderbar ändern.
    Produkt Attribute/Status für Artikel innerhalb einer Bestellung können wir damit nicht verändern.
    Es gibt in Magento die Tabelle catalog_product_entity und die abhängigen Tabellen catalog_product_…….).
    Über SOAP API kann man Attribute der Artikel über ProdID wunderbar ändern. Aber das brauchen wir nicht.

    Wenn der Kunde eine Bestellung durchführt, dann werden die bestellten Artikel in die Tabelle sales_flat_order_item kopiert. Und genau die bestellten Artikel Stati/Attribute möchten wir korrigieren.
    Aber die SOAP API Funktion passt für den Zweck gar nicht, da sie nur die Artikelstammdaten per ProdID korrigiert.

    Hast du eine Lösung gefunden, wie man mit SOAP V2 den Status eines Artikels bzw. Artikel Attribute in einer Bestellung ändert?

    Wir sind für alle Ideen oder Anregungen offen 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.