Getting (and setting) a custom product price (per customer) in Magento

The current project I’m working on has something special: each client has its own price, but this price is not in Magento but in an Oracle DB. Every client on the website has a client id related to the Oracle DB, and in the Oracle DB there is a discount that is different for each client.

The possibility of adding all these price rules for each client in Magento is discarded. Then, the solution is getting that discount and applying it to the product price. This means that the final product price is different for each client (OK, that was our goal).

At this point, we have to find out how to apply that discount to the product price and set the new price in Magento. This is what I’m going to explain in the following lines.

Creating a module

First of all, we need to create a custom module for this. I’m not going to explain how to do so. Go to the Alan Storm (what a cool name!) website and learn!

Once you have created your module, your etc/config.xml file should look like this:

<?xml version=";1.0"; encoding=";UTF-8";?>
<config>
 <modules>
  <COMPANY_CustomPrice>
   <version>0.1.0</version>
  </COMPANY_CustomPrice>
 </modules>
 <global>
  <events>
   <catalog_product_get_final_price>
    <observers>
     <COMPANY_CustomPrice_price_observer>
      <type>singleton</type>
      <class>COMPANY_CustomPrice_Model_Observer</class>
      <method>get_final_price</method>
     </COMPANY_CustomPrice_price_observer>
    </observers>
   </catalog_product_get_final_price>
  </events>
 </global>
</config>

Here we are rewriting the method that gets the final price. Now its time to create the observer. Create a Model/Observer.php file and paste the following code:

<?php

class COMPANY_CustomPrice_Model_Observer
{

 public function __construct()
 {
 }

 public function get_final_price($observer)
 {
  /* Check if the customer is logged in, if so, then we proceed (this can be done on the xml using <customer_is_logged_in> (or something like that...)  */

  if(Mage::getSingleton('customer/session')->isLoggedIn())
  {
   $customer_id = Mage::getSingleton('customer/session')->getCustomerId();

   /*Do whatever you need to get the custom discount for this client
   ---
   */

   $discount = 0.3;

   $event = $observer->getEvent();
   $product = $event->getProduct();
   $product->original_price = $product->getPrice();

   $final_price = $product->original_price * (1 - $discount);

   $product->setFinalPrice($final_price);

   return $this;
  }
 }
}
?>

What now?

Now that we know how to set the a special price manually, there are going to be a lot of conditions to take into the account depending on our website. In my case, we only apply a special price for registered clients that have been assigned an special id (different than the magento client id).

Note that this change is being applied only on the product page, not on the product list. This is because, in my case, we have to get the price from an Oracle DB that takes its time to return the result. If it’s only a single product, then it’s OK, but if we need to get more results, it takes longer.

There are also other things to take into the account: is this the best way to change the price on the product price? How about changing the price directly and not setting a Ā«special priceĀ»? I’ll find out and write about it (here or in a new post).

This works in Magento CE and EE