Jump to content

Show warehouse stock on product page?


Recommended Posts

  • 1 month later...
  • 2 years later...

An idea of solution:

 

you can modify ProductController.php by override. In this file, in the initContent() function, you can do something like that:

$warehouses_product =  Warehouse::getProductWarehouseList((int)$this->product->id);

$warehouses_stock = array();

if (!empty($warehouses_product))
{
    foreach ($warehouses_product  as $wp)
    {
       $warehouse_data = array();
       $warehouse_data['name'] = $wp['name'];
       $warehouse_data['stock'] = Product::getRealQuantity((int)$this->product->id, 0, $wp['id_warehouse']);
       $warehouses_stock[] = $warehouse_data;
    }
   if (!empty($stock_warehouses))
       $this->context->smarty->assign(array( 'warehouses_stock' => $warehouses_stock));
}

Then in your product.tpl, you use a foreach loop on warehouses_stock array to display information in a table.

Link to comment
Share on other sites

An idea of solution:

 

you can modify ProductController.php by override. In this file, in the initContent() function, you can do something like that:

$warehouses_product =  Warehouse::getProductWarehouseList((int)$this->product->id);

$warehouses_stock = array();

if (!empty($warehouses_product))
{
    foreach ($warehouses_product  as $wp)
    {
       $warehouse_data = array();
       $warehouse_data['name'] = $wp['name'];
       $warehouse_data['stock'] = Product::getRealQuantity((int)$this->product->id, 0, $wp['id_warehouse']);
       $warehouses_stock[] = $warehouse_data;
    }
   if (!empty($stock_warehouses))
       $this->context->smarty->assign(array( 'warehouses_stock' => $warehouses_stock));
}

Then in your product.tpl, you use a foreach loop on warehouses_stock array to display information in a table.

 

thank you fred vinapresta,  this feature very important for who's running a store with multiple branches,  

 

i will try it although i cant do code :)

 

 

Nope. It became a hot mess so the store was abandoned in favour of shopify.

 

 

 

thank you edzio, i hope the presta team will inculde this feature in the next update

Link to comment
Share on other sites

  • 1 month later...

thank you fred vinapresta,  this feature very important for who's running a store with multiple branches,  

 

i will try it although i cant do code :)

 

 

 

 

thank you edzio, i hope the presta team will inculde this feature in the next update

 

Can you tell us please what code exactly should I put on product.tpl to make it work? Thankyou!

Link to comment
Share on other sites

  • 1 month later...
  • 3 weeks later...
  • 1 month later...

Please, can someone post the "foreach" loop that we should use to retrieve warehouses list with the code mentionned in this previous post ?

 

Thanks ;)

 

I've never used smarty and cannot seem to guess how to loop through this array.

 

Tried something like this, but it will obviously not work :

 

{foreach from=$warehouses_stock item=wareHouse}
    <p>{$wareHouse.name|escape:'html':'UTF-8'}</p>
{/foreach}
Edited by mlcrpc (see edit history)
Link to comment
Share on other sites

DON'T USE THIS ANYMORE, PLEASE READ MY OTHER SOLUTION POSTED BELOW https://www.prestashop.com/forums/topic/199256-show-warehouse-stock-on-product-page/?p=2072064 )

 

 

 

 

 

-------------------------------------------------------------------------------------------------------

 

- Find and copy ProductController.php from "controllers/front/"

 

- Paste it to "override/controllers/front"

 

- Open the new file

 

FIND

public function initContent()
{
    parent::initContent();
    if (!$this->errors)
    {   

AFTER, INSERT

            $id_product = (int)Tools::getValue('id_product'); 
            $sql = 'SELECT name,physical_quantity FROM ps_warehouse,ps_stock WHERE id_product ='.$id_product.' AND ps_warehouse.id_warehouse = ps_stock.id_warehouse';
            if ($results = Db::getInstance()->ExecuteS($sql))
                foreach ($results as $row)
                    $warehouses[] = array($row['name'],$row['physical_quantity']);
                        
            $this->context->smarty->assign(array(
                            'warehouse' => $warehouses)); 

- Open product.tpl from "themes/default-bootstrap" (or whatever your theme is)

 

- Where you want to display the warehouses names and available stocks :

 

PASTE

<p>Warehouse(s) :</p>
{foreach from=$warehouse item=w}
    {if $w[1]>0}                    
        <p>{$w[0]} ({$w[1]})</p>
    {/if}
{/foreach}

Update : New condition so warehouses without stock are not shown.

Edited by mlcrpc (see edit history)
Link to comment
Share on other sites

Found a better and cleaner way to display products warehouses and quantity.

Browsing prestashop classes (warehouseCore & productCore)

http://www.devsprite.fr/prestadoc/html/classWarehouseCore.html

http://www.devsprite.fr/prestadoc/html/classProductCore.html

 

So here is my solution for now :

 

 

Override ProductController.php

 

FIND

public function initContent()
  {
    parent::initContent();
    if (!$this->errors)
    {  

AFTER, INSERT

$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
foreach($warehouses as $qty)
  $warehouse_qty[]=ProductCore::getRealQuantity($id_product,'',$qty['id_warehouse']);
$this->context->smarty->assign(array('warehouseName' => $warehouses));
$this->context->smarty->assign(array('warehouseQty' => $warehouse_qty));

------

 

In product.tpl

 

INSERT (wherever you need it)

{foreach from=$warehouseName item=warehouse key=k}
  {if $warehouseQty[$k] > 0}
    <p>{$warehouse['name']} ({$warehouseQty[$k]})</p>
  {/if}
{/foreach}

This will loop and display all the product's warehouses and the quantity stored in each of them.

Edited by mlcrpc (see edit history)
Link to comment
Share on other sites

  • 2 months later...

Found a better and cleaner way to display products warehouses and quantity.

Browsing prestashop classes (warehouseCore & productCore)

http://www.devsprite.fr/prestadoc/html/classWarehouseCore.html

http://www.devsprite.fr/prestadoc/html/classProductCore.html

 

So here is my solution for now :

 

 

Override ProductController.php

 

FIND

public function initContent()
  {
    parent::initContent();
    if (!$this->errors)
    {  

AFTER, INSERT

$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
foreach($warehouses as $qty)
  $warehouse_qty[]=ProductCore::getRealQuantity($id_product,'',$qty['id_warehouse']);
$this->context->smarty->assign(array('warehouseName' => $warehouses));
$this->context->smarty->assign(array('warehouseQty' => $warehouse_qty));

------

 

In product.tpl

 

INSERT (wherever you need it)

{foreach from=$warehouseName item=warehouse key=k}
  {if $warehouseQty[$k] > 0}
    <p>{$warehouse['name']} ({$warehouseQty[$k]})</p>
  {/if}
{/foreach}

This will loop and display all the product's warehouses and the quantity stored in each of them.

 

Doesnt work in Presta Version 1.6.0.14 right?

 

Link to comment
Share on other sites

Doesnt work in Presta Version 1.6.0.14 right?

 

 

I've been working on this based on the 1.6.0.9 code.

Did not have time to upgrade and see if there were any changes in 1.6.0.14 that could affect the method.

 

If you didn't test it yet, I'd say... just do !.. as this is just a few lines to paste.

 

If it works, please let us know.

 

Thank you.

Link to comment
Share on other sites

Ive worked with 1.6.0.14 and EU-Legal. But it doesnt work.

I can copy the code. So maybe you could help?
 
 
 
ProductController.php

/**
* EU Legal - Better security for German and EU merchants.
*
* @version : 1.0.2
* @date : 2014 08 26
* @author : Markus Engel/Chris Gurk @ Onlineshop-Module.de | George June/Alexey Dermenzhy @ Silbersaiten.de
* @copyright : 2014 Onlineshop-Module.de | 2014 Silbersaiten.de
* @contact : [email protected] | [email protected]
* @homepage : www.onlineshop-module.de | www.silbersaiten.de
* @license : http://opensource.org/licenses/osl-3.0.php
* @changelog : see changelog.txt
* @compatibility : PS == 1.6.0.9
*/

class ProductController extends ProductControllerCore
{

/*
* module: eu_legal
* date: 2015-07-19 14:27:44
* version: 1.4.1
*/
public function initContent()
{
parent::initContent();

if (Configuration::get('PS_EU_PAYMENT_API')) {
$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
foreach($warehouses as $qty)
$warehouse_qty[]=ProductCore::getRealQuantity($id_product,'',$qty['id_warehouse']);
$this->context->smarty->assign(array('warehouseName' => $warehouses));
$this->context->smarty->assign(array('warehouseQty' => $warehouse_qty));

$instance = new EU_Legal();
Media::addJsDef(
array(
'deliveryNowValue' => $this->product->delivery_now,
'deliveryLaterValue' => $this->product->delivery_later,
'deliveryNoStockValue' => $instance->l('This product is no longer in stock')
)
);
}
}
}

 

 

Greetz

Edited by ZoXx (see edit history)
Link to comment
Share on other sites

public function initContent()
{
    parent::initContent();

    if (Configuration::get('PS_EU_PAYMENT_API')) {
        $id_product = (int)Tools::getValue('id_product');
        $warehouses = WarehouseCore::getWarehousesByProductId($id_product);
        foreach($warehouses as $qty)
        $warehouse_qty[]=ProductCore::getRealQuantity($id_product,'',$qty['id_warehouse']);
        $this->context->smarty->assign(array('warehouseName' => $warehouses));
        $this->context->smarty->assign(array('warehouseQty' => $warehouse_qty));

        $instance = new EU_Legal();
        Media::addJsDef(
            array(
            'deliveryNowValue' => $this->product->delivery_now,
            'deliveryLaterValue' => $this->product->delivery_later,
            'deliveryNoStockValue' => $instance->l('This product is no longer in stock')
            )
        );
    }
}

1) Are you overriding the controller ?

2) Are you facing a blank page, did you check php errors ?

3) Also make sure that " if (Configuration::get('PS_EU_PAYMENT_API')) " is true

 

I don't know prestashop much, so that's all I can suggest for now, but if you could be more precise, I or someone could maybe give more solutions/advices.

 

Good luck.

Link to comment
Share on other sites

Hey,

thanks for fast feedback!
 

Yeah i think that EU-Legal is overriding the controller.
The code so works great, but the settings you told, doenst work.

Nothing is shown on my product page.

the code i paste in makes no error or something like that, but the code shows no stock.

thats it 

 

greetz

Edited by ZoXx (see edit history)
Link to comment
Share on other sites

Hi, here are a few things you can try :

 

In the back office (admin),

 

Preferences / Products

 

- Enable advanced stock management

 

Stock / Warehouses

 

- One or more warehouses have to be set

 

Catalog / Products

 

Quantities -> Try using "advanced stock management" / Quantities based on stock

Warehouses -> Check that your product's warehouse is set

 

Stock / Stock Management

 

- Quantity has to be set

 

 

If you're not using advanced stock management and your warehouse's product quantity isn't > 0, nothing will be shown.

Edited by mlcrpc (see edit history)
Link to comment
Share on other sites

  • 2 months later...
  • 2 months later...
  • 4 months later...

Found a better and cleaner way to display products warehouses and quantity.

Browsing prestashop classes (warehouseCore & productCore)

http://www.devsprite.fr/prestadoc/html/classWarehouseCore.html

http://www.devsprite.fr/prestadoc/html/classProductCore.html

 

So here is my solution for now :

 

 

Override ProductController.php

 

FIND

public function initContent()
  {
    parent::initContent();
    if (!$this->errors)
    {  

AFTER, INSERT

$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
foreach($warehouses as $qty)
  $warehouse_qty[]=ProductCore::getRealQuantity($id_product,'',$qty['id_warehouse']);
$this->context->smarty->assign(array('warehouseName' => $warehouses));
$this->context->smarty->assign(array('warehouseQty' => $warehouse_qty));

------

 

In product.tpl

 

INSERT (wherever you need it)

{foreach from=$warehouseName item=warehouse key=k}
  {if $warehouseQty[$k] > 0}
    <p>{$warehouse['name']} ({$warehouseQty[$k]})</p>
  {/if}
{/foreach}

This will loop and display all the product's warehouses and the quantity stored in each of them.

 

Hi, do you know how to show quantity for each attribute in each warehouse? The solution above sum all the quantity of all attributes into each warehouse.

 

Example:

Warehouse 1: size S (2) and M (2)

Warehouse 2: size S (3) and M (5)

 

The product page will show:

 

#W1 - Warehouse 1 (4)

#W2 - Warehouse 2 (8)

 

Would like to show quantity of each attribute when while changing attributes in product page.

Link to comment
Share on other sites

Hi, do you know how to show quantity for each attribute in each warehouse? The solution above sum all the quantity of all attributes into each warehouse.

 

Example:

Warehouse 1: size S (2) and M (2)

Warehouse 2: size S (3) and M (5)

 

The product page will show:

 

#W1 - Warehouse 1 (4)

#W2 - Warehouse 2 (8)

 

Would like to show quantity of each attribute when while changing attributes in product page.

 

Hello, I'm not into prestashop anymore, just worked on it for a few weeks for a former project.

 

I guess that you gonna have to get the current product attribute, store it in a variable and then add it to the foreach loop... something like :

getWarehousesByProductId($id_product,$id_product_attribute)

Don't forget you can find prestashop functions on the github project page : https://github.com/PrestaShop/PrestaShop/

 

 

/classes/stock/Warehouse.php

    /**
     * For a given product, returns the warehouses it is stored in
     *
     * @param int $id_product Product Id
     * @param int $id_product_attribute Optional, Product Attribute Id - 0 by default (no attribues)
     * @return array Warehouses Ids and names
     */
    public static function getWarehousesByProductId($id_product, $id_product_attribute = 0)
    {
        if (!$id_product && !$id_product_attribute) {
            return array();
        }
        $query = new DbQuery();
        $query->select('DISTINCT w.id_warehouse, CONCAT(w.reference, " - ", w.name) as name');
        $query->from('warehouse', 'w');
        $query->leftJoin('warehouse_product_location', 'wpl', 'wpl.id_warehouse = w.id_warehouse');
        if ($id_product) {
            $query->where('wpl.id_product = '.(int)$id_product);
        }
        if ($id_product_attribute) {
            $query->where('wpl.id_product_attribute = '.(int)$id_product_attribute);
        }
        $query->orderBy('w.reference ASC');
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
    }
Link to comment
Share on other sites

I am using 1.6.0.14.

 

override/controllers/front/ProductController.php
add:
 

$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
		
	$id_product_attribute = Db::getInstance()->ExecuteS('
		SELECT 
		pa.id_product_attribute id_pa,
		al.name name,
		CONCAT(w.reference, " - ", w.name) as wname,
		w.id_warehouse id_w
		FROM `ps_product_attribute` pa
		LEFT JOIN `ps_product_attribute_combination` pac ON (pa.`id_product_attribute` = pac.`id_product_attribute`)
		LEFT JOIN `ps_attribute` a ON (pac.`id_attribute` = a.`id_attribute`)
		LEFT JOIN `ps_attribute_lang` al ON (a.`id_attribute` = al.`id_attribute`)
		LEFT JOIN `ps_stock` s ON (pa.`id_product_attribute` = s.`id_product_attribute`)
		LEFT JOIN `ps_warehouse` w ON (s.`id_warehouse` = w.`id_warehouse`)
		WHERE pa.`id_product` = '.(int)$id_product .'
		GROUP BY w.id_warehouse, pa.id_product_attribute
		ORDER BY w.reference, a.`position`');
		
		$attributetable = array();
		
			foreach ($id_product_attribute as $row)
			{
				$attributetable[] = array(
					"id_pa" => $row['id_pa'],
					"name" => $row['name'],
					"wname" => $row['wname'],
					"id_w" => $row['id_w'],
					"realqty" => ProductCore::getRealQuantity($id_product,$row['id_pa'],$row['id_w'])
				);
			}
		
		$warehousetable = array();
		
			foreach ($warehouses as $row)
			{
				$warehousetable[] = array(
					"name" => $row['name'],
					"warehouseQty" => ProductCore::getRealQuantity($id_product,null,$row['id_warehouse'])
				);
			}
			
		$this->context->smarty->assign("attributetable",$attributetable);
		$this->context->smarty->assign("warehousetable",$warehousetable);

 
themes/[your_theme]/product.tpl
add anywhere you like. 
 

{foreach $warehousetable as $j}
	{if $j.warehouseQty != 0}
		<table>
			<thead>
				<tr>
				<th colspan="2">{$j.name}</th>
				</tr>
			</thead>
			<tbody>
				{foreach $attributetable as $item}
				        {if $item.wname == $j.name}
				<tr>
				   <td>
				      {$item.name} {if $item.name == 'S' || $item.name == 'M' || $item.name == 'L' || $item.name == 'XL'}size{else}{/if}
				   </td>
				   <td>
				      {if $item.realqty == 0}Out of Stock{else}{$item.realqty} {if $item.realqty == 1}item{else}items{/if}{/if}
				   </td>
				</tr>
				         {/if}
				{/foreach}
			</tbody>
		</table>
	<br>
	{/if}
{/foreach}

You will get a table for each warehouse, including showing each attribute of the product. Display attribute is out of stock if qty is 0, and hides the whole warehouse table if qty for all attribute is 0.

 

Your table will look something like this:

http://www.tinybibiya.com/lace-petti-romper/154-teal-lace-petti-romper-with-headband.html

 

post-943662-0-31432900-1467822759_thumb.jpg

Link to comment
Share on other sites

  • 3 months later...

I am using 1.6.0.14.

 

override/controllers/front/ProductController.php

add:

 

$id_product = (int)Tools::getValue('id_product');
$warehouses = WarehouseCore::getWarehousesByProductId($id_product);
		
	$id_product_attribute = Db::getInstance()->ExecuteS('
		SELECT 
		pa.id_product_attribute id_pa,
		al.name name,
		CONCAT(w.reference, " - ", w.name) as wname,
		w.id_warehouse id_w
		FROM `ps_product_attribute` pa
		LEFT JOIN `ps_product_attribute_combination` pac ON (pa.`id_product_attribute` = pac.`id_product_attribute`)
		LEFT JOIN `ps_attribute` a ON (pac.`id_attribute` = a.`id_attribute`)
		LEFT JOIN `ps_attribute_lang` al ON (a.`id_attribute` = al.`id_attribute`)
		LEFT JOIN `ps_stock` s ON (pa.`id_product_attribute` = s.`id_product_attribute`)
		LEFT JOIN `ps_warehouse` w ON (s.`id_warehouse` = w.`id_warehouse`)
		WHERE pa.`id_product` = '.(int)$id_product .'
		GROUP BY w.id_warehouse, pa.id_product_attribute
		ORDER BY w.reference, a.`position`');
		
		$attributetable = array();
		
			foreach ($id_product_attribute as $row)
			{
				$attributetable[] = array(
					"id_pa" => $row['id_pa'],
					"name" => $row['name'],
					"wname" => $row['wname'],
					"id_w" => $row['id_w'],
					"realqty" => ProductCore::getRealQuantity($id_product,$row['id_pa'],$row['id_w'])
				);
			}
		
		$warehousetable = array();
		
			foreach ($warehouses as $row)
			{
				$warehousetable[] = array(
					"name" => $row['name'],
					"warehouseQty" => ProductCore::getRealQuantity($id_product,null,$row['id_warehouse'])
				);
			}
			
		$this->context->smarty->assign("attributetable",$attributetable);
		$this->context->smarty->assign("warehousetable",$warehousetable);

 

themes/[your_theme]/product.tpl

add anywhere you like. 

 

{foreach $warehousetable as $j}
	{if $j.warehouseQty != 0}
		<table>
			<thead>
				<tr>
				<th colspan="2">{$j.name}</th>
				</tr>
			</thead>
			<tbody>
				{foreach $attributetable as $item}
				        {if $item.wname == $j.name}
				<tr>
				   <td>
				      {$item.name} {if $item.name == 'S' || $item.name == 'M' || $item.name == 'L' || $item.name == 'XL'}size{else}{/if}
				   </td>
				   <td>
				      {if $item.realqty == 0}Out of Stock{else}{$item.realqty} {if $item.realqty == 1}item{else}items{/if}{/if}
				   </td>
				</tr>
				         {/if}
				{/foreach}
			</tbody>
		</table>
	<br>
	{/if}
{/foreach}

You will get a table for each warehouse, including showing each attribute of the product. Display attribute is out of stock if qty is 0, and hides the whole warehouse table if qty for all attribute is 0.

 

Your table will look something like this:

http://www.tinybibiya.com/lace-petti-romper/154-teal-lace-petti-romper-with-headband.html

 

attachicon.gifwarehouse-stock-display.jpg

 

 

What role do the override to productcontroller.php?

 

 

if you can paste the full code I appreciate it. I'm in a version 1.6.1.7 and can not.

What role do the override to productcontroller.php?

Link to comment
Share on other sites

  • 7 years later...
On 6/4/2015 at 6:49 PM, mlcrpc said:

DON'T USE THIS ANYMORE, PLEASE READ MY OTHER SOLUTION POSTED BELOW https://www.prestashop.com/forums/topic/199256-show-warehouse-stock-on-product-page/?p=2072064 )

 

 

 

 

 

-------------------------------------------------------------------------------------------------------

 

- Find and copy ProductController.php from "controllers/front/"

 

- Paste it to "override/controllers/front"

 

- Open the new file

 

FIND

public function initContent()
{
    parent::initContent();
    if (!$this->errors)
    {   

AFTER, INSERT

            $id_product = (int)Tools::getValue('id_product'); 
            $sql = 'SELECT name,physical_quantity FROM ps_warehouse,ps_stock WHERE id_product ='.$id_product.' AND ps_warehouse.id_warehouse = ps_stock.id_warehouse';
            if ($results = Db::getInstance()->ExecuteS($sql))
                foreach ($results as $row)
                    $warehouses[] = array($row['name'],$row['physical_quantity']);
                        
            $this->context->smarty->assign(array(
                            'warehouse' => $warehouses)); 

- Open product.tpl from "themes/default-bootstrap" (or whatever your theme is)

 

- Where you want to display the warehouses names and available stocks :

 

PASTE

<p>Warehouse(s) :</p>
{foreach from=$warehouse item=w}
    {if $w[1]>0}                    
        <p>{$w[0]} ({$w[1]})</p>
    {/if}
{/foreach}

Update : New condition so warehouses without stock are not shown.

Hello, for me work this solution. But tell me please how also display a price for product on the each warehouse?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...