<?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; country</title>
	<atom:link href="http://nemops.com/tag/country/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>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>
