Prestashop 1.6 API Update Product Quantity

10,463

Solution 1

As you say, the field "quantity" in a product is write-protected, and in the schema "stock_available" you have a quantity field that you can write. Indeed, this is the field you should write.

You don't have to touch the DB; you can update the stock directly through the WS.

The schema "stock_availables" stores the ids of all the combinations of the products you have in your store. This is what the schema has:

<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
  <stock_available>
  <id_product required="true" format="isUnsignedId"/>
  <id_product_attribute required="true" format="isUnsignedId"/>
  <id_shop format="isUnsignedId"/>
  <id_shop_group format="isUnsignedId"/>
  <quantity required="true" format="isInt"/>
  <depends_on_stock required="true" format="isBool"/>
  <out_of_stock required="true" format="isInt"/>
 </stock_available>
</prestashop>

The id_product_attribute refers to one combination of a product. If this attribute has a zero, it means that the product doesn't have any combination. As I say, this schema stores all the combinations of the products you have (all of them), so if a product has more than one combination, you'll have to look for it.

There are 3 schemas where the quantity field apears: products, combinations and stock_availables. Only the last one is "used". The first one is write protected and the second one, as I could investigate, is not used by the back store.

I hope this can help you and sorry for my poor english.

Solution 2

Here is how u create a product and change the quantity

    try{
        $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);

        $opt = array('resource' => 'products');

        $opt['postXml'] = $new_xml_content;
        $xml = $webService->add($opt);

        $id = $xml->children()->children()->id;


        return $xml;
    }
    catch (PrestaShopWebserviceException $e)
    {
    }

getIdStockAvailableAndSet($new_xml->product->id);

function set_product_quantity($ProductId, $StokId, $AttributeId){
        $xml = $this->getWebService() -> get(array('url' => PS_SHOP_PATH . '/api/stock_availables?schema=blank'));
        $resources = $xml -> children() -> children();
        $resources->id = $StokId;
        $resources->id_product  = $ProductId;
        $resources->quantity = 10000000;
        $resources->id_shop = 1;
        $resources->out_of_stock=1;
        $resources->depends_on_stock = 0;
        $resources->id_product_attribute=$AttributeId;
        try {
            $opt = array('resource' => 'stock_availables');
            $opt['putXml'] = $xml->asXML();
            $opt['id'] = $StokId ;
            $xml = $this->getWebService()->edit($opt);
        }catch (PrestaShopWebserviceException $ex) {
            echo "<b>Error al setear la cantidad  ->Error : </b>".$ex->getMessage().'<br>';
        }
    }


    function getIdStockAvailableAndSet($ProductId){
        global $webService;
        $opt['resource'] = 'products';
        $opt['id'] = $ProductId;
        $xml = $webService->get($opt);
        foreach ($xml->product->associations->stock_availables->stock_available as $item) {
            //echo "ID: ".$item->id."<br>";
            //echo "Id Attribute: ".$item->id_product_attribute."<br>";
            set_product_quantity($ProductId, $item->id, $item->id_product_attribute);
        }
    }

Solution 3

I wanted to share my solution of a product quantity update(in hope to help someone else). It may not be the best solution, but what the hek, it works (for me).

As Jarlaxxe says: The way to edit product quantity is via: api/stock_availables. So in order to geet the stock_availables ID you first need to get productinformation and retrieve stock_availables ID from there, and then put.

$webService = new PrestaShopWebservice('http://yoursite.com', 'LADEDILADEDA-BTW-YOUR-API-KEY-HERE', false);
    updateStock(productnumber, quantity);

    function updateStock($productID, $quantity){
        //First we got the stock_availables ID from the Product ID
        try
        {
            $opt = array('resource' => 'products');
            $opt['id'] = $productID;
            $xml = $webService->get($opt);
            $resources = $xml->children()->children();
            $stockID = $resources->associations->stock_availables->stock_availables;

            foreach($stockID as $stock){                
                $stockAVailableID = $stock->id;
            }

        }
        catch (PrestaShopWebserviceException $e)
        {
            $trace = $e->getTrace();
            if ($trace[0]['args'][0] == 404) echo 'Bad ID';
            else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
            else echo 'Other error<br />'.$e->getMessage();
        }   

        //Second we get all the stockAvailables resources
        try
        {
            $opt = array('resource' => 'stock_availables');
                $opt['id'] = $stockAVailableID;
            $xml = $webService->get($opt);
            $resources = $xml->children()->children();
        }
        catch (PrestaShopWebserviceException $e)
        {
            $trace = $e->getTrace();
            if ($trace[0]['args'][0] == 404) echo 'Bad ID';
            else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
            else echo 'Other error<br />'.$e->getMessage();
        }


        //At last we update the quantity with the given value manupulated and all other values original
        foreach ($resources as $nodeKey => $node)
        {
            if($nodeKey == 'quantity'){
                unset($node);
                $node = $quantity;
            }
            $resources->$nodeKey = $node;
        }
        try
        {
            $opt = array('resource' => 'stock_availables');
            $opt['putXml'] = $xml->asXML();
            $opt['id'] = $stockAVailableID;
            $xml = $webService->edit($opt);
            echo "Successfully updated.";
        }
        catch (PrestaShopWebserviceException $ex)
        {
            $trace = $ex->getTrace();
            if ($trace[0]['args'][0] == 404) echo 'Bad ID';
            else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
            else echo 'Other error<br />'.$ex->getMessage();
        }
    }   
Share:
10,463
IeM
Author by

IeM

Updated on September 01, 2022

Comments

  • IeM
    IeM over 1 year

    I'm making a bridging app. to sync product quantities from a warehouse DB with a Prestashop 1.6 Multi-Store cart.

    The script just needs to update one product quantity at a time and we have the product "ID" and the "quantity", however, I keep getting the following error returned:

    RETURN HTTP BODY
    <?xml version="1.0" encoding="UTF-8"?>
    <prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
    <errors>
    <error>
    <code><![CDATA[93]]></code>
    <message><![CDATA[parameter "quantity" not writable. Please remove this attribute of this XML]]></message>
    </error>
    </errors>
    </prestashop>
    

    This comes with: Other error This call to PrestaShop Web Services failed and returned an HTTP status of 400. That means: Bad Request.

    XML error code 93 is The table is not present in the descriptor. I thought this was done by including "$opt = array('resource' => 'products');"

    Advanced Stock control is also enabled on the site and this script does not make adjustments with it(One should also include this, maybe next version).

    The code I'm using to get the XML, change the quantity value, and update is:

    function test1($id, $quantity){
        $id = (int)$id;
        $quantity = (int)$quantity;
    
        try
        {
            $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
            $opt = array('resource' => 'products', 'display' => '[id,quantity]');
            if (isset($id))
                $opt['id'] = $id;
            $xml = $webService->get($opt);
    
            $resources = $xml->children()->children();
        }
        catch (PrestaShopWebserviceException $e)
        {
            // Dealing with errors
            $trace = $e->getTrace();
            if ($trace[0]['args'][0] == 404) echo 'Bad ID';
            else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
            else echo 'Other error<br />'.$e->getMessage();
        }
    
        if (isset($id) && isset($quantity)){
    
            $resources->id = $id;
            $resources->quantity = $quantity;
            // Call the web service
            try
            {
                $opt = array('resource' => 'products');
                $opt['putXml'] = $xml->asXML();
                $opt['id'] = $id;
                $xml = $webService->edit($opt);
                echo "Successfully updated.";
            }
            catch (PrestaShopWebserviceException $ex)
            {
                // Here we are dealing with errors
                $trace = $ex->getTrace();
                if ($trace[0]['args'][0] == 404) echo 'Bad ID';
                else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
                else echo 'Other error<br />'.$ex->getMessage();
            }
        }
    }
    

    The initial XML returned that I use to update is:

    <?xml version="1.0" encoding="UTF-8"?>
    <prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
    <product id="45" xlink:href="https://www.WEBSITE.com/api/products/45"/>
    </prestashop>
    

    The XML that was sent for the Update is:

    <?xml version="1.0" encoding="UTF-8"?>
    <prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
    <product id="45" xlink:href="https://www.WEBSITE.com/api/products/45"><id>45</id><quantity>22</quantity></product>
    </prestashop>
    

    It seems that the sent XML or something is missing the table reference or something.

    I've tried a couple ways all with the same result. Any ideas?

    Thanks

  • IeM
    IeM over 8 years
    Thanks Jarlaxxe and you did well with the english. I've had to move on to other issues for the moment but look forward to working with your suggestions when I can.
  • Elia Weiss
    Elia Weiss over 8 years
    Please try to write more simple and to the point, I don't understand what to do