Adding a “I received my order” Button in PrestaShop

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.

Download Project Files

  • Compatibility: Prestashop 1.5

Why asking customers if they received an order?

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).

Unless you integrated the carrier’s API into Prestashop, so that an order status can automatically be updated upon destination reach (impossible in the latter case, anyway), you’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’s flaws.

In this tutorial, we will make use of one override, and modify 2 theme files. Specifically:

  • OrderDetailController Override
  • order-detail.tpl
  • history.js

We will make use of the default order statuses Shipped and Delivered for the given example, but feel free to use your own, keeping in mind their ids as we add the necessary code snippets.

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.

Lastly, please note that the following applies to registered customers only, not to guests.

Step 1 – Adding the “I received this order” button

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:

Prestashop order detail

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’s add our button there. After making sure you got a theme’s backup in case of failure, open order-detail.tpl, located, in my case, in themes/default/.

Look for:

<h3>{l s='Follow your order\'s status step-by-step'}</h3>

And add the following right after, but before the table_block div:

{if $order_history.0.id_order_state == 4}
	<form action="{$link->getPageLink('order-detail', true)|escape:'html'}" method="post" class="std" id="markAsReceived">
		<input type="hidden" class="hidden" value="{$order->id|intval}" name="id_order" />
		<input type="submit" class="exclusive" name="markAsReceived" id="markAsReceivedBtn" value="{l s='I have received this order'}">
		<p class="clear"></p>
	</form>

{/if}

Explanation: Remember we mentioned the default order statuses at the beginning of the article? Well, in this conditional if statement, we are taking advantage of the Shipped 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 $order_history, which is an array. Therefore, we get the most recent element’s status (which is the first one of the stack).
Then, we open a form that points to the order-detail page (and relative controller), so that our markAsReceived parameter is sent to it. We also need to pass the order id to this form, as the system needs to know which order’s status needs to be updated later.

Prestashop order detail - adding the order received button

We are basically done with the template part. We’ll come back later to add a confirmation message upon successful order status change.

How to check order status IDs?

If you do not wish to use the default statuses, you can easily create your own, and check their IDs from the back office Orders > Statuses.

Prestashop Order Statuses

The IDs are, needless to say, the ones under the ID column.

Step 2 – OrderDetailController override

Create a new php file in override/controllers/front and call it OrderDetailController.php. Inside it, add the following within php tags:

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->getCurrentState() = 4) // if the order is shipped
				{
					$new_history = new OrderHistory();
					$new_history->id_order = (int)$order->id;
					$new_history->changeIdOrderState(5, $order); // 5: delivered
					$new_history->addWithemail(true);
				}

				$this->context->smarty->assign('receipt_confirmation', true);

			} else $this->_errors[] = Tools::displayError('Error: Invalid order number');

		}

	}

}

Explanation: uh, quite a heavy jump! However, nothing special here, really. We are overriding the core’s postProcess method, which occurs right after having loaded the controller’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 markAsReceived button has been pressed.
If it has, we grab the order ID we passed, then create a new order object using it. It’s fundamental to always make sure a Prestashop Object was correctly loaded every time, using Validate::isLoadedObject($object).

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 OrderHistory class, setting the current order id ($new_history->id_order = (int)$order->id;) and then changing its status to 5 (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.

On the other end, we display an error in case the order object was not valid, for any reason.

At this point, we can already test out the form. But remember to delete the class_index file, located inside the /cache/ folder first, for the override to take place.

If you did everything correctly, the whole page will be refreshed, redirecting you to the order-detail controller, but with the ‘delivered’ status added.

It’s fundamental to always make sure a Prestashop Object was correctly loaded every time, using Validate::isLoadedObject($object)

The confirmation message

As we want to be polite to our customers, right before the form we added to order-detail.tpl, insert the following snippets, to thank them for their feedback.

{if isset($receipt_confirmation) && $receipt_confirmation}
	<p class="success">
		{l s='Thank you for your feedback!'}
	</p>
{/if}

So it looks like:

<h3>{l s='Follow your order\'s status step-by-step'}</h3>
{if isset($receipt_confirmation) && $receipt_confirmation}
	<p class="success">
		{l s='Thank you for your feedback!'}
	</p>
{/if}
{if $order_history.0.id_order_state == 4}
	<form action="{$link->getPageLink('order-detail', true)|escape:'html'}" method="post" class="std" id="markAsReceived">

		<input type="hidden" class="hidden" value="{$order->id|intval}" name="id_order" />
		<input type="submit" class="exclusive" name="markAsReceived" id="markAsReceivedBtn" value="{l s='I have received this order'}">
		<p class="clear"></p>
	</form>

{/if}

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.

Step 3 – Adding some Ajax to history.js

Open up history.js, located in the theme folder, /js/. We have to catch the submit event of the new form first. a suitable place for this is right after the following:

				$('form#sendOrderMessage').submit(function(){
					return sendOrderMessage();

				});

That catches the submission of the “Send a message” form. You can find it at line 73 in Prestashop 1.5.6.2. Right after, add:

				$('form#markAsReceived').submit(function(){
					return markAsReceived();
				});

Okay, we are returning a function instead of submitting the page. We don’t have it yet, so let’s use the sendOrderMessage() one as a base for ours. Add this at the end of the file:


function markAsReceived()
{
	paramString = "ajax=true";
	$('#markAsReceived').find('input').each(function(){
		paramString += '&' + $(this).attr('name') + '=' + encodeURIComponent($(this).val());
	});
	$.ajax({
		type: "POST",
		headers: { "cache-control": "no-cache" },
		url: $('#markAsReceived').attr("action") + '?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;
}

Explanation: 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’ll do. In this case, they will be markAsReceived and id_order, as we need them in the controller.
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’t forget to return false, or call e.preventDefault() at the end, to avoid the page refresh!

Save & test, no page refresh will now occur anymore!

TIP: 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)

Prestashop - I received my order confirmed

Conclusion

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 “shipped” but not “delivered” orders. Well, we might do it in another tutorial!

Need Prestashop Modules? Have a look at my Prestashop Addons Store!

Looking for quality PrestaShop Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , | Posted under PrestaShop | RSS 2.0

Author Spotlight

Fabio Porta

Fabio Porta

Fabio has been involved in web development and design since 2005, when launched his first website at the age of 16. He’s now highly skilled in both client and server side development, along with design, and since August 2012 runs a successful website about PrestaShop tutorials and Prestashop Modules called Nemo’s Post Scriptum, at http://nemops.com

Leave a Reply

Your email address will not be published. Required fields are marked *


3 + = 5

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>