<?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; orders</title>
	<atom:link href="http://nemops.com/tag/orders/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>Private Orders Shop in PrestaShop and thirty bees part 1: manual customer verification</title>
		<link>http://nemops.com/private-orders-shop-in-prestashop-and-thirty-bees-part-1-manual-customer-verification/</link>
		<comments>http://nemops.com/private-orders-shop-in-prestashop-and-thirty-bees-part-1-manual-customer-verification/#comments</comments>
		<pubDate>Wed, 30 May 2018 12:39:37 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[customers]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[private]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3133</guid>
		<description><![CDATA[<p>In this 2-part tutorial series, we will see how to create a private orders shop in PrestaShop and thirty bees. In this first part we will see how to add a manual approval for new customers while in the second on we will learn how to prevent orders from people who are not registered and [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/private-orders-shop-in-prestashop-and-thirty-bees-part-1-manual-customer-verification/">Private Orders Shop in PrestaShop and thirty bees part 1: manual customer verification</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this 2-part tutorial series, we will see how to create a private orders shop in PrestaShop and thirty bees.<br />
In this first part we will see how to add a manual approval for new customers while in the second on  we will learn how to prevent orders from people who are not registered and approved by us.<br />
<span id="more-3133"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/CkNh1VEdpbw" 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>I will use PrestaShop 1.6 for the demo but the modification works in thirty bees as well. Bear in mind it DOES NOT work in PrestaShop 1.7.</p>
<p>Open up controllers/front/AuthController.php</p>
<p>Look for the following code, around line 455. If it’s not in those whereabouts, just make sure you change every instance</p>
<pre class="brush: php; title: ; notranslate">
$customer-&gt;active = 1;
</pre>
<p>set to 0, so that the user cannot perform any action right away.</p>
<p>Now we also want to give the user some feedback, so let&#8217;s redirect him to a custom page. Scroll down a few lines, and where you see all these redirects:</p>
<pre class="brush: php; title: ; notranslate">
if (($back = Tools::getValue('back')) &amp;&amp; $back == Tools::secureReferrer($back)) {
                            Tools::redirect(html_entity_decode($back));
                        }
</pre>
<p>And add a new one before</p>
<pre class="brush: php; title: ; notranslate">
  Tools::redirect($this-&gt;context-&gt;link-&gt;getPageLink('welcome'));
</pre>
<p>Of course this page does not exist yet but we will create it in a moment.</p>
<p>Before that though, we have to take care of a little issue. Since the user has been created but set to inactive, the system treats it as banned by default. Even if we are to redirect to a page, we would instantly be kicked out of the session and redirected to the login. We want to create an exception so that the welcome page can be displayed. </p>
<p>Let&#8217;s go ahead and open up the customer class, so classes/customer.php<br />
Look for the following method:</p>
<pre class="brush: php; title: ; notranslate">
public static function isBanned($id_customer)
</pre>
<p>And at the very beginning, add:</p>
<pre class="brush: php; title: ; notranslate">
        if(Context::getContext()-&gt;controller-&gt;php_self == 'welcome')
            return false;
</pre>
<p>That’s settled! Now for our welcome page, I will create a new controller and a template file in the theme folder</p>
<p>Let’s head to controllers/front, and create a new PHP file first, named WelcomeController.php:</p>
<pre class="brush: php; title: ; notranslate">
class WelcomeControllerCore extends FrontController
{
    public $php_self = 'welcome';


    public function initContent()
    {
        parent::initContent();
        $this-&gt;setTemplate(_PS_THEME_DIR_.'welcome.tpl');
    }
}
</pre>
<p>Then in the theme folder, create a new file named welcome.tpl, adding the following code inside</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{capture name=&quot;path&quot;} {l s='Welcome'}{/capture}
&lt;h1&gt;{l s='Welcome to'} {$shop_name}! &lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;
	{l s='Your account is currently under review, you will receive an email as soon as it is validated'}
&lt;/p&gt;
</pre>
<p>So let&#8217;s go ahead and try it out now&#8230; but before let&#8217;s clear cache by erasing cache/class_index.php, since we added a new controller and the system wouldn’t read it otherwise.</p>
<p>The next step is to send out and email when a status is changed to active for the customer, in the back office.<br />
Open controllers/admin/admincustomerscontroller.php</p>
<p>We will add a new method, which is inherited from the admincontroller class:</p>
<pre class="brush: php; title: ; notranslate">

    public function processStatus()
    {
        if($object = parent::processStatus()) {
            if(get_class($object) == 'Customer' &amp;&amp; $object-&gt;active) // the customer has been activated, send out an email
            {
                Mail::Send($object-&gt;id_lang, 'account_activated', $this-&gt;l('Your account has been activated'),
                    ['name' =&gt; $object-&gt;firstname .' '. $object-&gt;lastname],
                $object-&gt;email,
                $object-&gt;firstname .' '. $object-&gt;lastname,
                Configuration::get('PS_SHOP_EMAIL'),
                Configuration::get('PS_SHOP_NAME'));
            }
        }

       return $object;
    }

</pre>
<p>Of course, there is no such email template so we have to create it. I suggest copying an existing one, like the order confirmation, and adding new text, just to be quicker. The code is different for every template, just bear in mind to add the {name} variable inside it, so that the customer name is displayed!</p>
<p>This is it for part 1, make sure you test the email as well since sometimes they do fail for odd reasons, if you don&#8217;t see it coming, triple check the template names and make sure they are located in the proper path for each language you use.</p>
<p>In part two we will see how to prevent orders in case a customer is not registered, which is fundamental not to break the system if you have a one page checkout, as right now it would display an error.</p>
<p>The post <a rel="nofollow" href="http://nemops.com/private-orders-shop-in-prestashop-and-thirty-bees-part-1-manual-customer-verification/">Private Orders Shop in PrestaShop and thirty bees part 1: manual customer verification</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/private-orders-shop-in-prestashop-and-thirty-bees-part-1-manual-customer-verification/feed/</wfw:commentRss>
		<slash:comments>0</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>Filter orders by employee in the PrestaShop Back Office</title>
		<link>http://nemops.com/filter-orders-by-employee-in-the-prestashop-back-office/</link>
		<comments>http://nemops.com/filter-orders-by-employee-in-the-prestashop-back-office/#comments</comments>
		<pubDate>Mon, 03 Jul 2017 09:40:23 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[employee]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop 1.6]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3043</guid>
		<description><![CDATA[<p>In this quick tip we will explore methods to filter the PrestaShop back office orders list by employee profile. Watch the screencast Text Version This tutorial can be applied to ThirtyBees as well! To filter the PrestaShop order list we simply have to add conditions to the &#8220;where&#8221; clause of the AdminOrdersController.php, located at controllers/admin. [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/filter-orders-by-employee-in-the-prestashop-back-office/">Filter orders by employee in the PrestaShop Back Office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this quick tip we will explore methods to filter the PrestaShop back office orders list by employee profile.</p>
<p><span id="more-3043"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/eR-MLFnQr7k" 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>This tutorial can be applied to <strong><a href="http://thirtybees.com" title="ThirtyBees e-commerce software" target="_blank">ThirtyBees</a></strong> as well!</p>
<p>To filter the PrestaShop order list we simply have to add conditions to the &#8220;where&#8221; clause of the <strong>AdminOrdersController.php</strong>, located at <em>controllers/admin</em>.<br />
What we want to do is append the extra conditions to the construct method, around line 68:</p>
<pre class="brush: php; title: ; notranslate">
if($this-&gt;context-&gt;employee-&gt;id_profile == 1)
        {
            $this-&gt;_where .= ' AND os.id_order_state = 2';
            $this-&gt;_where .= ' AND country.id_country = 21';
            $this-&gt;_where .= ' AND a.module = &quot;bankwire&quot;';
        }
</pre>
<p>The first condition will filter orders by current status, in this case &#8220;Payment Accepted&#8221;; The second will only display orders shipping to the United States; the third one will narrow the results to the ones paid by bank wire.<br />
We are using the employee&#8217;s profile ID to trigger the conditions, so that only the selected department will be affected.</p>
<p>These snippets will be enough in most cases, but if you want to be extra careful, it&#8217;s better to also prevent direct access to the single order view, by editing the <strong>renderView</strong> method:</p>
<pre class="brush: php; title: ; notranslate">
// At the beginning of the renderView method, after the $order variable has been validated, we can use this to prevent access if the order is not set to payment accepted. We can do the same with the bankwire method as we saw above, by simply changing the property name from current_state to module
if($this-&gt;context-&gt;employee-&gt;id_profile == 1)
        {

            if($order-&gt;current_state != 2)
            {
                $this-&gt;errors[] = Tools::displayError('You are not authorized to see this page.');
                return;
            }
        }
</pre>
<p>We can also do the same for the country condition, around line 1650, after $addressDelivery has been declared:</p>
<pre class="brush: php; title: ; notranslate">
        if($this-&gt;context-&gt;employee-&gt;id_profile == 1) 
        {
            if($addressDelivery-&gt;id_country != 21)
            {
                $this-&gt;errors[] = Tools::displayError('You are not authorized to see this page.');
                return;
            }
        }
</pre>
<p>The post <a rel="nofollow" href="http://nemops.com/filter-orders-by-employee-in-the-prestashop-back-office/">Filter orders by employee in the PrestaShop Back Office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/filter-orders-by-employee-in-the-prestashop-back-office/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Replace Order References with IDs in Prestashop</title>
		<link>http://nemops.com/prestashop-replace-order-references-with-ids/</link>
		<comments>http://nemops.com/prestashop-replace-order-references-with-ids/#comments</comments>
		<pubDate>Tue, 30 Jun 2015 09:26:31 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[reference]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2460</guid>
		<description><![CDATA[<p>If you find it annoying to have Order References with random characters, here is how to take Order IDs back in Prestashop, for customers as well. Watch the Screencast Text Version There is just one quick step to take, in order to replace the new odd reference number, and that is amending the generateReference method [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-replace-order-references-with-ids/">Quick Tip: Replace Order References with IDs in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>If you find it annoying to have Order References with random characters, here is how to take Order IDs back in Prestashop, for customers as well.</p>
<p><span id="more-2460"></span></p>
<h2>Watch the Screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/YKZ2AK-_XQA" 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>There is just one quick step to take, in order to replace the new odd reference number, and that is amending the <strong>generateReference</strong> method of the Order class.</p>
<p>Let&#8217;s create an override for it! Create a new file inside <em>override/classes/order</em> and name it <strong>Order.php</strong>.<br />
Add the usual override code inside:</p>
<pre class="brush: php; title: ; notranslate">
Class Order extends OrderCore
{

}
</pre>
<p>Then, inside it, let&#8217;s paste the generateReference method:</p>
<pre class="brush: php; title: ; notranslate">
	public static function generateReference()
	{
		return strtoupper(Tools::passwdGen(9, 'NO_NUMERIC'));
	}
</pre>
<p>We want to grab the very last order ID, then increase it by one, increase it by one and pad it so all the new references have the same length in terms of characters</p>
<pre class="brush: php; title: ; notranslate">
	public static function generateReference()
	{
		$last_id = Db::getInstance()-&gt;getValue('
			SELECT MAX(id_order)
			FROM '._DB_PREFIX_.'orders');
		return str_pad((int)$last_id + 1, 9, '000000000', STR_PAD_LEFT);

	}
</pre>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-replace-order-references-with-ids/">Quick Tip: Replace Order References with IDs in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-replace-order-references-with-ids/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Set the order status to Shipped when adding a tracking code in Prestashop</title>
		<link>http://nemops.com/prestashop-order-status-shipped-tracking/</link>
		<comments>http://nemops.com/prestashop-order-status-shipped-tracking/#comments</comments>
		<pubDate>Mon, 01 Jun 2015 09:34:34 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[shipping]]></category>
		<category><![CDATA[tracking]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2435</guid>
		<description><![CDATA[<p>This little trick will save you the time of having to manually change the order status when you add a tracking number for orders, in the Prestashop Back Office. Before proceeding, be aware that this method is not ideal in case you are offering multi shipping (that is, if the same order is associated to [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-order-status-shipped-tracking/">Set the order status to Shipped when adding a tracking code in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>This little trick will save you the time of having to manually change the order status when you add a tracking number for orders, in the Prestashop Back Office.</p>
<p><span id="more-2435"></span></p>
<p>Before proceeding, be aware that this method is not ideal in case you are offering multi shipping (that is, if the same order is associated to multiple carriers and tracking numbers), as it would be set to shipped even if not all of the items have been.</p>
<p>That said, open up <strong>AdminOrdersController.php</strong> located in the <em>controllers/admin</em> folder. Locate the following:</p>
<pre class="brush: php; title: ; notranslate">
if (Tools::isSubmit('submitShippingNumber') &amp;&amp; isset($order))
		{
			..
</pre>
<p>Inside this conditional, we are going to plug in our code, and the ideal spot for it would be right before</p>
<pre class="brush: php; title: ; notranslate">
// Send mail to customer
	$customer = new Customer((int)$order-&gt;id_customer);
	$carrier = new Carrier((int)$order-&gt;id_carrier, $order-&gt;id_lang);
</pre>
<p>As at this point the tracking number has already been set. Therefore, let&#8217;s start by adding some lines of code (my line is around 465, in Prestashop 1.6.0.14:)</p>
<pre class="brush: php; title: ; notranslate">

$shipped_status = Configuration::get('PS_OS_SHIPPING');
if($order-&gt;current_state != $shipped_status &amp;&amp; $order-&gt;current_state != Configuration::get('PS_OS_CANCELED'))
{
	// todo
}

</pre>
<p><strong>Explanation:</strong> First, we are grabbing the shipped status from the database configuration, then we check that the current order has not been shipped already (it would be redundant to add another identical status!). We also make sure it&#8217;s not canceled, to avoid any conflict if we accidentally (or necessarily) update the tracking after canceling an order</p>
<p> Inside our new condition, add</p>
<pre class="brush: php; title: ; notranslate">
	$history = new OrderHistory();
	$history-&gt;id_order = $order-&gt;id;
	$history-&gt;id_employee = (int)$this-&gt;context-&gt;employee-&gt;id;

	$history-&gt;changeIdOrderState((int)$shipped_status, $order);
 </pre>
<p> So that we effectively modify the status. Now that the order is changed, we can do two things: sending an extra email to the customer (For the &#8220;shipped&#8221; status) and updating stock in case we use advanced stock management.</p>
<pre class="brush: php; title: ; notranslate">
	$carrier = new Carrier($order-&gt;id_carrier, $order-&gt;id_lang);
	$templateVars = array();
	if ($order-&gt;shipping_number)
		$templateVars = array('{followup}' =&gt; str_replace('@', $order-&gt;shipping_number, $carrier-&gt;url));

	if ($history-&gt;addWithemail(true, $templateVars))
	{
		if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
			foreach ($order-&gt;getProducts() as $product)
				if (StockAvailable::dependsOnStock($product['product_id']))
					StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
	}	
 </pre>
<p> Bear in mind that, if you don&#8217;t want to send out any email, you migh as well just paste in the last part:</p>
<pre class="brush: php; title: ; notranslate">

 	if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
			foreach ($order-&gt;getProducts() as $product)
				if (StockAvailable::dependsOnStock($product['product_id']))
					StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
 </pre>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-order-status-shipped-tracking/">Set the order status to Shipped when adding a tracking code in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-order-status-shipped-tracking/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Prestashop 101 Day 9 &#8211; Order Management</title>
		<link>http://nemops.com/order-management/</link>
		<comments>http://nemops.com/order-management/#comments</comments>
		<pubDate>Tue, 30 Dec 2014 10:01:37 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Basics]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[prestashop 101]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=920</guid>
		<description><![CDATA[<p>It&#8217;s time to give your customers what they want. In this lesson, we will extensively talk about Order management in Prestashop, how to deal with refunds, and also create orders from the back office. Running Time: 26 mins / 23 mins Watch the screencast &#8211; 1.6 version Watch the screencast &#8211; 1.5 version &#160; All [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/order-management/">Prestashop 101 Day 9 &#8211; Order Management</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s time to give your customers what they want. In this lesson, we will extensively talk about Order management in Prestashop, how to deal with refunds, and also create orders from the back office.</p>
<p><span id="more-920"></span></p>
<ul>
<li><strong>Running Time</strong>: 26 mins / 23 mins</li>
</ul>
<div class="separator"></div>
<h2>Watch the screencast &#8211; 1.6 version</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/cZ2U8hVuAEc#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>
<h2>Watch the screencast &#8211; 1.5 version</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/22Q2NY2zAqM" 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>All series&#8217; lessons</h3>
<h3>Prestashop 1.6</h3>
<ul><li><a href="http://nemops.com/prestashop-101-day-1-installing-prestashop" title="Prestashop 101 Day 1 – Introducing and installing Prestashop">Prestashop 101 Day 1 – Introducing and installing Prestashop</a></li><li><a href="http://nemops.com/prestashop-101-prestashop-configuration" title="Prestashop 101 Day 2 – Basic Prestashop Configuration">Prestashop 101 Day 2 – Basic Prestashop Configuration</a></li><li><a href="http://nemops.com/prestashop-categories-and-products" title="Prestashop 101 Day 3 – Prestashop categories and products">Prestashop 101 Day 3 – Prestashop categories and products</a></li><li><a href="http://nemops.com/prestashop-attributes" title="Prestashop 101 Day 4 – Prestashop attributes combinations">Prestashop 101 Day 4 – Prestashop attributes combinations</a></li><li><a href="http://nemops.com/prestashop-upgrade" title="Prestashop 101 Day 5 – Prestashop Upgrade">Prestashop 101 Day 5 – Prestashop Upgrade</a></li><li><a href="http://nemops.com/prestashop-modules" title="Prestashop 101 Day 6 – Prestashop Modules">Prestashop 101 Day 6 – Prestashop Modules</a></li><li><a href="http://nemops.com/prestashop-shipping-zones-countries" title="Prestashop 101 Day 7 – Prestashop Shipping, Zones and Countries">Prestashop 101 Day 7 – Prestashop Shipping, Zones and Countries</a></li><li><a href="http://nemops.com/prestashop-payments-currencies-taxes" title="Prestashop 101 Day 8 – Taxes, Currencies, Payments">Prestashop 101 Day 8 – Taxes, Currencies, Payments</a></li><li>Prestashop 101 Day 9 – Order Management</li><li><a href="http://nemops.com/prestashop-customers" title="Prestashop 101 Day 10 – Prestashop Customers">Prestashop 101 Day 10 – Prestashop Customers</a></li><li><a href="http://nemops.com/prestashop-discounts-cart-rules" title="Prestashop 101 Day 11 – Prestashop Discounts (Cart rules)">Prestashop 101 Day 11 – Prestashop Discounts (Cart rules)</a></li></ul>
<h3>Prestashop 1.5</h3>
<ul><li><a href="http://nemops.com/prestashop-101-day-1-installing-prestashop" title="Prestashop 101 Day 1 – Introducing and installing Prestashop">Prestashop 101 Day 1 – Introducing and installing Prestashop</a></li><li><a href="http://nemops.com/prestashop-101-prestashop-configuration" title="Prestashop 101 Day 2 – Basic Prestashop Configuration">Prestashop 101 Day 2 – Basic Prestashop Configuration</a></li><li><a href="http://nemops.com/prestashop-categories-and-products" title="Prestashop 101 Day 3 – Prestashop categories and products">Prestashop 101 Day 3 – Prestashop categories and products</a></li><li><a href="http://nemops.com/prestashop-attributes" title="Prestashop 101 Day 4 – Prestashop attributes combinations">Prestashop 101 Day 4 – Prestashop attributes combinations</a></li><li><a href="http://nemops.com/prestashop-upgrade" title="Prestashop 101 Day 5 – Prestashop Upgrade">Prestashop 101 Day 5 – Prestashop Upgrade</a></li><li><a href="http://nemops.com/prestashop-modules" title="Prestashop 101 Day 6 – Prestashop Modules">Prestashop 101 Day 6 – Prestashop Modules</a></li><li><a href="http://nemops.com/prestashop-shipping-zones-countries" title="Prestashop 101 Day 7 – Prestashop Shipping, Zones and Countries">Prestashop 101 Day 7 – Prestashop Shipping, Zones and Countries</a></li><li><a href="http://nemops.com/prestashop-payments-currencies-taxes" title="Prestashop 101 Day 8 – Taxes, Currencies, Payments">Prestashop 101 Day 8 – Taxes, Currencies, Payments</a></li><li>Prestashop 101 Day 9 – Order Management</li><li><a href="http://nemops.com/prestashop-customers" title="Prestashop 101 Day 10 – Prestashop Customers">Prestashop 101 Day 10 – Prestashop Customers</a></li><li><a href="http://nemops.com/prestashop-discounts-cart-rules" title="Prestashop 101 Day 11 – Prestashop Discounts (Cart rules)">Prestashop 101 Day 11 – Prestashop Discounts (Cart rules)</a></li><li><a href="http://nemops.com/prestashop-themes" title="Prestashop 101 Day 12 – Prestashop Themes and visual tweaks">Prestashop 101 Day 12 – Prestashop Themes and visual tweaks</a></li><li><a href="http://nemops.com/prestashop-cms" title="Prestashop 101 Day 13 – Prestashop CMS">Prestashop 101 Day 13 – Prestashop CMS</a></li><li><a href="http://nemops.com/prestashop-seo-and-preferences" title="Prestashop 101 Day 14 – Prestashop SEO and Preferences">Prestashop 101 Day 14 – Prestashop SEO and Preferences</a></li><li><a href="http://nemops.com/prestashop-multistore" title="Prestashop 101 Day 15 – Prestashop Multistore">Prestashop 101 Day 15 – Prestashop Multistore</a></li><li><a href="http://nemops.com/prestashop-employees-and-languages/#.U2f_LPna6r0" title="Prestashop 101 Day 16 – Employees and Languages">Prestashop 101 Day 16 – Employees and Languages</a></li></ul>
<p>The post <a rel="nofollow" href="http://nemops.com/order-management/">Prestashop 101 Day 9 &#8211; Order Management</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/order-management/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding pagination to the Prestashop Order History</title>
		<link>http://nemops.com/prestashop-order-history-pagination/</link>
		<comments>http://nemops.com/prestashop-order-history-pagination/#comments</comments>
		<pubDate>Wed, 10 Sep 2014 10:16:38 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[pagination]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2145</guid>
		<description><![CDATA[<p>In this article we will see how to add pagination to the order history in Prestashop, so that our customers can more easily reach their past orders information. Action Plan Before starting with any modification, it&#8217;s important to have a clear action plan. There are three files we need to amend/extend, in order to paginate [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-order-history-pagination/">Adding pagination to the Prestashop Order History</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this article we will see how to add pagination to the order history in Prestashop, so that our customers can more easily reach their past orders information.</p>
<p><span id="more-2145"></span></p>
<a class="download-files button style1" href="http://nemops.com/wp-content/uploads/2014/09/historypagination_files.zip" title="Download Project Files">Download Project Files</a>
<h2>Action Plan</h2>
<p>Before starting with any modification, it&#8217;s important to have a clear action plan. There are three files we need to amend/extend, in order to paginate the customer order history:</p>
<ul>
<li>Order.php (the Order class)</li>
<li>HistoryController.php (the controller ran in the order history page)</li>
<li>history.tpl (the template used to display orders)</li>
</ul>
<p>In terms of hard modifications, we will only be directly editing the history.tpl file (although you can also decide to create a new theme instead of modifying the base one). For the Order class and History controllers we will, as I always recommend, place a couple of overrides. To extend the default functionality. Therefore, if you don&#8217;t know much about overrides, have a look at the <a href="http://doc.prestashop.com/display/PS15/Overriding+default+behaviors#Overridingdefaultbehaviors-Overridingaclass" title="Official Prestashop Documentation on overrides">Official Prestashop Documentation on overrides</a>.</p>
<div class="separator"></div>
<h2>1. Extending the Order Class</h2>
<p>Create a new file inside <em>override/classes/Order</em> (or simply override/classes/) and name it <strong>Order.php</strong>, then paste the following base override code inside php tags:</p>
<pre class="brush: php; title: ; notranslate">
class Order extends OrderCore
{
}
</pre>
<p>The method we need to override is <strong>Order::GetCustomerOrders</strong>, and looks like the following in Prestashop 1.6.0.8:</p>
<pre class="brush: php; title: ; notranslate">

	public static function getCustomerOrders($id_customer, $showHiddenStatus = false, Context $context = null)
	{
		if (!$context)
			$context = Context::getContext();

		$res = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
		SELECT o.*, (SELECT SUM(od.`product_quantity`) FROM `'._DB_PREFIX_.'order_detail` od WHERE od.`id_order` = o.`id_order`) nb_products
		FROM `'._DB_PREFIX_.'orders` o
		WHERE o.`id_customer` = '.(int)$id_customer.'
		GROUP BY o.`id_order`
		ORDER BY o.`date_add` DESC');
		if (!$res)
			return array();

		foreach ($res as $key =&gt; $val)
		{
			$res2 = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
				SELECT os.`id_order_state`, osl.`name` AS order_state, os.`invoice`, os.`color` as order_state_color
				FROM `'._DB_PREFIX_.'order_history` oh
				LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = oh.`id_order_state`)
				INNER JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$context-&gt;language-&gt;id.')
			WHERE oh.`id_order` = '.(int)($val['id_order']).(!$showHiddenStatus ? ' AND os.`hidden` != 1' : '').'
				ORDER BY oh.`date_add` DESC, oh.`id_order_history` DESC
			LIMIT 1');

			if ($res2)
				$res[$key] = array_merge($res[$key], $res2[0]);

		}
		return $res;
	}

</pre>
<p>As you can see, there is no reference whatsoever to any kind of pagination. That&#8217;s what we need, so copy the whole method inside the override, then start by adding two extra parameters to the method itself</p>
<pre class="brush: php; title: ; notranslate">

	public static function getCustomerOrders($id_customer, $showHiddenStatus = false, Context $context = null, $p = 1, $n = 5)
	{
		...
	}

</pre>
<p><strong>$p</strong> will hold the page number, while <strong>$n</strong> will be the number of orders per page we want to grab. We are also setting defaults as the base method doesn&#8217;t have such values, and this would create issues with standard calls.</p>
<p>The next step is to take care of 0 values, just in case, so if $p is 0, for any reason, we set it&#8217;s value back to one.</p>
<pre class="brush: php; title: ; notranslate">
	public static function getCustomerOrders($id_customer, $showHiddenStatus = false, Context $context = null, $p = 1, $n = 5)
	{
		if (!$context)
			$context = Context::getContext();
		if ($p &lt; 1) $p = 1;
		
		$res = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
		SELECT o.*, (SELECT SUM(od.`product_quantity`) FROM `'._DB_PREFIX_.'order_detail` od WHERE od.`id_order` = o.`id_order`) nb_products
		FROM `'._DB_PREFIX_.'orders` o
		WHERE o.`id_customer` = '.(int)$id_customer.'
		GROUP BY o.`id_order`
		ORDER BY o.`date_add` DESC');
		if (!$res)
			return array();

		...

	}
</pre>
<p>Then, the real deal, let&#8217;s limit the <strong>$res</strong> query results depending on the chosen page:</p>
<pre class="brush: php; title: ; notranslate">
	public static function getCustomerOrders($id_customer, $showHiddenStatus = false, Context $context = null, $p = 1, $n = 5)
	{
		if (!$context)
			$context = Context::getContext();
		if ($p &lt; 1) $p = 1;
		
		$res = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
		SELECT o.*, (SELECT SUM(od.`product_quantity`) FROM `'._DB_PREFIX_.'order_detail` od WHERE od.`id_order` = o.`id_order`) nb_products
		FROM `'._DB_PREFIX_.'orders` o
		WHERE o.`id_customer` = '.(int)$id_customer.'
		GROUP BY o.`id_order`
		ORDER BY o.`date_add` DESC LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n );
		if (!$res)
			return array();

		...

	}
</pre>
<p>The important part here is the LIMIT clause:</p>
<pre class="brush: php; title: ; notranslate">
...
ORDER BY o.`date_add` DESC LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n );
...
</pre>
<p>Which is simply a 1:1 copy of the category pagination code, as it multiplies the current page, minus one, for the number or items per page, and grabs as many of them as specified by the number itself.</p>
<p>This is as far as we need to go for the current override. The final code will look like:</p>
<pre class="brush: php; title: ; notranslate">

class Order extends OrderCore
{
	
	public static function getCustomerOrders($id_customer, $showHiddenStatus = false, Context $context = null, $p = 1, $n = 5)
	{
		if (!$context)
			$context = Context::getContext();

		if ($p &lt; 1) $p = 1;
		
		$res = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
		SELECT o.*, (SELECT SUM(od.`product_quantity`) FROM `'._DB_PREFIX_.'order_detail` od WHERE od.`id_order` = o.`id_order`) nb_products
		FROM `'._DB_PREFIX_.'orders` o
		WHERE o.`id_customer` = '.(int)$id_customer.'
		GROUP BY o.`id_order`
		ORDER BY o.`date_add` DESC LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n );
		if (!$res)
			return array();


		foreach ($res as $key =&gt; $val)
		{
			$res2 = Db::getInstance(_PS_USE_SQL_SLAVE_)-&gt;executeS('
				SELECT os.`id_order_state`, osl.`name` AS order_state, os.`invoice`, os.`color` as order_state_color
				FROM `'._DB_PREFIX_.'order_history` oh
				LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = oh.`id_order_state`)
				INNER JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$context-&gt;language-&gt;id.')
			WHERE oh.`id_order` = '.(int)($val['id_order']).(!$showHiddenStatus ? ' AND os.`hidden` != 1' : '').'
				ORDER BY oh.`date_add` DESC, oh.`id_order_history` DESC
			LIMIT 1');

			if ($res2)
				$res[$key] = array_merge($res[$key], $res2[0]);

		}
		return $res;
	}
}
</pre>
<div class="separator"></div>
<h2>2. Extending the order History Override</h2>
<p>This part is the trickiest. We need to add a fair amount of code to this controller, so that all pagination variables are set in the template too. As a first step, let&#8217;s create the override itself in <em>override/controllers/front/</em>, declare the base class information, and then paste in the original <strong>initContent()</strong> method:</p>
<pre class="brush: php; title: ; notranslate">

class HistoryController extends HistoryControllerCore
{
	
	public function initContent()
	{
		parent::initContent();

		if ($orders = Order::getCustomerOrders($this-&gt;context-&gt;customer-&gt;id))
			foreach ($orders as &amp;$order)
			{
				$myOrder = new Order((int)$order['id_order']);
				if (Validate::isLoadedObject($myOrder))
					$order['virtual'] = $myOrder-&gt;isVirtual(false);
			}
		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'orders' =&gt; $orders,
			'invoiceAllowed' =&gt; (int)(Configuration::get('PS_INVOICE')),
			'reorderingAllowed' =&gt; !(int)(Configuration::get('PS_DISALLOW_HISTORY_REORDERING')),
			'slowValidation' =&gt; Tools::isSubmit('slowvalidation')
		));

		$this-&gt;setTemplate(_PS_THEME_DIR_.'history.tpl');
	}

}
</pre>
<p>The first thing we want to do is take advantage of our new pagination variables in the getCustomerOrders method:</p>
<pre class="brush: php; title: ; notranslate">

class HistoryController extends HistoryControllerCore
{
	
	public function initContent()
	{
		parent::initContent();

		$p = Tools::getValue('p');
		$n = 5;


		if ($orders = Order::getCustomerOrders($this-&gt;context-&gt;customer-&gt;id, false, null, $p, $n))
			foreach ($orders as &amp;$order)
			{
				$myOrder = new Order((int)$order['id_order']);
				if (Validate::isLoadedObject($myOrder))
					$order['virtual'] = $myOrder-&gt;isVirtual(false);
			}
		...
	}

}

</pre>
<p>Notice we are hard setting the number of orders per page to 5, using the $n variable.</p>
<p>At this point, we can already test out our modifications. Reach the <em>cache/</em> folder and erase <strong>class_index.php</strong>. Some recent versions have a small bug that prevents it from being created. If you run into this issue, try <strong><a href="https://github.com/PrestaShop/PrestaShop/blob/8288a6fffa0eb7a42b280298f798ff9292dd7be3/classes/PrestaShopAutoload.php" title="Prestashop autoload fix">this autoload fix</a></strong>.</p>
<p>Then, reach the order history page and try various settings for $n and $p to see if it works. To test pagination you can also add ?p=3 or any number to the url. Of course, you will get no orders if you go above the total order number with the page.</p>
<h3>Setting up pagination in the controller</h3>
<p>As we cannot ask customers to input a page number in the url, we need to prepare the template to receive pagination variables. RIght after the previous code, add:</p>
<pre class="brush: php; title: ; notranslate">
		// to paginate, get the total order number 
		$nb_orders = Order::getCustomerNbOrders($this-&gt;context-&gt;customer-&gt;id);
		$pages_nb = ceil($nb_orders / (int)$n);

		$range = 2; /* how many pages around page selected */
		$start = (int)($p - $range);
		if ($start &lt; 1)
			$start = 1;
		$stop = (int)($p + $range);
		if ($stop &gt; $pages_nb)
			$stop = (int)$pages_nb;

		if (!$p) $p = 1;


		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'pages_nb' =&gt; $pages_nb,
			'prev_p' =&gt; $p != 1 ? $p - 1 : 1,
			'next_p' =&gt; (int)$p + 1  &gt; $pages_nb ? $pages_nb : $p + 1,
			'requestPage' =&gt; $this-&gt;context-&gt;link-&gt;getPageLink('history'),
			'p' =&gt; $p,
			'n' =&gt; $n,
			'range' =&gt; $range,
			'start' =&gt; $start,
			'stop' =&gt; $stop,
		));


</pre>
<p><strong>Explanation</strong>: we are getting some of these pagination variables directly from the default pagination system. We need to know the total number of orders, the number of pages, and the range around the current page for which we can show links (so we are not displaying ALL available pages, but we use dots). Then, we simply assign all these (and a couple more, like the request page, the previous and next numbers.</p>
<p>The final override:</p>
<pre class="brush: php; title: ; notranslate">


/**
* History Controller Override to allow pagination
*/

class HistoryController extends HistoryControllerCore
{
	
	public function initContent()
	{
		parent::initContent();

		$p = Tools::getValue('p');
		$n = 10;


		if ($orders = Order::getCustomerOrders($this-&gt;context-&gt;customer-&gt;id, false, null, $p, $n))
			foreach ($orders as &amp;$order)
			{
				$myOrder = new Order((int)$order['id_order']);
				if (Validate::isLoadedObject($myOrder))
					$order['virtual'] = $myOrder-&gt;isVirtual(false);
			}


		// to paginate, get the total order number 
		$nb_orders = Order::getCustomerNbOrders($this-&gt;context-&gt;customer-&gt;id);
		$pages_nb = ceil($nb_orders / (int)$n);

		$range = 2; /* how many pages around page selected */
		$start = (int)($p - $range);
		if ($start &lt; 1)
			$start = 1;
		$stop = (int)($p + $range);
		if ($stop &gt; $pages_nb)
			$stop = (int)$pages_nb;

		if (!$p) $p = 1;

		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'pages_nb' =&gt; $pages_nb,
			'prev_p' =&gt; $p != 1 ? $p - 1 : 1,
			'next_p' =&gt; (int)$p + 1  &gt; $pages_nb ? $pages_nb : $p + 1,
			'requestPage' =&gt; $this-&gt;context-&gt;link-&gt;getPageLink('history'),
			'p' =&gt; $p,
			'n' =&gt; $n,
			'range' =&gt; $range,
			'start' =&gt; $start,
			'stop' =&gt; $stop,
		));

		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'orders' =&gt; $orders,
			'invoiceAllowed' =&gt; (int)(Configuration::get('PS_INVOICE')),
			'reorderingAllowed' =&gt; !(int)(Configuration::get('PS_DISALLOW_HISTORY_REORDERING')),
			'slowValidation' =&gt; Tools::isSubmit('slowvalidation')
		));

		$this-&gt;setTemplate(_PS_THEME_DIR_.'history.tpl');
	}

}
</pre>
<div class="separator"></div>
<h2>Adding pagination to the template</h2>
<p>This will be the easiest part. Unless your version is really different (major release) from the one used in this tutorial (1.6.0.8), you should be able to get away with this by simply copying and pasting the provided snippet. First, open up <strong>history.tpl</strong>, and place the cursor right <strong>before </strong> </p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;div id=&quot;block-order-detail&quot; class=&quot;unvisible&quot;&gt;&amp;nbsp;&lt;/div&gt;
</pre>
<p>But after the closing table tag. Then simply paste in the following:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">


		{if $start!=$stop}
			&lt;ul class=&quot;pagination&quot;&gt;
				{if $p != 1 &amp;&amp; $p}
					{assign var='p_previous' value=$p-1}
					&lt;li id=&quot;pagination_previous{if isset($paginationId)}_{$paginationId}{/if}&quot; class=&quot;pagination_previous&quot;&gt;
						&lt;a rel=&quot;nofollow&quot; href=&quot;{$requestPage}?p={$prev_p}&quot;&gt;
							&lt;i class=&quot;icon-chevron-left&quot;&gt;&lt;/i&gt; &lt;b&gt;{l s='Previous'}&lt;/b&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{else}
					&lt;li id=&quot;pagination_previous{if isset($paginationId)}_{$paginationId}{/if}&quot; class=&quot;disabled pagination_previous&quot;&gt;
						&lt;span&gt;
							&lt;i class=&quot;icon-chevron-left&quot;&gt;&lt;/i&gt; &lt;b&gt;{l s='Previous'}&lt;/b&gt;
						&lt;/span&gt;
					&lt;/li&gt;
				{/if}
				{if $start==3}
					&lt;li&gt;
						&lt;a rel=&quot;nofollow&quot;  href=&quot;{$link-&gt;goPage($requestPage, 1)}&quot;&gt;
							&lt;span&gt;1&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
					&lt;li&gt;
						&lt;a rel=&quot;nofollow&quot;  href=&quot;{$link-&gt;goPage($requestPage, 2)}&quot;&gt;
							&lt;span&gt;2&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{/if}
				{if $start==2}
					&lt;li&gt;
						&lt;a rel=&quot;nofollow&quot;  href=&quot;{$link-&gt;goPage($requestPage, 1)}&quot;&gt;
							&lt;span&gt;1&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{/if}
				{if $start&gt;3}
					&lt;li&gt;
						&lt;a rel=&quot;nofollow&quot;  href=&quot;{$link-&gt;goPage($requestPage, 1)}&quot;&gt;
							&lt;span&gt;1&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
					&lt;li class=&quot;truncate&quot;&gt;
						&lt;span&gt;
							&lt;span&gt;...&lt;/span&gt;
						&lt;/span&gt;
					&lt;/li&gt;
				{/if}
				{section name=pagination start=$start loop=$stop+1 step=1}
					{if $p == $smarty.section.pagination.index}
						&lt;li class=&quot;active current&quot;&gt;
							&lt;span&gt;
								&lt;span&gt;{$p|escape:'html':'UTF-8'}&lt;/span&gt;
							&lt;/span&gt;
						&lt;/li&gt;
					{else}
						&lt;li&gt;
							&lt;a rel=&quot;nofollow&quot; href=&quot;{$link-&gt;goPage($requestPage, $smarty.section.pagination.index)}&quot;&gt;
								&lt;span&gt;{$smarty.section.pagination.index|escape:'html':'UTF-8'}&lt;/span&gt;
							&lt;/a&gt;
						&lt;/li&gt;
					{/if}
				{/section}
				{if $pages_nb&gt;$stop+2}
					&lt;li class=&quot;truncate&quot;&gt;
						&lt;span&gt;
							&lt;span&gt;...&lt;/span&gt;
						&lt;/span&gt;
					&lt;/li&gt;
					&lt;li&gt;
						&lt;a href=&quot;{$link-&gt;goPage($requestPage, $pages_nb)}&quot;&gt;
							&lt;span&gt;{$pages_nb|intval}&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{/if}
				{if $pages_nb==$stop+1}
					&lt;li&gt;
						&lt;a href=&quot;{$link-&gt;goPage($requestPage, $pages_nb)}&quot;&gt;
							&lt;span&gt;{$pages_nb|intval}&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{/if}
				{if $pages_nb==$stop+2}
					&lt;li&gt;
						&lt;a href=&quot;{$link-&gt;goPage($requestPage, $pages_nb-1)}&quot;&gt;
							&lt;span&gt;{$pages_nb-1|intval}&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
					&lt;li&gt;
						&lt;a href=&quot;{$link-&gt;goPage($requestPage, $pages_nb)}&quot;&gt;
							&lt;span&gt;{$pages_nb|intval}&lt;/span&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{/if}
				{if $pages_nb &gt; 1 AND $p != $pages_nb}
					{assign var='p_next' value=$p+1}
					&lt;li id=&quot;pagination_next{if isset($paginationId)}_{$paginationId}{/if}&quot; class=&quot;pagination_next&quot;&gt;
						&lt;a rel=&quot;nofollow&quot; href=&quot;{$requestPage}?p={$next_p}&quot;&gt;
							&lt;b&gt;{l s='Next'}&lt;/b&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;
						&lt;/a&gt;
					&lt;/li&gt;
				{else}
					&lt;li id=&quot;pagination_next{if isset($paginationId)}_{$paginationId}{/if}&quot; class=&quot;disabled pagination_next&quot;&gt;
						&lt;span&gt;
							&lt;b&gt;{l s='Next'}&lt;/b&gt; &lt;i class=&quot;icon-chevron-right&quot;&gt;&lt;/i&gt;
						&lt;/span&gt;
					&lt;/li&gt;
				{/if}
			&lt;/ul&gt;
		{/if}



</pre>
<p>And save. It&#8217;s a bit troublesome to explain everything going on here. It&#8217;s basically a 1:1 copy from the default pagination, where I removed most of the useless variables.</p>
<p><strong>Make sure the order number is more than the orders per page you setup in the controller, or pagination will not show up!</strong></p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-order-history-pagination/">Adding pagination to the Prestashop Order History</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-order-history-pagination/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Add bought products to the Prestashop Order list in the back office</title>
		<link>http://nemops.com/bought-products-prestashop-order-list/</link>
		<comments>http://nemops.com/bought-products-prestashop-order-list/#comments</comments>
		<pubDate>Tue, 11 Feb 2014 08:48:42 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=1872</guid>
		<description><![CDATA[<p>In today&#8217;s tutorial we will see how to show bought products in the back office order list, and also how to enable filtering by this parameter. Introduction Last year, we saw how to filter by country in the Prestashop order list, which is indeed useful when your customer base is spread around the world. Today, [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/bought-products-prestashop-order-list/">Add bought products to the Prestashop Order list in the back office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In today&#8217;s tutorial we will see how to show bought products in the back office order list, and also how to enable filtering by this parameter.</p>
<p><span id="more-1872"></span></p>
<h2>Introduction</h2>
<p>Last year, we saw <a href="http://nemops.com/filter-by-country-prestashop-order-list/#.UvijO_k7ur0" title="how to filter by country in the Prestashop order list" target="_blank">how to filter by country in the Prestashop order list</a>, which is indeed useful when your customer base is spread around the world. Today, we will add another parameter to the orders table, showing us <strong>which products</strong> are part of the order, effectively saving us a lot of time in many situations when we only need to know what is to be shipped.</p>
<p>One override will be enough to achieve this result: <strong>AdminOrdersController</strong>.</p>
<div class="separator"></div>
<h2>Overriding the AdminOrdersController</h2>
<p>To start off, create a new file in <em>override/controllers/admin</em> and call it <strong>AdminOrderController.php</strong>. We need to override the construct method; therefore start by adding the following inside php tags:</p>
<pre class="brush: php; title: ; notranslate">
class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{

	}
}
</pre>
<p>If you don&#8217;t know anything about overrides, have a look at <a href="http://doc.prestashop.com/display/PS15/Overriding+default+behaviors#Overridingdefaultbehaviors-OverridingPrestaShop%27sclassesandcontrollers" rel="nofollow" title="how to override Prestashop classes and controllers" target="_blank">how to override Prestashop classes and controllers</a> at Prestashop&#8217;s Doc.</p>
<p>Now let&#8217;s add some base parameter. Have a look at your own original AdminOrdersController file (<em>controllers/admin</em>) if you use a version different from 1.5.6.x.</p>
<pre class="brush: php; title: ; notranslate">
class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{
		$this-&gt;table = 'order';
		$this-&gt;className = 'Order';
		$this-&gt;lang = false;
		$this-&gt;addRowAction('view');
		$this-&gt;explicitSelect = true;
		$this-&gt;allow_export = true;
		$this-&gt;deleted = false;
		$this-&gt;context = Context::getContext();
	}
}
</pre>
<p>We didn&#8217;t do anything special here, just setting up the module&#8217;s basics by copying the original method. Time to extend the SELECT statement!</p>
<div class="separator"></div>
<h2>Selecting products within the order query</h2>
<p>Right after the  object definition we added before, we need to extend the  <strong>$this->_select</strong> variable in order to grab products as well. Here is how it looks in the original order controller:</p>
<pre class="brush: php; title: ; notranslate">
	$this-&gt;_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
		IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) &gt; 1, 0, 1) as new';

</pre>
<p>So, grab this, add it after the last lines we wrote, and change it to:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
		(SELECT GROUP_CONCAT(odd.product_name SEPARATOR &quot;, &quot;) FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) as products,
		IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) &gt; 1, 0, 1) as new';
</pre>
<p>As you can see, we added: <strong>(SELECT GROUP_CONCAT(odd.product_name SEPARATOR &#8220;, &#8220;) FROM `&#8217;._DB_PREFIX_.&#8217;order_detail` odd WHERE odd.id_order = a.id_order) as products,</strong>. This is the subquery that will grab products from the order_detail table, given that the order id is the current one, of course! Using GROUP_CONCAT will ensure all products will br shown, separated by a comma and space. You can use any separator you prefer, of course.</p>
<p>Our override so far:</p>
<pre class="brush: php; title: ; notranslate">
class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{
		$this-&gt;table = 'order';
		$this-&gt;className = 'Order';
		$this-&gt;lang = false;
		$this-&gt;addRowAction('view');
		$this-&gt;explicitSelect = true;
		$this-&gt;allow_export = true;
		$this-&gt;deleted = false;
		$this-&gt;context = Context::getContext();

		$this-&gt;_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
		(SELECT GROUP_CONCAT(odd.product_name SEPARATOR &quot;, &quot;) FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) as products,
		IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) &gt; 1, 0, 1) as new';

}


</pre>
<p>We don&#8217;t need extra stuff for the query, so right after the select variable, add:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;_join = '
		LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
		LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
		LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this-&gt;context-&gt;language-&gt;id.')';
		$this-&gt;_orderBy = 'id_order';
		$this-&gt;_orderWay = 'DESC';

		$statuses_array = array();
		$statuses = OrderState::getOrderStates((int)$this-&gt;context-&gt;language-&gt;id);

		foreach ($statuses as $status)
			$statuses_array[$status['id_order_state']] = $status['name'];

</pre>
<p>In any casy, copy everything after your original controller&#8217;s select variable, down to <strong>before</strong> $this->fields_list.</p>
<p>Let&#8217;s now more to showing products!</p>
<div class="separator"></div>
<h2>Displaying the selected products</h2>
<p>To add new fields in the orders table, we need to extend <strong> $this->fields_list</strong>. Therefore, grab the definition from the original controller, and paste it after the last foreach we added. On 1.5.6.x, it looks like this:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;fields_list = array(
		'id_order' =&gt; array(
			'title' =&gt; $this-&gt;l('ID'),
			'align' =&gt; 'center',
			'width' =&gt; 25
		),
		'reference' =&gt; array(
			'title' =&gt; $this-&gt;l('Reference'),
			'align' =&gt; 'center',
			'width' =&gt; 65
		),
		'new' =&gt; array(
			'title' =&gt; $this-&gt;l('New'),
			'width' =&gt; 25,
			'align' =&gt; 'center',
			'type' =&gt; 'bool',
			'tmpTableFilter' =&gt; true,
			'icon' =&gt; array(
				0 =&gt; 'blank.gif',
				1 =&gt; array(
					'src' =&gt; 'note.png',
					'alt' =&gt; $this-&gt;l('First customer order'),
				)
			),
			'orderby' =&gt; false
		),
		'customer' =&gt; array(
			'title' =&gt; $this-&gt;l('Customer'),
			'havingFilter' =&gt; true,
		),
		'total_paid_tax_incl' =&gt; array(
			'title' =&gt; $this-&gt;l('Total'),
			'width' =&gt; 70,
			'align' =&gt; 'right',
			'prefix' =&gt; '&lt;b&gt;',
			'suffix' =&gt; '&lt;/b&gt;',
			'type' =&gt; 'price',
			'currency' =&gt; true
		),
		'payment' =&gt; array(
			'title' =&gt; $this-&gt;l('Payment: '),
			'width' =&gt; 100
		),
		'osname' =&gt; array(
			'title' =&gt; $this-&gt;l('Status'),
			'color' =&gt; 'color',
			'width' =&gt; 280,
			'type' =&gt; 'select',
			'list' =&gt; $statuses_array,
			'filter_key' =&gt; 'os!id_order_state',
			'filter_type' =&gt; 'int',
			'order_key' =&gt; 'osname'
		),
		'date_add' =&gt; array(
			'title' =&gt; $this-&gt;l('Date'),
			'width' =&gt; 130,
			'align' =&gt; 'right',
			'type' =&gt; 'datetime',
			'filter_key' =&gt; 'a!date_add'
		),
		'id_pdf' =&gt; array(
			'title' =&gt; $this-&gt;l('PDF'),
			'width' =&gt; 35,
			'align' =&gt; 'center',
			'callback' =&gt; 'printPDFIcons',
			'orderby' =&gt; false,
			'search' =&gt; false,
			'remove_onclick' =&gt; true)
		);
</pre>
<p>Where to add the product list? I chose to add it right after the customer name. We have to add the new field as an array, like this:</p>
<pre class="brush: php; title: ; notranslate">
		'products' =&gt; array(
			'title' =&gt; $this-&gt;l('Products'),
			'havingFilter' =&gt; true,
			'filter_key' =&gt; 'products',
			'width' =&gt; 370,
		),	
</pre>
<p>In the order, we have the column title (of little importance, it&#8217;s the one shown to the viewer); the possibility to filter by those parameters; the name of the filter key (<strong>caution!</strong> it must be the same as the name of the parameter we grabbed in the select statement!); the column width in pixels.</p>
<p>At this point, add it to the array:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;fields_list = array(
		'id_order' =&gt; array(
			'title' =&gt; $this-&gt;l('ID'),
			'align' =&gt; 'center',
			'width' =&gt; 25
		),
		'reference' =&gt; array(
			'title' =&gt; $this-&gt;l('Reference'),
			'align' =&gt; 'center',
			'width' =&gt; 65
		),
		'new' =&gt; array(
			'title' =&gt; $this-&gt;l('New'),
			'width' =&gt; 25,
			'align' =&gt; 'center',
			'type' =&gt; 'bool',
			'tmpTableFilter' =&gt; true,
			'icon' =&gt; array(
				0 =&gt; 'blank.gif',
				1 =&gt; array(
					'src' =&gt; 'note.png',
					'alt' =&gt; $this-&gt;l('First customer order'),
				)
			),
			'orderby' =&gt; false
		),
		'customer' =&gt; array(
			'title' =&gt; $this-&gt;l('Customer'),
			'havingFilter' =&gt; true,
		),
		'products' =&gt; array(
			'title' =&gt; $this-&gt;l('Products'),
			'havingFilter' =&gt; true,
			'filter_key' =&gt; 'products',
			'width' =&gt; 370,
		),	
		'total_paid_tax_incl' =&gt; array(
			'title' =&gt; $this-&gt;l('Total'),
			'width' =&gt; 70,
			'align' =&gt; 'right',
			'prefix' =&gt; '&lt;b&gt;',
			'suffix' =&gt; '&lt;/b&gt;',
			'type' =&gt; 'price',
			'currency' =&gt; true
		),
		'payment' =&gt; array(
			'title' =&gt; $this-&gt;l('Payment: '),
			'width' =&gt; 100
		),
		'osname' =&gt; array(
			'title' =&gt; $this-&gt;l('Status'),
			'color' =&gt; 'color',
			'width' =&gt; 280,
			'type' =&gt; 'select',
			'list' =&gt; $statuses_array,
			'filter_key' =&gt; 'os!id_order_state',
			'filter_type' =&gt; 'int',
			'order_key' =&gt; 'osname'
		),
		'date_add' =&gt; array(
			'title' =&gt; $this-&gt;l('Date'),
			'width' =&gt; 130,
			'align' =&gt; 'right',
			'type' =&gt; 'datetime',
			'filter_key' =&gt; 'a!date_add'
		),
		'id_pdf' =&gt; array(
			'title' =&gt; $this-&gt;l('PDF'),
			'width' =&gt; 35,
			'align' =&gt; 'center',
			'callback' =&gt; 'printPDFIcons',
			'orderby' =&gt; false,
			'search' =&gt; false,
			'remove_onclick' =&gt; true)
		);
</pre>
<p>We are almost done!</p>
<div class="separator"></div>
<h2>Finishing off the override</h2>
<p>The rest of the override is basically identical to the original file, so from that one, grab everything you find after the fields list in the construct method, and paste it into the override:</p>
<pre class="brush: php; title: ; notranslate">

		$this-&gt;shopLinkType = 'shop';
		$this-&gt;shopShareDatas = Shop::SHARE_ORDER;

		if (Tools::isSubmit('id_order'))
		{
			// Save context (in order to apply cart rule)
			$order = new Order((int)Tools::getValue('id_order'));
			if (!Validate::isLoadedObject($order))
				throw new PrestaShopException('Cannot load Order object');
			$this-&gt;context-&gt;cart = new Cart($order-&gt;id_cart);
			$this-&gt;context-&gt;customer = new Customer($order-&gt;id_customer);
		}

		parent::__construct();

</pre>
<p>Lastly, since we don&#8217;t want our new fields list to be overridden by the original one, change <strong>parent::__construct();</strong> to <strong>AdminController::__construct</strong>.</p>
<p>Save, go to <em>cache/</em> and delete the <strong>class_index.php</strong> file so that our override can take place. We are done!</p>
<p>The final override</p>
<pre class="brush: php; title: ; notranslate">


class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{
		$this-&gt;table = 'order';
		$this-&gt;className = 'Order';
		$this-&gt;lang = false;
		$this-&gt;addRowAction('view');
		$this-&gt;explicitSelect = true;
		$this-&gt;allow_export = true;
		$this-&gt;deleted = false;
		$this-&gt;context = Context::getContext();

		$this-&gt;_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
		(SELECT GROUP_CONCAT(odd.product_name SEPARATOR &quot;, &quot;) FROM `'._DB_PREFIX_.'order_detail` odd WHERE odd.id_order = a.id_order) as products,
		IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) &gt; 1, 0, 1) as new';


		$this-&gt;_join = '
		LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
		LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
		LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this-&gt;context-&gt;language-&gt;id.')';
		$this-&gt;_orderBy = 'id_order';
		$this-&gt;_orderWay = 'DESC';

		$statuses_array = array();
		$statuses = OrderState::getOrderStates((int)$this-&gt;context-&gt;language-&gt;id);

		foreach ($statuses as $status)
			$statuses_array[$status['id_order_state']] = $status['name'];



		$this-&gt;fields_list = array(
		'id_order' =&gt; array(
			'title' =&gt; $this-&gt;l('ID'),
			'align' =&gt; 'center',
			'width' =&gt; 25
		),
		'reference' =&gt; array(
			'title' =&gt; $this-&gt;l('Reference'),
			'align' =&gt; 'center',
			'width' =&gt; 65
		),
		'new' =&gt; array(
			'title' =&gt; $this-&gt;l('New'),
			'width' =&gt; 25,
			'align' =&gt; 'center',
			'type' =&gt; 'bool',
			'tmpTableFilter' =&gt; true,
			'icon' =&gt; array(
				0 =&gt; 'blank.gif',
				1 =&gt; array(
					'src' =&gt; 'note.png',
					'alt' =&gt; $this-&gt;l('First customer order'),
				)
			),
			'orderby' =&gt; false
		),
		'customer' =&gt; array(
			'title' =&gt; $this-&gt;l('Customer'),
			'havingFilter' =&gt; true,
		),
		'products' =&gt; array(
			'title' =&gt; $this-&gt;l('Products'),
			'havingFilter' =&gt; true,
			'filter_key' =&gt; 'products',
			'width' =&gt; 370,
		),	
		'total_paid_tax_incl' =&gt; array(
			'title' =&gt; $this-&gt;l('Total'),
			'width' =&gt; 70,
			'align' =&gt; 'right',
			'prefix' =&gt; '&lt;b&gt;',
			'suffix' =&gt; '&lt;/b&gt;',
			'type' =&gt; 'price',
			'currency' =&gt; true
		),
		'payment' =&gt; array(
			'title' =&gt; $this-&gt;l('Payment: '),
			'width' =&gt; 100
		),
		'osname' =&gt; array(
			'title' =&gt; $this-&gt;l('Status'),
			'color' =&gt; 'color',
			'width' =&gt; 280,
			'type' =&gt; 'select',
			'list' =&gt; $statuses_array,
			'filter_key' =&gt; 'os!id_order_state',
			'filter_type' =&gt; 'int',
			'order_key' =&gt; 'osname'
		),
		'date_add' =&gt; array(
			'title' =&gt; $this-&gt;l('Date'),
			'width' =&gt; 130,
			'align' =&gt; 'right',
			'type' =&gt; 'datetime',
			'filter_key' =&gt; 'a!date_add'
		),
		'id_pdf' =&gt; array(
			'title' =&gt; $this-&gt;l('PDF'),
			'width' =&gt; 35,
			'align' =&gt; 'center',
			'callback' =&gt; 'printPDFIcons',
			'orderby' =&gt; false,
			'search' =&gt; false,
			'remove_onclick' =&gt; true)
		);

		$this-&gt;shopLinkType = 'shop';
		$this-&gt;shopShareDatas = Shop::SHARE_ORDER;

		if (Tools::isSubmit('id_order'))
		{
			// Save context (in order to apply cart rule)
			$order = new Order((int)Tools::getValue('id_order'));
			if (!Validate::isLoadedObject($order))
				throw new PrestaShopException('Cannot load Order object');
			$this-&gt;context-&gt;cart = new Cart($order-&gt;id_cart);
			$this-&gt;context-&gt;customer = new Customer($order-&gt;id_customer);
		}

		AdminController::__construct();
	}
}


</pre>
<div class="separator"></div>
<h3>Additional Resources</h3>
<ul>
<li><a target="_blank" href="http://nemops.com/filter-by-country-prestashop-order-list/#.UvijO_k7ur0" title="How to filter by country in the Prestashop order list">How to filter by country in the Prestashop order list</a></li>
<li><a href="http://doc.prestashop.com/display/PS15/Overriding+default+behaviors#Overridingdefaultbehaviors-OverridingPrestaShop%27sclassesandcontrollers" rel="nofollow" title="How to override Prestashop classes and controllers" target="_blank">How to override Prestashop classes and controllers</a> at Prestashop&#8217;s Doc.</li>
</ul>
<p>The post <a rel="nofollow" href="http://nemops.com/bought-products-prestashop-order-list/">Add bought products to the Prestashop Order list in the back office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/bought-products-prestashop-order-list/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Adding a &#8220;I received my order&#8221; button in Prestashop</title>
		<link>http://nemops.com/order-received-button-prestashop/</link>
		<comments>http://nemops.com/order-received-button-prestashop/#comments</comments>
		<pubDate>Wed, 05 Feb 2014 10:10:14 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[order status]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=1843</guid>
		<description><![CDATA[<p>For many types of business it is fundamental to know whether the order has been received by the client or not, especially when using non-traceable carriers. Today we will give our customers an option to mark an order as received, saving us time and trouble. Compatibility: Prestashop 1.5 Why asking customers if they received an [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/order-received-button-prestashop/">Adding a &#8220;I received my order&#8221; button in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>For many types of business it is fundamental to know whether the order has been received by the client or not, especially when using non-traceable carriers. Today we will give our customers an option to mark an order as received, saving us time and trouble.</p>
<p><span id="more-1843"></span></p>
<a class="download-files button style1" href="http://nemops.com/wp-content/uploads/2014/02/order_received.zip" title="Download Project Files">Download Project Files</a>
<ul>
<li>Compatibility: Prestashop 1.5</li>
</ul>
<div class="separator"></div>
<h2>Why asking customers if they received an order?</h2>
<p>Depending on the type of business you run, you might want to be sure some items have actually been delivered to your customers, whether you ship with tracked carriers or free postage (without tracking number).</p>
<p>Unless you integrated the carrier&#8217;s API into Prestashop, so that an order status can automatically be updated upon destination reach (impossible in the latter case, anyway), you&#8217;d find yourself having to manually check each and every order, to make sure it has actually been received. Giving customers the chance to manually notify themselves whether an order was delivered or not can save us a huge amount of time, and partially overcome the non-tracked carrier&#8217;s flaws.</p>
<p>In this tutorial, we will make use of one override, and modify 2 theme files. Specifically:</p>
<ul>
<li>OrderDetailController Override</li>
<li>order-detail.tpl</li>
<li>history.js	</li>
</ul>
<p>We will make use of the default order statuses <strong>Shipped</strong> and <strong>Delivered</strong> for the given example, but feel free to use your own, keeping in mind their ids as we add the necessary code snippets.</p>
<p>Next thing to notice is that, by default, the order detail page is grabbed using javascript, directly from the history page, and thus we have to account for an ajax call that points to the controller override.</p>
<p>Lastly, please note that the following applies to registered customers only, not to guests.</p>
<div class="separator"></div>
<h2>Step 1 &#8211; Adding the &#8220;I received this order&#8221; button</h2>
<p>The very first thing we need to do is add some kind of button the customer can click. The ideal page for this is, of course, the order detail one, which can be accessed via the user account panel:</p>
<p><a href="http://nemops.com/wp-content/uploads/2014/02/orderdetail.png"><img src="http://nemops.com/wp-content/uploads/2014/02/orderdetail-680x554.png" alt="Prestashop order detail" width="680" height="554" class="aligncenter size-large wp-image-1847" /></a></p>
<p>As you can see, this order has been shipped already, and thus the customer should be able to tell us if it was delivered or not. Since there is a step-by-step order follow section already, let&#8217;s add our button there. After making sure you got a theme&#8217;s backup in case of failure, open order-detail.tpl, located, in my case, in <em>themes/default/</em>.</p>
<p>Look for:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;h3&gt;{l s='Follow your order\'s status step-by-step'}&lt;/h3&gt;
</pre>
<p>And add the following right after, but <strong>before</strong> the table_block div:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if $order_history.0.id_order_state == 4}
	&lt;form action=&quot;{$link-&gt;getPageLink('order-detail', true)|escape:'html'}&quot; method=&quot;post&quot; class=&quot;std&quot; id=&quot;markAsReceived&quot;&gt;
		&lt;input type=&quot;hidden&quot; class=&quot;hidden&quot; value=&quot;{$order-&gt;id|intval}&quot; name=&quot;id_order&quot; /&gt;
		&lt;input type=&quot;submit&quot; class=&quot;exclusive&quot; name=&quot;markAsReceived&quot; id=&quot;markAsReceivedBtn&quot; value=&quot;{l s='I have received this order'}&quot;&gt;
		&lt;p class=&quot;clear&quot;&gt;&lt;/p&gt;
	&lt;/form&gt;

{/if}
</pre>
<p><strong>Explanation:</strong> Remember we mentioned the default <strong>order statuses</strong> at the beginning of the article? Well, in this conditional <strong>if</strong> statement, we are taking advantage of the <strong>Shipped</strong> status, which has 4 as status ID. Therefore, customers will only see the button if the current order has been set to Shipped. We access it using the variable <strong>$order_history</strong>, which is an array. Therefore, we get the most recent element&#8217;s status (which is the first one of the stack). <br />
Then, we open a form that points to the order-detail page (and relative controller), so that our <strong>markAsReceived</strong> parameter is sent to it. We also need to pass the order id to this form, as the system needs to know which order&#8217;s status needs to be updated later.</p>
<p><a href="http://nemops.com/wp-content/uploads/2014/02/orderdetailbutton.png"><img src="http://nemops.com/wp-content/uploads/2014/02/orderdetailbutton-680x293.png" alt="Prestashop order detail - adding the order received button" width="680" height="293" class="aligncenter size-large wp-image-1848" /></a></p>
<p>We are basically done with the template part. We&#8217;ll come back later to add a confirmation message upon successful order status change.</p>
<h3>How to check order status IDs?</h3>
<p>If you do not wish to use the default statuses, you can easily create your own, and check their IDs from the back office <em>Orders > Statuses</em>.</p>
<p><a href="http://nemops.com/wp-content/uploads/2014/02/orderstatuses.png"><img src="http://nemops.com/wp-content/uploads/2014/02/orderstatuses-680x540.png" alt="Prestashop Order Statuses" width="680" height="540" class="aligncenter size-large wp-image-1849" /></a></p>
<p>The IDs are, needless to say, the ones under the ID column.</p>
<div class="separator"></div>
<h2>Step 2 &#8211; OrderDetailController override</h2>
<p>Create a new php file in <em>override/controllers/front</em> and call it <strong>OrderDetailController.php</strong>. Inside it, add the following within php tags:</p>
<pre class="brush: php; title: ; notranslate">
class OrderDetailController extends OrderDetailControllerCore
{

	public function postProcess()
	{
		parent::postProcess();

		if (Tools::isSubmit('markAsReceived'))
		{
			$idOrder = (int)(Tools::getValue('id_order'));
			$order = new Order($idOrder);

			if(Validate::isLoadedObject($order))
			{
				if($order-&gt;getCurrentState() == 4) // if the order is shipped
				{
					$new_history = new OrderHistory();
					$new_history-&gt;id_order = (int)$order-&gt;id;
					$new_history-&gt;changeIdOrderState(5, $order); // 5: delivered
					$new_history-&gt;addWithemail(true);	
				}

				$this-&gt;context-&gt;smarty-&gt;assign('receipt_confirmation', true);

			} else $this-&gt;_errors[] = Tools::displayError('Error: Invalid order number');
			
		}		

	}


}


</pre>
<p><strong>Explanation:</strong> uh, quite a heavy jump! However, nothing special here, really. We are overriding the core&#8217;s postProcess method, which occurs right after having loaded the controller&#8217;s basic properties, so that other data can be collected and stored. In this case, we first make sure to refer back to the original postProcess(), then check if our <strong>markAsReceived</strong> button has been pressed. <br />
If it has, we grab the order ID we passed, then create a new order object using it. It&#8217;s fundamental to always make sure a Prestashop Object was correctly loaded every time, using <strong>Validate::isLoadedObject($object)</strong>. </p>
<p>If it is a valid object, and then if the current state is shipped (ID = 4) we can add a new order status. To do this, we use the <strong>OrderHistory</strong> class, setting the current order id ($new_history->id_order = (int)$order->id;) and then changing its status to <strong>5</strong> (delivered). Lastly, we submit the order change with $new_history->addWithemail(true). In case an email is to be sent out, it will. After this, we confirm the order has been received and assign a variable to the template, in order to show a confirmation message.</p>
<p>On the other end, we display an error in case the order object was not valid, for any reason.
</p>
<p>At this point, we can already test out the form. But remember to delete the <strong>class_index</strong> file, located inside the <em>/cache/</em> folder first, for the override to take place.</p>
<p>If you did everything correctly, the whole page will be refreshed, redirecting you to the order-detail controller, but with the &#8216;delivered&#8217; status added.</p>
<blockquote><p><span class="bqstart">“</span>It&#8217;s fundamental to always make sure a Prestashop Object was correctly loaded every time, using <strong>Validate::isLoadedObject($object)</strong><span class="bqend">”</span></p></blockquote>
<h3>The confirmation message</h3>
<p>As we want to be polite to our customers, right before the form we added to <strong>order-detail.tpl</strong>, insert the following snippets, to thank them for their feedback.</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($receipt_confirmation) &amp;&amp; $receipt_confirmation}
	&lt;p class=&quot;success&quot;&gt;
		{l s='Thank you for your feedback!'}
	&lt;/p&gt;
{/if}
</pre>
<p>So it looks like:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;h3&gt;{l s='Follow your order\'s status step-by-step'}&lt;/h3&gt;
{if isset($receipt_confirmation) &amp;&amp; $receipt_confirmation}
	&lt;p class=&quot;success&quot;&gt;
		{l s='Thank you for your feedback!'}
	&lt;/p&gt;
{/if}
{if $order_history.0.id_order_state == 4}
	&lt;form action=&quot;{$link-&gt;getPageLink('order-detail', true)|escape:'html'}&quot; method=&quot;post&quot; class=&quot;std&quot; id=&quot;markAsReceived&quot;&gt;


		&lt;input type=&quot;hidden&quot; class=&quot;hidden&quot; value=&quot;{$order-&gt;id|intval}&quot; name=&quot;id_order&quot; /&gt;
		&lt;input type=&quot;submit&quot; class=&quot;exclusive&quot; name=&quot;markAsReceived&quot; id=&quot;markAsReceivedBtn&quot; value=&quot;{l s='I have received this order'}&quot;&gt;
		&lt;p class=&quot;clear&quot;&gt;&lt;/p&gt;
	&lt;/form&gt;

{/if}
</pre>
<p>We could stop here; however, to give our customers a better user experience, we will integrate this button to the ajax style of the order history page.</p>
<div class="separator"></div>
<h2>Step 3 &#8211; Adding some Ajax to history.js</h2>
<p>Open up <strong>history.js</strong>, located in the theme folder, <em>/js/</em>. We have to catch the submit event of the new form first. a suitable place for this is right after the following:</p>
<pre class="brush: jscript; title: ; notranslate">
				$('form#sendOrderMessage').submit(function(){
					return sendOrderMessage();
				
				});
</pre>
<p>That catches the submission of the &#8220;Send a message&#8221; form. You can find it at line 73 in Prestashop 1.5.6.2. Right after, add:</p>
<pre class="brush: jscript; title: ; notranslate">
				$('form#markAsReceived').submit(function(){
					return markAsReceived();
				});
</pre>
<p>Okay, we are returning a function instead of submitting the page. We don&#8217;t have it yet, so let&#8217;s use the sendOrderMessage() one as a base for ours. Add this at the end of the file:</p>
<pre class="brush: jscript; title: ; notranslate">
				
function markAsReceived()
{
	paramString = &quot;ajax=true&quot;;
	$('#markAsReceived').find('input').each(function(){
		paramString += '&amp;' + $(this).attr('name') + '=' + encodeURIComponent($(this).val());
	});
	$.ajax({
		type: &quot;POST&quot;,
		headers: { &quot;cache-control&quot;: &quot;no-cache&quot; },
		url: $('#markAsReceived').attr(&quot;action&quot;) + '?rand=' + new Date().getTime(),
		data: paramString,
		success: function (msg){
			$('#block-order-detail').fadeOut('slow', function() {
				$(this).html(msg);
				//catch the submit event of sendOrderMessage form
				
				$(this).find('#markAsReceivedBtn').fadeOut;
				$(this).fadeIn('slow');
			});
		}
	});
	return false;
}

</pre>
<p><strong>Explanation:</strong> despite having a scary look, there is not much going on under the hood. We first tell the script we will be using ajax, then add each parameter in the form to the POST call we&#8217;ll do. In this case, they will be <strong>markAsReceived</strong> and <strong>id_order</strong>, as we need them in the controller. <br />
Then, we do an ajax call to our override (the url being called is the same of the action property of the form!), passing a random parameter to avoid duplicate calls. At this point, all the previously mentioned operations occur. Upon success, we fade out the entire order detail block, change its content with the one retrieved from the ajax call, fade out the mark as received button and show the order detail block again. Don&#8217;t forget to return false, or call e.preventDefault() at the end, to avoid the page refresh!</p>
<p>Save &#038; test, no page refresh will now occur anymore!</p>
<p><strong>TIP:</strong> instead of creating dozens of new orders for testing purposes, after the status is set to delivered, take it back to shipped so our button is visible again! (as i did in the following image)</p>
<p><a href="http://nemops.com/wp-content/uploads/2014/02/last-screen.png"><img src="http://nemops.com/wp-content/uploads/2014/02/last-screen-680x500.png" alt="Prestashop - I received my order confirmed" width="680" height="500" class="aligncenter size-large wp-image-1850" /></a></p>
<div class="separator"></div>
<h2>Conclusion</h2>
<p>Customers can now inform us when they receive an order. However, an ideal extension to this would be an automated system that sends out emails to all customers who have &#8220;shipped&#8221; but not &#8220;delivered&#8221; orders. Well, we might do it in another tutorial!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/order-received-button-prestashop/">Adding a &#8220;I received my order&#8221; button in Prestashop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/order-received-button-prestashop/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Filtering by country on the Prestashop order list</title>
		<link>http://nemops.com/filter-by-country-prestashop-order-list/</link>
		<comments>http://nemops.com/filter-by-country-prestashop-order-list/#comments</comments>
		<pubDate>Tue, 22 Oct 2013 10:53:10 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[country]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=1645</guid>
		<description><![CDATA[<p>It can be useful to be able to see from which country you received an order, without having to inspect each and every of them. In this tutorial, we will see how to add a &#8216;country&#8217; column to the Prestashop order list, which will also enable us to filter them by country itself. Version used: [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/filter-by-country-prestashop-order-list/">Filtering by country on the Prestashop order list</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>It can be useful to be able to see from which country you received an order, without having to inspect each and every of them. In this tutorial, we will see how to add a &#8216;country&#8217; column to the Prestashop order list, which will also enable us to filter them by country itself.</p>
<p><span id="more-1645"></span></p>
<a class="download-files button style1" href="http://nemops.com/wp-content/uploads/2013/10/AdminOrdersController.zip" title="Download Project Files">Download Project Files</a>
<ul>
<li>Version used: <strong>Prestashop 1.5.6</strong></li>
</ul>
<p>&nbsp;</p>
<p>Once more, in this tutorial we will make use of overrides. To be specific, we will extend the <strong>AdminOrdersController</strong> constructor to first grab all the country related data from our database, and then display the new column. To make some room, we will get  rid of the invoice column, but feel free to simply add the new one, if you need that, or even replace another which is not useful to you. Let&#8217;s get started!</p>
<div class="separator"></div>
<h2>Extending the AdminOrders Controller</h2>
<p>As I always want to stress, when adding new functions to Prestashop, it&#8217;s fundamental not to touch the core, to avoid loosing all modifications at the next upgrade. Therefore, head over to <em>override/controllers/admin</em> and create a new file called <strong>AdminOrdersController.php</strong>. Go back to Prestashop&#8217;s root folder, then <em>cache/</em> and delete <strong>class_index.php</strong> to make sure our beloved e-commerce software can read the new override.</p>
<p>Back to the new file, let&#8217;s start by adding some preliminary class code inside php tags:</p>
<pre class="brush: php; title: ; notranslate">
class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{
		AdminController::__construct();
	}
}
</pre>
<p><strong>Note:</strong> As you can see, we are calling the current class&#8217;s grandfather, instead of direct parent. Why? If we were to use parent::_construct, the original <strong>adminOrdersController</strong> data and settings would have overridden again our modifications, which would have never taken place. Thus, we skip the call to the original class constructor and call AdminController::__construct directly.</p>
<p>At this point, if you visit the order list page, you will have nothing but a blank page. Don&#8217;t freak out! this is just the beginning.</p>
<div class="separator"></div>
<h2>Grabbing all data we need for the new column</h2>
<p>Now, let&#8217;s copy a bunch of properties from the original AdminOrdersController:</p>
<pre class="brush: php; title: ; notranslate">

class AdminOrdersController extends AdminOrdersControllerCore
{

	public function __construct()
	{
		$this-&gt;table = 'order';
		$this-&gt;className = 'Order';
		$this-&gt;lang = false;
		$this-&gt;addRowAction('view');
		$this-&gt;explicitSelect = true;
		$this-&gt;allow_export = true;
		$this-&gt;deleted = false;
		$this-&gt;context = Context::getContext();

		
		AdminController::__construct();
	}

}
</pre>
<p><strong>Make sure</strong> the grandpa&#8217;s call stays at the very bottom of the constructor! Then, it&#8217;s time to tell this class which fields we want to grab. It&#8217;s pretty much the same as the default, with a slight addition. Add the following right before the grandfather&#8217;s constructor&#8217;s call:</p>
<pre class="brush: php; title: ; notranslate">

		$this-&gt;_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		cl.name as country,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
		IF((SELECT COUNT(so.id_order) FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer) &gt; 1, 0, 1) as new';

</pre>
<p>The only addition here is <strong>cl.name as country,</strong>. Now, we need to join all tables we need, of course!</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;_join = '
		LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
		LEFT JOIN `'._DB_PREFIX_.'address` ad ON (ad.`id_address` = a.`id_address_delivery`)
		LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = ad.`id_country` AND cl.`id_lang` = '.(int)$this-&gt;context-&gt;language-&gt;id.')
		LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
		LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this-&gt;context-&gt;language-&gt;id.')';
</pre>
<p>Compared to the original one, this has two new joins:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;_join = '
		LEFT JOIN `'._DB_PREFIX_.'address` ad ON (ad.`id_address` = a.`id_address_delivery`)
		LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = ad.`id_country` AND cl.`id_lang` = '.(int)$this-&gt;context-&gt;language-&gt;id.')
</pre>
<p>Why do we need two? Because, as the first table we are grabbing data from is <strong>ps_orders</strong>, whose alias is <strong>a</strong>, we only have access to the address ID (id_address_delivery). This tells us which address the customer used to checkout. I deliberately chose this one, but you can use <strong>id_address_invoice</strong> instead, if you prefer. At this point, having the address id, we grab the country associated to this very address, by joining the <strong>ps_country_lang</strong> table to get the real name of it.</p>
<p>So, the logical &#8216;table lookup&#8217; to get the country name is <strong>ps_orders.id_address_delivery &raquo; ps_address.id_address &#8211; ps_address.id_country &raquo; ps_country_lang.id_country &#8211; ps_country_lang.name</strong>.</p>
<p>We have all data  we need, what&#8217;s left at this point is copying a bunch of rows from the original controller, and add the new column to the fields list.</p>
<div class="separator"></div>
<h2>Adding the new column to the fields_list</h2>
<p>First things first, right after the last code snippet, add the following, grabbed directly from the original AdminOrdersController:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;_orderBy = 'id_order';
		$this-&gt;_orderWay = 'DESC';

		$statuses_array = array();
		$statuses = OrderState::getOrderStates((int)$this-&gt;context-&gt;language-&gt;id);

		foreach ($statuses as $status)
			$statuses_array[$status['id_order_state']] = $status['name'];


		$this-&gt;fields_list = array(
		'id_order' =&gt; array(
			'title' =&gt; $this-&gt;l('ID'),
			'align' =&gt; 'center',
			'width' =&gt; 25
		),
		'reference' =&gt; array(
			'title' =&gt; $this-&gt;l('Reference'),
			'align' =&gt; 'center',
			'width' =&gt; 65
		),
		'new' =&gt; array(
			'title' =&gt; $this-&gt;l('New'),
			'width' =&gt; 25,
			'align' =&gt; 'center',
			'type' =&gt; 'bool',
			'tmpTableFilter' =&gt; true,
			'icon' =&gt; array(
				0 =&gt; 'blank.gif',
				1 =&gt; array(
					'src' =&gt; 'note.png',
					'alt' =&gt; $this-&gt;l('First customer order'),
				)
			),
			'orderby' =&gt; false
		),
		'customer' =&gt; array(
			'title' =&gt; $this-&gt;l('Customer'),
			'havingFilter' =&gt; true,
		),
		'total_paid_tax_incl' =&gt; array(
			'title' =&gt; $this-&gt;l('Total'),
			'width' =&gt; 70,
			'align' =&gt; 'right',
			'prefix' =&gt; '&lt;b&gt;',
			'suffix' =&gt; '&lt;/b&gt;',
			'type' =&gt; 'price',
			'currency' =&gt; true
		),
		'payment' =&gt; array(
			'title' =&gt; $this-&gt;l('Payment: '),
			'width' =&gt; 100
		),
		'osname' =&gt; array(
			'title' =&gt; $this-&gt;l('Status'),
			'color' =&gt; 'color',
			'width' =&gt; 280,
			'type' =&gt; 'select',
			'list' =&gt; $statuses_array,
			'filter_key' =&gt; 'os!id_order_state',
			'filter_type' =&gt; 'int'
		),
		'date_add' =&gt; array(
			'title' =&gt; $this-&gt;l('Date'),
			'width' =&gt; 130,
			'align' =&gt; 'right',
			'type' =&gt; 'datetime',
			'filter_key' =&gt; 'a!date_add'
		),
		'id_pdf' =&gt; array(
			'title' =&gt; $this-&gt;l('PDF'),
			'width' =&gt; 35,
			'align' =&gt; 'center',
			'callback' =&gt; 'printPDFIcons',
			'orderby' =&gt; false,
			'search' =&gt; false,
			'remove_onclick' =&gt; true)
		);

</pre>
<p>The important part to notice here is the <strong>fields_list</strong> assignment. This contains all columns of the order table, and tells to each one how to behave. As mentioned at the beginning of the tutorial, I will get rid of the last field, id_pdf, in order to make some room for countries. Once more, feel free to simply add the new one.</p>
<p>Here is the array that needs to be added:</p>
<pre class="brush: php; title: ; notranslate">

'country' =&gt; array(
			'title' =&gt; $this-&gt;l('CT'),
			'width' =&gt; 60,
			'align' =&gt; 'center',
			'filter_key' =&gt; 'cl!name')

</pre>
<p><strong>Explanation:</strong> For lists of objects in the back office, Prestashop uses its own helper to build the table. Each of the keys of the fields_list array is the name property of the input box, which will be used to filter this column. Of course, provided that you actually want to filter it. The array values determine properties for the table column, in this case: the text displayed at the top, the column&#8217;s width, whether the text needs to be centered, and the name of the key I want to use as filter. As I mentioned a couple of lines above, by default Prestashop uses the array key to look for a value to filter. If we specify  a <strong>filter_key</strong> in the values array, we can alter the lookup to our content. In this case, if somebody enters a value, say &#8216;Italy&#8217; for the country column, and hits filter, Prestashop will look for &#8216;Italy&#8217; in <strong>cl.name</strong> (notice an exclamation mark must be used in place of the dot here). Simply put: the filter_key value must reflect the database field you want to target when filtering. Once more, in this case, the Country Name.</p>
<blockquote><p><span class="bqstart">&#8220;</span>For lists of objects in the back office, Prestashop uses its own helper to build the table. <span class="bqend">&#8221;</span></p></blockquote>
<p>Going through all the properties of the table helper is beyond the scope of this tutorial, but if you want to dive into it, I suggest you have a look at the various admin controllers Prestashop has, especially the product and category ones. Unfortunately, there is no real documentation about this subject, except for a few lines on <a href="http://doc.prestashop.com/display/PS15/Using+helpers+to+overload+a+back-office+template" target="_blank" title="using templates for helpers within a controller in Prestashop"> using templates for helpers within a controller</a> at doc.prestashop.com.</p>
<p>In any case, here is how the fields_list should look after adding our own dataset:</p>
<pre class="brush: php; title: ; notranslate">

		$this-&gt;fields_list = array(
		'id_order' =&gt; array(
			'title' =&gt; $this-&gt;l('ID'),
			'align' =&gt; 'center',
			'width' =&gt; 25
		),
		'reference' =&gt; array(
			'title' =&gt; $this-&gt;l('Reference'),
			'align' =&gt; 'center',
			'width' =&gt; 65
		),
		'new' =&gt; array(
			'title' =&gt; $this-&gt;l('New'),
			'width' =&gt; 25,
			'align' =&gt; 'center',
			'type' =&gt; 'bool',
			'tmpTableFilter' =&gt; true,
			'icon' =&gt; array(
				0 =&gt; 'blank.gif',
				1 =&gt; array(
					'src' =&gt; 'note.png',
					'alt' =&gt; $this-&gt;l('First customer order'),
				)
			),
			'orderby' =&gt; false
		),
		'customer' =&gt; array(
			'title' =&gt; $this-&gt;l('Customer'),
			'havingFilter' =&gt; true,
		),
		'total_paid_tax_incl' =&gt; array(
			'title' =&gt; $this-&gt;l('Total'),
			'width' =&gt; 70,
			'align' =&gt; 'right',
			'prefix' =&gt; '&lt;b&gt;',
			'suffix' =&gt; '&lt;/b&gt;',
			'type' =&gt; 'price',
			'currency' =&gt; true
		),
		'payment' =&gt; array(
			'title' =&gt; $this-&gt;l('Payment: '),
			'width' =&gt; 100
		),
		'osname' =&gt; array(
			'title' =&gt; $this-&gt;l('Status'),
			'color' =&gt; 'color',
			'width' =&gt; 280,
			'type' =&gt; 'select',
			'list' =&gt; $statuses_array,
			'filter_key' =&gt; 'os!id_order_state',
			'filter_type' =&gt; 'int'
		),
		'date_add' =&gt; array(
			'title' =&gt; $this-&gt;l('Date'),
			'width' =&gt; 130,
			'align' =&gt; 'right',
			'type' =&gt; 'datetime',
			'filter_key' =&gt; 'a!date_add'
		),
		'country' =&gt; array(
			'title' =&gt; $this-&gt;l('CT'),
			'width' =&gt; 60,
			'align' =&gt; 'center',
			'filter_key' =&gt; 'cl!name')
		);


</pre>
<p>We are done, as the only thing left is to copy over a tiny snippet grabbed directly from the original controller, right after the fields_list:</p>
<pre class="brush: php; title: ; notranslate">
		$this-&gt;shopLinkType = 'shop';
		$this-&gt;shopShareDatas = Shop::SHARE_ORDER;

		if (Tools::isSubmit('id_order'))
		{
			// Save context (in order to apply cart rule)
			$order = new Order((int)Tools::getValue('id_order'));
			if (!Validate::isLoadedObject($order))
				throw new PrestaShopException('Cannot load Order object');
			$this-&gt;context-&gt;cart = new Cart($order-&gt;id_cart);
			$this-&gt;context-&gt;customer = new Customer($order-&gt;id_customer);
		}

</pre>
<p>Save, reload the page and try to filter the column. We are done!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/filter-by-country-prestashop-order-list/">Filtering by country on the Prestashop order list</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/filter-by-country-prestashop-order-list/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
