<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NemoPS &#187; products</title>
	<atom:link href="http://nemops.com/tag/products/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemops.com</link>
	<description>Prestashop Tutorials, Modules and More!</description>
	<lastBuildDate>Wed, 05 Dec 2018 13:25:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.35</generator>
	<item>
		<title>Removing out of stock products from the cart in PrestaShop 1.7</title>
		<link>http://nemops.com/remove-out-of-stock-products-from-the-cart-prestashop-17/</link>
		<comments>http://nemops.com/remove-out-of-stock-products-from-the-cart-prestashop-17/#comments</comments>
		<pubDate>Thu, 04 Oct 2018 00:08:07 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[out of stock]]></category>
		<category><![CDATA[prestashop 1.7]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3151</guid>
		<description><![CDATA[<p>PrestaShop 1.7 does not remove out of stock products from shopping carts, creating major troubles when keeping low stock. Let&#8217;s see how to improve our customer&#8217;s experience with a simple modification! Watch the screencast Text Version If you have lots of users it might happen sometimes that a product goes out of stock while it&#8217;s [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/remove-out-of-stock-products-from-the-cart-prestashop-17/">Removing out of stock products from the cart in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>PrestaShop 1.7 does not remove out of stock products from shopping carts, creating major troubles when keeping low stock. Let&#8217;s see how to improve our customer&#8217;s experience with a simple modification!</p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/OouTaCaMZBU" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<h2>Text Version</h2>
<p>If you have lots of users it might happen sometimes that a product goes out of stock while it&#8217;s in someone&#8217;s cart. For example two users add the last unit, one proceeds to the checkout and the other doesn&#8217;t. What happens is when the second customer places the order, the product will not be available anymore, and it will cause confusion if not irritation to that person, especially if you cannot restock that specific item.</p>
<h3>The Cart Presenter in PrestaShop 1.7</h3>
<p>The first file we need to edit is the <strong>cartPresenter</strong>, which is responsible of displaying cart information across the store.</p>
<p>Open up <em>src/Adapter/Cart/cartpresenter.php</em> and add the following around line 51, in the class properties:</p>
<pre class="brush: php; title: ; notranslate">
private static $removedProducts = [];
</pre>
<p>Then locate the <strong>present </strong>method, and right after the following statement:</p>
<pre class="brush: php; title: ; notranslate">
        if ($shouldSeparateGifts) {
            $rawProducts = $cart-&gt;getProductsWithSeparatedGifts();
        } else {
            $rawProducts = $cart-&gt;getProducts(true);
        }
</pre>
<p>Add this:</p>
<pre class="brush: php; title: ; notranslate">


        // start nemo

        if(!self::$removedProducts)
            foreach ($rawProducts as $pk =&gt; $product)
            {
            // we want to remove the product in case it's not available
                if($product['quantity_available'] &lt;= 0 &amp;&amp; !Product::isAvailableWhenOutOfStock($product['out_of_stock']))
                {
                    Context::getContext()-&gt;cart-&gt;deleteProduct($product['id_product'],$product['id_product_attribute'], $product['id_customization'], $product['id_address_delivery']);
                    self::$removedProducts[] = $product['name'];
                    unset($rawProducts[$pk]);
                    continue;
                }
            }
           
        Context::getContext()-&gt;smarty-&gt;assign(['removed_products' =&gt; self::$removedProducts]);
        \Media::addJsDef(['removed_products' =&gt; self::$removedProducts]);


</pre>
<p>And that&#8217;s all for php! Before continuing let&#8217;s make sure the product actually gets removed, so let&#8217;s test it and see if they really get removed!</p>
<h3>The shopping cart template in PrestaShop 1.7</h3>
<p>Let&#8217;s open up <em>themes/classic/modules/ps_shoppingcart/ps_shoppingcart.tpl </em></p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($removed_products) &amp;&amp; $removed_products}
  &lt;div id=&quot;removed-modal&quot; class=&quot;modal&quot;&gt;
    &lt;div class=&quot;modal-dialog&quot;&gt;
      &lt;div class=&quot;modal-content&quot;&gt;
        &lt;div class=&quot;modal-body&quot;&gt;
          &lt;p&gt;{l s='These products are out of stock' d='Shop.Theme.Checkout'}&lt;/p&gt;
            &lt;ul&gt;
              {foreach from=$removed_products item='r_product'}
                &lt;li&gt;- {$r_product}&lt;/li&gt;
              {/foreach}
            &lt;/ul&gt;
            &lt;p&gt;{l s='And have therefore been removed from your cart' d='Shop.Theme.Checkout'}&lt;/p&gt;
        &lt;/div&gt;

      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
{/if}
</pre>
<p>And the very last thing is actually triggering the modal when we need, so let&#8217;s add some javascript to <em>themes/classic/assets/js/custom.js</em></p>
<pre class="brush: jscript; title: ; notranslate">
if(removed_products.length &gt; 0) {
	$('#removed-modal').modal('show');
}

</pre>
<p>And that&#8217;s it! Now this modal doesn&#8217;t look so fancy, but no worries since in one of the next videos we will go over creating and styling custom popups in prestashop 1.7, so stay tuned!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/remove-out-of-stock-products-from-the-cart-prestashop-17/">Removing out of stock products from the cart in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/remove-out-of-stock-products-from-the-cart-prestashop-17/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Creating a “Clear cart” button in PrestaShop 1.7</title>
		<link>http://nemops.com/prestashop-1-7-clear-cart-button/</link>
		<comments>http://nemops.com/prestashop-1-7-clear-cart-button/#comments</comments>
		<pubDate>Mon, 06 Nov 2017 13:09:06 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[cart]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop 1.7]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3093</guid>
		<description><![CDATA[<p>Let&#8217; see how to create a button to empty the PrestaShop 1.7 shopping cart in one click! Version used: Prestashop 1.7.2.4 In this tutorial we will see how to apply my previous guide on Creating a “Clear cart” button in PrestaShop to PrestaShop 1.7, as it doesn&#8217;t work out of the box because of the [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-7-clear-cart-button/">Creating a “Clear cart” button in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let&#8217; see how to create a button to empty the PrestaShop 1.7 shopping cart in one click!<br />
<span id="more-3093"></span></p>
<ul>
<li>Version used: <strong>Prestashop 1.7.2.4</strong></li>
</ul>
<p>In this tutorial we will see how to apply my previous guide on <a href="http://nemops.com/clear-cart-button-prestashop">Creating a “Clear cart” button in PrestaShop</a> to PrestaShop 1.7, as it doesn&#8217;t work out of the box because of the new template.</p>
<p>The basic code still works, and the process is more or less the same, though the files needing modifications are totally different. For this tutorial, I will be using the classic (or standard) template, so wherever you read &#8220;themename&#8221;, just put <strong>classic</strong>. As a side not, please notice some files might be different if you use a custom PrestaShop theme.</p>
<h2>Adding the button to the cart page in PrestaShop 1.7</h2>
<p>The PrestaShop 1.7 template structure is quite different from 1.6, so we need to account for that. The main view for the cart is now located at <em>themes/*themename*/templates/checkout/</em>, and it&#8217;s called <strong>cart.tpl</strong>. Open it up, and locat the following block:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
      {block name='cart_overview'}
        {include file='checkout/_partials/cart-detailed.tpl' cart=$cart}
      {/block}
</pre>
<p>This represents the products list block, and we want to add the button right after it:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
    &lt;a class=&quot;btn btn-primary&quot; style=&quot;float:right&quot; id=&quot;removeAll&quot; href=&quot;javascript:void(0)&quot;&gt;
      Empty Cart
    &lt;/a&gt;
</pre>
<p>At this point, unlike 1.6 where we could add our code directly to the template, with PrestaShop 1.7 we have to use a new file, named <strong>custom.js</strong>.</p>
<div class="separator"></div>
<h2>Adding new javascript to a PrestaShop 1.7 template</h2>
<p>Open up <strong>custom.js</strong>, located in <em>themes/*themename*/assets/js</em>.<br />
It&#8217;s empty by default, so if not (as in the case of custom templates), just add the code at the end.</p>
<p>This file is loaded on all pages, and since we only want to run it on the cart one, we have to wrap our snippet with a condition:</p>
<pre class="brush: jscript; title: ; notranslate">
if(prestashop.page.page_name == 'cart')
{}
</pre>
<p>The <strong>prestashop</strong> javascript variable is a new global available in all pages of the shop, which contains a number of useful data that can be used in scripts. In this case, we use the current page name.</p>
<p>Here is all the rest of the code we need:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {

	    $('#removeAll').click(function(e) {
	        e.preventDefault()
	        $.ajax({
	            type: 'POST',
	            headers: { &quot;cache-control&quot;: &quot;no-cache&quot; },
	            url: prestashop.urls.base_url + &quot;cart&quot;,
	            async: true,
	            cache: false,
	            data: 'deleteAll=1&amp;token=' + prestashop.token + '&amp;ajax=true',
	            success: function(data){	
	                window.location.reload();
	            }
	        })
	    });
	});	
</pre>
<p><strong>Explanation:</strong> we are using the prestashop variable again, this time to fetch the base url. The cart controller, which we will be editing shortly, can be accessed at /cart by default, so we pass this url to the ajax call.<br />
For the querystring, we pass in <strong>deleteAll</strong>, to make sure we can refer to this action in the next step, a <strong>token</strong> required by PrestaShop 1.7, and <strong>ajax=true</strong>, so that the cart know the action has to be run in ajax mode.<br />
If the call is successful, we refresh the page to show that the cart is now empty.</p>
<div class="separator"></div>
<h2>Editing the CartController</h2>
<p>PrestaShop 1.7 discourages the use of overrides, but we will use one in any case <img src="http://nemops.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /><br />
Create a new file in <em>override/controllers/front</em>, and name it <strong>cartController.php</strong>. Reach back the original cart controller in the main <em>controllers/front</em>, and copy the whole <strong>updateCart</strong> method, pasting it into our new file:</p>
<pre class="brush: php; title: ; notranslate">
    protected function updateCart()
    {
        // Update the cart ONLY if $this-&gt;cookies are available, in order to avoid ghost carts created by bots
        if ($this-&gt;context-&gt;cookie-&gt;exists() &amp;&amp; !$this-&gt;errors &amp;&amp; !($this-&gt;context-&gt;customer-&gt;isLogged() &amp;&amp; !$this-&gt;isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this-&gt;processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this-&gt;processDeleteProductInCart();
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this-&gt;errors[] = $this-&gt;trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this-&gt;errors[] = $this-&gt;trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) &amp;&amp; Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule-&gt;checkValidity($this-&gt;context, false, true)) {
                                $this-&gt;errors[] = $error;
                            } else {
                                $this-&gt;context-&gt;cart-&gt;addCartRule($cartRule-&gt;id);
                            }
                        } else {
                            $this-&gt;errors[] = $this-&gt;trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) &amp;&amp; Validate::isUnsignedId($id_cart_rule)) {
                    $this-&gt;context-&gt;cart-&gt;removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this-&gt;context);
                }
            }
        } elseif (!$this-&gt;isTokenValid() &amp;&amp; Tools::getValue('action') !== 'show' &amp;&amp; !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }
</pre>
<p>All we have to do now is add our condition, as part of all those ELSEIFs:</p>
<pre class="brush: php; title: ; notranslate">
            elseif (Tools::getIsset('deleteAll')) {
                $this-&gt;context-&gt;cart-&gt;delete();
                $this-&gt;context-&gt;cookie-&gt;id_cart = 0;
                die(1);
            }
</pre>
<p>Here is the final code:</p>
<pre class="brush: php; title: ; notranslate">
    protected function updateCart()
    {
        // Update the cart ONLY if $this-&gt;cookies are available, in order to avoid ghost carts created by bots
        if ($this-&gt;context-&gt;cookie-&gt;exists() &amp;&amp; !$this-&gt;errors &amp;&amp; !($this-&gt;context-&gt;customer-&gt;isLogged() &amp;&amp; !$this-&gt;isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this-&gt;processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this-&gt;processDeleteProductInCart();

            } elseif (Tools::getIsset('deleteAll')) { /* Nemo */
                $this-&gt;context-&gt;cart-&gt;delete();
                $this-&gt;context-&gt;cookie-&gt;id_cart = 0;
                die(1);
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this-&gt;errors[] = $this-&gt;trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this-&gt;errors[] = $this-&gt;trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) &amp;&amp; Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule-&gt;checkValidity($this-&gt;context, false, true)) {
                                $this-&gt;errors[] = $error;
                            } else {
                                $this-&gt;context-&gt;cart-&gt;addCartRule($cartRule-&gt;id);
                            }
                        } else {
                            $this-&gt;errors[] = $this-&gt;trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) &amp;&amp; Validate::isUnsignedId($id_cart_rule)) {
                    $this-&gt;context-&gt;cart-&gt;removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this-&gt;context);
                }
            }
        } elseif (!$this-&gt;isTokenValid() &amp;&amp; Tools::getValue('action') !== 'show' &amp;&amp; !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }
</pre>
<p>We are done! Reach the back office, Advanced Parameters, Performance, and hit the clear cache button on the top right, so that the override takes place.</p>
<p>Should it not work, check that <strong>Disable all overrides</strong> is set to no, right below on the same page. If it still doesn&#8217;t, try editing the core CartController.php.</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-7-clear-cart-button/">Creating a “Clear cart” button in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-1-7-clear-cart-button/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mark orders with returned products in the order list of ThirtyBees and PrestaShop</title>
		<link>http://nemops.com/thirtybees-prestashop-mark-returned-orders/</link>
		<comments>http://nemops.com/thirtybees-prestashop-mark-returned-orders/#comments</comments>
		<pubDate>Mon, 02 Oct 2017 10:34:33 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop 1.6]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[return]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3085</guid>
		<description><![CDATA[<p>In this video for ThirtyBees and Prestashop 1.6, we will see how to add a checkmark for orders that contain returned products, so that they are easy to spot in the back office order list Watch the screencast Text Version All of the modifications need to be applied to AdminOrdersController.php, located in controllers/admin Add to [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/thirtybees-prestashop-mark-returned-orders/">Mark orders with returned products in the order list of ThirtyBees and PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this video for ThirtyBees and Prestashop 1.6, we will see how to add a checkmark for orders that contain returned products, so that they are easy to spot in the back office order list<br />
<span id="more-3085"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/fpuJEs8oo84" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<h2>Text Version</h2>
<p>All of the modifications need to be applied to <strong>AdminOrdersController.php</strong>, located in <em>controllers/admin</em><br />
Add to $this->_select (do not forget the comma!):</p>
<pre class="brush: php; title: ; notranslate">
od.product_quantity_return as has_returned,
</pre>
<p>Add to $this->_join:</p>
<pre class="brush: php; title: ; notranslate">
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON (od.`id_order` = a.`id_order`)
</pre>
<p>Right after the join variable is set, add:</p>
<pre class="brush: php; title: ; notranslate">
$this-&gt;_group = 'GROUP BY a.id_order';
</pre>
<p>This way we avoid duplicates in the order list.</p>
<p>In the next step we will add the actual column, scroll down to around line 130, and add the following to the $this->fields_list variable:</p>
<pre class="brush: php; title: ; notranslate">
                'has_returned'            =&gt; [
                    'title'      =&gt; $this-&gt;l('Return'),
                    'align'      =&gt; 'text-center',
                    'type'       =&gt; 'bool',
                    'callback'       =&gt; 'getIsReturned',
                ],
</pre>
<p>Lastly, out of the construct method (it can be anywhere, right after it or at the end of the file) we will add the callback function:</p>
<pre class="brush: php; title: ; notranslate">
    public function getIsReturned($a, $order)
    {
        $has_returned = Db::getInstance()-&gt;getValue('SELECT product_quantity_return FROM '._DB_PREFIX_.'order_detail WHERE id_order =' .(int)$order['id_order'] .' AND product_quantity_return &gt; 0');

        $class = $has_returned ? 'icon-check' : 'icon-remove';
        return '&lt;i class=&quot;'.$class.'&quot;&gt;&lt;/i&gt;';

    }
</pre>
<p>The post <a rel="nofollow" href="http://nemops.com/thirtybees-prestashop-mark-returned-orders/">Mark orders with returned products in the order list of ThirtyBees and PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/thirtybees-prestashop-mark-returned-orders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make product fields multi-language in PrestaShop and ThirtyBees</title>
		<link>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/</link>
		<comments>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/#comments</comments>
		<pubDate>Mon, 18 Sep 2017 02:56:55 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3067</guid>
		<description><![CDATA[<p>In this tutorial we will learn how to make product fields translatable in PrestaShop 1.6, and see how to apply the method to the &#8220;price per&#8230;&#8221; field. Introduction You might have come across the need to translate the price per unit field in your PrestaShop or Thirtybees, but crashed against the software&#8217;s limitation, as that&#8217;s [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-thirtybees-multi-language-product-fields/">Make product fields multi-language in PrestaShop and ThirtyBees</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this tutorial we will learn how to make product fields translatable in PrestaShop 1.6, and see how to apply the method to the &#8220;price per&#8230;&#8221; field.<br />
<span id="more-3067"></span></p>
<h2>Introduction</h2>
<p>You might have come across the need to translate the price per unit field in your PrestaShop or Thirtybees, but crashed against the software&#8217;s limitation, as that&#8217;s a single language property. Any product field can be made multi-language with a simple modification, so let&#8217;s see how to do it using the Unity one as example in this tutorial!</p>
<div class="separator"></div>
<h2>Step 1 &#8211; Adding the new database column</h2>
<p>In order to make the field translatable, we have to add it to the <strong>product_lang </strong>table in the database. Not only, but  we also have to erase the same column in both the product and product_shop tables, to avoid conflicts when retrieving values from the database. Let&#8217;s add it first!</p>
<p>Using phpMyAdmin or Adminer, locate the <strong>*prefix*product_lang</strong> table in your database, and add a new column as <strong>VARCHAR</strong>, 24 characters long. Once done, it will look like this:</p>
<p><img src="http://nemops.com/wp-content/uploads/2017/09/multilang_field_db.png" alt="multilang_field_db" width="606" height="97" class="aligncenter size-full wp-image-3069" /></p>
<p>Next, let&#8217;s get rid of the leftovers: open the *prefix*product table and drop the <strong>unity</strong> column first, and then on the <strong>product_shop</strong> table.<br />
We are done! We just broke the Product class though, and have to compensate by letting it know where to grab the new values from.</p>
<div class="separator"></div>
<h2>Step 2 &#8211; Editing the product class</h2>
<p>We have a new column in the database, but at this point the Product class would still just ignore it. To have it lookup, and save into the correct table, we must tell it that the property we are wanting to translate is a multilanguage field. To do so, we must change its definition.</p>
<p>Open up <strong>Product.php</strong>, located in the <em>classes/</em> folder.</p>
<p>Scroll down until you find the following line, part of the <strong>$definition</strong> property:</p>
<pre class="brush: php; title: ; notranslate">
'unity'                     =&gt; ['type' =&gt; self::TYPE_STRING, 'shop' =&gt; true, 'validate' =&gt; 'isString'],
</pre>
<p>To make any field translatable, we can simply add &#8216;lang&#8217; => true as follows</p>
<pre class="brush: php; title: ; notranslate">
'unity'                     =&gt; ['type' =&gt; self::TYPE_STRING, 'shop' =&gt; true, 'validate' =&gt; 'isString', 'lang' =&gt; true],
</pre>
<p><strong>Please notice that, as always, using an override is strongly recommended, instead of editing core files.</strong></p>
<div class="separator"></div>
<h2>Step 3 &#8211; Editing the back office</h2>
<h3>The controller</h3>
<p>This is the most complicated part, as we will have to edit both the admin controller for products, and the correct template. For our example, the template is <strong>prices.tpl</strong>, but it will be different if the field you want to translate is in another tab.</p>
<p>Let&#8217;s start with the controller. The prices template does not offer us any option for translating fields, and therefore misses the indispensable $languages variable.<br />
Open up <strong>AdminProductsController</strong>, located in <em>controllers/admin</em></p>
<p>We are interested in the method called <strong>initFormPrices</strong>, so once you find it you can simply clone that to an override, or continue editing the core.</p>
<p>Right after $data is assigned, at the very beginning of the function, but <strong>before $product = $obj</strong>, add the following</p>
<pre class="brush: php; title: ; notranslate">
if (!$this-&gt;default_form_language) {
    $this-&gt;getLanguages();
}
$data-&gt;assign(array(
    'languages'=&gt; $this-&gt;_languages,
    'id_lang' =&gt; $this-&gt;context-&gt;language-&gt;id,
    'default_form_language' =&gt; $this-&gt;default_form_language,
));
</pre>
<p><strong>Explanation</strong>: Nothing too complex here, we are first checking if languages are loaded, and if not, assigning them to the controller. Then, we simply assign that class property to the template, along with a few other required ones. Please notice we do not use a common smarty assign, but the $data variable instead.</p>
<h3>The template</h3>
<p>Time to make our changes visible in the back office! For the unity field, let&#8217;s open up <em>*admin folder*/themes/default/template/controllers/products/prices.tpl</em></p>
<p>Locate the input with id unity, which will look more or less like the following:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;input id=&quot;unity&quot; name=&quot;unity&quot; type=&quot;text&quot; value=&quot;{$product-&gt;unity|htmlentitiesUTF8}&quot;  maxlength=&quot;255&quot; onkeyup=&quot;if (isArrowKey(event)) return ;unitySecond();&quot; onchange=&quot;unitySecond();&quot;/&gt;
</pre>
<p>Instead of this input, we will use a handy template PrestaShop makes available to us. Replace the above with the following code:</p>
<pre class="brush: php; title: ; notranslate">
{include file=&quot;controllers/products/input_text_lang.tpl&quot;
languages=$languages
input_class=&quot;{$class_input_ajax}{if !$product-&gt;id || Configuration::get('PS_FORCE_FRIENDLY_PRODUCT')}copy2friendlyUrl{/if} updateCurrentText&quot;
input_value=$product-&gt;unity
input_name=&quot;unity&quot;}
</pre>
<p>Save and refresh, and you will see the new field, translatable, appearing in the prices table of the back office. Time to test it, and see if it&#8217;s saving properly.<br />
We can take an extra step and translate the preview below as well:</p>
<pre class="brush: php; title: ; notranslate">
&lt;span id=&quot;unity_second&quot;&gt;{$product-&gt;unity}&lt;/span&gt;
</pre>
<p>to</p>
<pre class="brush: php; title: ; notranslate">
&lt;span id=&quot;unity_second&quot;&gt;{$product-&gt;unity.{$id_lang}}&lt;/span&gt;
</pre>
<p>At this point we can go ahead and test the Front Office. If everything has been done correctly, as soon as you change language, the class should automatically pick the correct translation for the field. Neat!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-thirtybees-multi-language-product-fields/">Make product fields multi-language in PrestaShop and ThirtyBees</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Create products from PHP in PrestaShop</title>
		<link>http://nemops.com/prestashop-create-products-from-php/</link>
		<comments>http://nemops.com/prestashop-create-products-from-php/#comments</comments>
		<pubDate>Tue, 09 May 2017 11:32:51 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3017</guid>
		<description><![CDATA[<p>In this video we will see how to create a simple script to generate products with PHP in PrestaShop Watch the screencast Final Code</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-create-products-from-php/">Create products from PHP in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this video we will see how to create a simple script to generate products with PHP in PrestaShop<span id="more-3017"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/0Kgn6HMcUsU" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<h3>Final Code</h3>
<pre class="brush: php; title: ; notranslate">
&lt;?php

include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');


// we have a csv file open
$default_lang = Configuration::get('PS_LANG_DEFAULT');
// looping through products
// this is a single line in the loop


$product = new Product(20);
$product-&gt;name = [$default_lang =&gt; 'Test'];
$product-&gt;link_rewrite = [$default_lang =&gt; 'test'];
$product-&gt;price = 13.90;
$product-&gt;quantity = 70;
$product-&gt;id_category = [3,4];
$product-&gt;id_category_default = 3;
StockAvailable::setQuantity((int)$product-&gt;id, 0, $product-&gt;quantity, Context::getContext()-&gt;shop-&gt;id);

$product-&gt;update();
</pre>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-create-products-from-php/">Create products from PHP in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-create-products-from-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Limit the total number of products in the cart &#8211; PrestaShop 1.6</title>
		<link>http://nemops.com/limit-cart-products-prestashop/</link>
		<comments>http://nemops.com/limit-cart-products-prestashop/#comments</comments>
		<pubDate>Mon, 27 Mar 2017 09:30:01 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[cart]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2993</guid>
		<description><![CDATA[<p>In today's video we will see how to limit the maximum number of products customers can add to the cart in PrestaShop 1.6. It also works in ThirtyBees, the PrestaShop fork.</p>
<p>The post <a rel="nofollow" href="http://nemops.com/limit-cart-products-prestashop/">Limit the total number of products in the cart &#8211; PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In today&#8217;s video we will see how to limit the maximum number of products customers can add to the cart in PrestaShop 1.6. It also works in ThirtyBees, the PrestaShop fork.<br />
<span id="more-2993"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/wAlXtr8u5Qo" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/limit-cart-products-prestashop/">Limit the total number of products in the cart &#8211; PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/limit-cart-products-prestashop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Display products from subcategories in PrestaShop 1.6</title>
		<link>http://nemops.com/prestashop-16-display-products-from-subcategories/</link>
		<comments>http://nemops.com/prestashop-16-display-products-from-subcategories/#comments</comments>
		<pubDate>Wed, 25 Jan 2017 11:52:29 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[category]]></category>
		<category><![CDATA[prestashop 1.6]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[subcategories]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2970</guid>
		<description><![CDATA[<p>Are you wondering how to display products from subcategories, without using the layered navigation module? Let&#8217;s see it for PrestaShop 1.6!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-16-display-products-from-subcategories/">Display products from subcategories in PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Are you wondering how to display products from subcategories, without using the layered navigation module? Let&#8217;s see it for PrestaShop 1.6!</p>
<p><span id="more-2970"></span></p>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/6BBM62S6I08" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-16-display-products-from-subcategories/">Display products from subcategories in PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-16-display-products-from-subcategories/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Update price on quantity change in PrestaShop 1.6</title>
		<link>http://nemops.com/update-price-on-quantity-change-in-prestashop-1-6/</link>
		<comments>http://nemops.com/update-price-on-quantity-change-in-prestashop-1-6/#comments</comments>
		<pubDate>Wed, 07 Dec 2016 11:51:50 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prestashop 1.6]]></category>
		<category><![CDATA[price]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2924</guid>
		<description><![CDATA[<p>Let&#8217;s give our customers some more feedback when they change quantity! In this video, we will see how to change the price on the product page based on the user&#8217;s chosen quantity in PrestaShop 1.6 Watch the Screencast</p>
<p>The post <a rel="nofollow" href="http://nemops.com/update-price-on-quantity-change-in-prestashop-1-6/">Update price on quantity change in PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let&#8217;s give our customers some more feedback when they change quantity! In this video, we will see how to change the price on the product page based on the user&#8217;s chosen quantity in PrestaShop 1.6<br />
<span id="more-2924"></span></p>
<h2>Watch the Screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/6znHv0zUao0" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/update-price-on-quantity-change-in-prestashop-1-6/">Update price on quantity change in PrestaShop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/update-price-on-quantity-change-in-prestashop-1-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Display price and Add to Cart in the viewed Products Block in PrestaShop</title>
		<link>http://nemops.com/prestashop-blockviewed-price-add-to-cart/</link>
		<comments>http://nemops.com/prestashop-blockviewed-price-add-to-cart/#comments</comments>
		<pubDate>Mon, 10 Oct 2016 10:38:23 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[blockviewed]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2874</guid>
		<description><![CDATA[<p>In this quick video tutorial, we will add the price, as well as an add to cart button, to the viewed products block in PrestaShop Watch the Screencast</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-blockviewed-price-add-to-cart/">Display price and Add to Cart in the viewed Products Block in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this quick video tutorial, we will add the price, as well as an add to cart button, to the viewed products block in PrestaShop<br />
<span id="more-2874"></span></p>
<h2>Watch the Screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/gqJmwHSMZYw#038;feature=youtu.be" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-blockviewed-price-add-to-cart/">Display price and Add to Cart in the viewed Products Block in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-blockviewed-price-add-to-cart/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Adding text for back-orderable Combinations in PrestaShop</title>
		<link>http://nemops.com/adding-text-for-back-orderable-combinations-in-prestashop/</link>
		<comments>http://nemops.com/adding-text-for-back-orderable-combinations-in-prestashop/#comments</comments>
		<pubDate>Wed, 10 Aug 2016 09:33:08 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[combinations]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2837</guid>
		<description><![CDATA[<p>In this flash tip we will see how to display an explanatory text for combinations which you have no stock for, but still want to allow the purchase of. PrestaShop Version used: 1.6.1.5 The background Do you allow back ordering products? If so, you might have noticed PrestaShop tends to be confusing on combinations. In [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/adding-text-for-back-orderable-combinations-in-prestashop/">Adding text for back-orderable Combinations in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this flash tip we will see how to display an explanatory text for combinations which you have no stock for, but still want to allow the purchase of.</p>
<p><span id="more-2837"></span></p>
<ul>
<li>PrestaShop Version used: 1.6.1.5</li>
</ul>
<h2>The background</h2>
<p>Do you allow back ordering products? If so, you might have noticed PrestaShop tends to be confusing on combinations. In the default template, when a combination is available and has stock, it displays the classic <strong>X items in stock</strong> message. However, if you select a combination that has currently zero stock, even if available for order, it displays nothing. Forum users have reported customers being confused by this, so let&#8217;s see how to fix it, and give our customers more feedback!</p>
<div class="separator"></div>
<h2>The translatable string</h2>
<p>Unless you run a single language shop, you will need the text we are going to display to be translatable. Therefore, we will take advantage of PrestaShop&#8217;s AddJsDefL method to add a javascript variable that can easily be translated from the back office. Open up your <strong>product.tpl</strong> file, located in the theme folder. At the very end of it, add the following:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{addJsDefL name='onBackOrderText'}{l s='On backorder' js=1}{/addJsDefL}
</pre>
<p><strong>What does it do?</strong> It takes any content between tags and assigns it to the variable with a given name. There is a manual method as well, but this is the one that better complies to PrestaShop standards. If you want to know more about this and other functions, you can refer to my <strong><a href="http://nemops.com/prestashop-functions-1/#.V6rx7_n5jmg" target="_blank" title="Essential PrestaShop functions">Essential PrestaShop functions</a></strong> series.</p>
<div class="separator"></div>
<h2>Editing product.js</h2>
<p>Now that we have a string to play with, we have to make it work as we want. Open up <strong>product.js</strong>, located in the theme folder <em>/js/</em>. Please notice yours might be different if you do not use the default template. Locate the following at around line 630:</p>
<pre class="brush: jscript; title: ; notranslate">
		if (allowBuyWhenOutOfStock &amp;&amp; !selectedCombination['unavailable'] &amp;&amp; productAvailableForOrder)
		{
			$('#add_to_cart:hidden').fadeIn(600);

			if (stock_management &amp;&amp; availableLaterValue != '')
			{
				$('#availability_value').addClass('label-warning').text(availableLaterValue).show('slow');
				$('#availability_statut:hidden').show('slow');
			}
			else 
				$('#availability_statut:visible').hide('slow');
				
		}
</pre>
<p>The last part, in the else, is the one responsible for not displaying anything. We could simply comment it out, but if you try it, you will notice it says the product is available in other variants only. What to do then? Let&#8217;s modify it as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
		if (allowBuyWhenOutOfStock &amp;&amp; !selectedCombination['unavailable'] &amp;&amp; productAvailableForOrder)
		{
			$('#add_to_cart:hidden').fadeIn(600);

			if (stock_management &amp;&amp; availableLaterValue != '')
			{
				$('#availability_value').addClass('label-warning').text(availableLaterValue).show('slow');
				$('#availability_statut:hidden').show('slow');
			}
			else {
				$('#availability_value').addClass('label-warning').text(onBackOrderText).show('slow');
				// $('#availability_statut:visible').hide('slow');
			}
				
		}
</pre>
<p>We just added brackets to the else statement, then copied the label-warning part from above, and used our text variable instead. Save and refresh, then try reloading the page with the combination selected, as well as switching between that and others. You will notice the text behaves as expected now!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/adding-text-for-back-orderable-combinations-in-prestashop/">Adding text for back-orderable Combinations in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/adding-text-for-back-orderable-combinations-in-prestashop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
