Magento1.9 – How to Extend SOAP v2 API for Writable Order Attributes

apiattributescreate-ordermagento-1.9soap-api-v2

I have Amasty "Order Attributes" installed and working.
I need to be able to extend SOAP API v2 to allow me to programmatically create an order and update these custom order attributes.
What all needs to be extended to programmatically create an order with custom order attributes?
an example of a custom order attribute is "original_order_id"

UPDATE

Thanks to Alex and Kevin for answering it.

I have applied this process, modified heavily to suit the situation I'm coding for, up to the "update" method, however, I cannot get the order to accept these Amasty order attribute keys and values as $data.

The $order->save() does not update the data on the actual order.

    /**
 * Update order data
 *
 * @param int $orderIncrementId
 * @param array $data
 * @return boolean
 */
public function update($orderIncrementId, $data)
{
    $data = (array) $data;
    Mage::log('orderIncrementId:' . $orderIncrementId, null, 'apiFile.log');
    foreach ($data as $key => $value) {
        Mage::log($key . ':' . $value, null, 'apiFile.log');
    }

    $order = $this->_initOrder($orderIncrementId);
    foreach ($data as $key => $value) {
        $order->setData($key,$value);
    }
    $order->save();

    return true;
}

For the record, also tried $order->addData($data)->save(); with the same results.

My log file registers:

2015-12-23T22:13:53+00:00 DEBUG (7): erp_customer_id:WILSON
2015-12-23T22:13:53+00:00 DEBUG (7): original_order_id:100001767
2015-12-23T22:13:53+00:00 DEBUG (7): shipping_date:12/15/2015

Which is exactly the data I expect to see, but this data will not apply to the order. The data shown here follows the format key:value for simplicity.

When I manually create orders this data populates, but will not update the order through this API call. Any help would be greatly appreciated.

So close I can TASTE it! Currently, we are required to create brand new orders to update these fields with information from our ERP system.
I am very hopeful someone can help me avoid that fate.

In case it helps, here is the XML for the call:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:salesOrderUpdate soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <sessionId xsi:type="xsd:string">a9c83197fb991bc969e904594ee58777</sessionId>
         <orderIncrementId xsi:type="xsd:string">100001768</orderIncrementId>
         <data xsi:type="urn:salesOrderUpdateEntity">
            <!--You may enter the following 3 items in any order-->
            <!--Optional:-->
            <erp_customer_id xsi:type="xsd:string">WILSON</erp_customer_id>
            <!--Optional:-->
            <original_order_id xsi:type="xsd:string">100001767</original_order_id>
            <!--Optional:-->
            <shipping_date xsi:type="xsd:string">12/15/2015</shipping_date>
         </data>
      </urn:salesOrderUpdate>
   </soapenv:Body>
</soapenv:Envelope>

Best Answer

This post helped me when I add to do something similar.

First I had to create a module Rewrites_Sales overriding Mage_Sales_Model_Order_Api_V2 with this config.xml :

<?xml version="1.0"?>
<config>
    <modules>
        <Rewrites_Sales>
            <version>0.2.0</version>
        </Rewrites_Sales>
    </modules>
    <global>    
        <models>
            <sales>
                <rewrite>
                    <order_api_v2>Rewrites_Sales_Model_Order_Api_V2</order_api_v2>
                </rewrite>
            </sales>
        </models>
    </global>    
</config>

Next I created Rewrites/Sales/Model/Order/Api/V2.php like this :

<?php

class Rewrites_Sales_Model_Order_Api_V2 extends Mage_Sales_Model_Order_Api_V2
{

    /**
     * Prepare data to insert/update.
     * Creating array for stdClass Object
     *
     * @param stdClass $data
     * @return array
     */
    protected function _prepareData(&$data)
    {
        if (null === ($data = get_object_vars($data))) {
            $data = array();
        }
        return $data;
    }

    /**
     * Update customer data
     *
     * @param int $orderIncrementId
     * @param array $data
     * @return boolean
     */
    public function update($orderIncrementId, $data)
    {
        $order = $this->_initOrder($orderIncrementId);

        $this->_prepareData($data);

        $order->addData($data)
            ->save();

        return true;
    }

    /**
     * Create order
     *
     * @param int $orderIncrementId
     * @param array $data
     * @return boolean
     */
    public function create($data)
    {
        $order = Mage::getModel('sales/order');

        $this->_prepareData($data);

        $order->setData($data)
            ->save();

        return true;
    }

}

I declared my acl and resources in api.xml :

<?xml version="1.0"?>
<config>
    <api>
        <resources>
            <sales_order>
                <methods>
                    <update translate="title" module="sales">
                        <title>Update Order Attribute</title>
                        <acl>sales/order/update</acl>
                    </update>
                </methods>
            </sales_order>
        </resources>
        <acl>
            <resources>
                <sales>
                    <order>
                        <update translate="title" module="sales">
                            <title>Update order attributes</title>
                        </update>
                    </order>
                </sales>
            </resources>
        </acl>
        <!-- Same nodes for create resources & acl -->
    </api>
</config>

And finaly API calls were set in wsdl.xml :

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
    <message name="salesOrderUpdateRequest">
        <part name="sessionId" type="xsd:string" />
        <part name="orderIncrementId" type="xsd:string" />
        <part name="data" type="typens:salesOrderCreateEntity" />
    </message>
    <message name="salesOrderUpdateResponse">
        <part name="result" type="xsd:boolean" />
    </message>
    <portType name="{{var wsdl.handler}}PortType">
        <operation name="salesOrderUpdate">
            <documentation>Update order attributes</documentation>
            <input message="typens:salesOrderUpdateRequest" />
            <output message="typens:salesOrderUpdateResponse" />
        </operation>
    </portType>
    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="salesOrderUpdate">
            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
            <input>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
        </operation>
    </binding>
    <!-- Reproduce same nodes for create method -->
</definitions>
Related Topic