Double Order Totals in Magento

I’ve been having a problem in magento for a small number of customers where the order total is double what it should be – although everything looks correct in the basket. I haven’t been able to find the underlying cause, but hopefully have found a link to a fix which might help others having the same problem.

The fix is on this website here:
http://www.magentocommerce.com/boards/viewthread/227560/

The problem seems to be that magento is creating duplicate entries for a quote in the table: sales_flat_quote_address

It’s obviously not a very clean fix, but adding code to:
Mage\Checkout\Model\Cart.php

in the init() function after line: $this->getQuote()->setCheckoutMethod(”);


$addresses = $this->getQuote()->getAllAddresses();
				
if (count($addresses) > 2) {
  for($i = 2; $i < count($addresses); $i++) {
    $address = $addresses[$i];
    $address->isDeleted(true);
  }
}

The verdict is out so far, but hopefully that should do the trick.

If you are allowing multiple shipping addresses for an order, this probably won’t work for you.

Like a “review” in Magento

Today I’ve created a “review” liking module in Magento so customers can read the reviews of a product and like (or dislike) any which they find useful. I based it on some code I found here:

http://sapnandu-magento.blogspot.co.uk/2012/06/create-review-like-module-in-magento.html#comment-form

I found the code a great place to start from, but found some problems with the login links, and I’m not sure how the data was being stored because it seemed to not have a 1 to 1 relationship between the review_like table and a particular review, but we’re interested in the total number of likes or dislikes. So I adapted things somewhat and seems to work great now.

I particularly like it because I’ve got the sorting on the review to show the most useful one first, and then it goes by most recent which I think will be very helpful for customers.

Creating Magento Free Post Promotion Coupons through code

I’ve getting increasing numbers of promotions to set-up in Magento, so I decided it was time to write a script so I can get them added more quickly.

I found some good code here, and decided to adapt it to suit my needs.

This script will generate a free postage code, with start and expiry date but could be easily adapted to offer discounts. It turned a 30 min job into a 5 min one. I’ll eventually write something in VBA so I can generate the data in excel and then just push the button to update the website with new promotions.


#Free Post Coupon Generation
#2013-05-29
#David Boyce

define('MAGENTO', realpath('/srv/www/htdocs/Catalogue'));
ini_set('memory_limit', '128M');

require_once MAGENTO . '/app/Mage.php';

Mage::app();

#Free Post
$code = "[PROMOTIONCOUPONCODE]";
$label = "[PROMOTIONLABEL]";
$amount = 0;
$freeShipping = 1;
$from_date = "2013-05-29";
$to_date = "2013-07-01";

generateRule( $code, $amount, $label, $from_date, $to_date, $name, $freeShipping);

function generateRule($code, $amount, $label, $from_date, $to_date, $name = '', $freeShipping){

  $name = (empty($name))? $label : $name;
  $labels[0] = $label;//default store label

  $coupon = Mage::getModel('salesrule/rule');
  $coupon->setName($name)
  ->setDescription($name)
  ->setFromDate($from_date)
  ->setToDate($to_date)
  ->setCouponCode($code)
  ->setUsesPerCoupon('')
  ->setUsesPerCustomer('')
  ->setCustomerGroupIds(getAllCustomerGroups()) //an array of customer group ids
  ->setIsActive(1)

  //serialized conditions.  the following examples are empty
  ->setConditionsSerialized('a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
  ->setActionsSerialized('a:6:{s:4:"type";s:40:"salesrule/rule_condition_product_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')

  ->setStopRulesProcessing(0)
  ->setIsAdvanced(1)
  ->setProductIds('')
  ->setSortOrder(0)
  ->setSimpleAction('cart_fixed')
  ->setDiscountAmount($amount)
  ->setDiscountQty(null)
  ->setDiscountStep('0')
  ->setSimpleFreeShipping($freeShipping)
  ->setApplyToShipping('0')
  ->setIsRss(0)
  ->setWebsiteIds(getAllWbsites())
  ->setCouponType(2)
  ->setStoreLabels($labels)
  ;

  $coupon->save();

}


function getAllCustomerGroups(){
  //get all customer groups
  $customerGroupsCollection = Mage::getModel('customer/group')->getCollection();
  $customerGroupsCollection->addFieldToFilter('customer_group_code',array('nlike'=>'%auto%'));
  $groups = array();
  foreach ($customerGroupsCollection as $group){
    $groups[] = $group->getId();
  }
  return $groups;
}

function getAllWbsites(){
  //get all wabsites
  $websites = Mage::getModel('core/website')->getCollection();
  $websiteIds = array();
  foreach ($websites as $website){
    $websiteIds[] = $website->getId();
  }
  return $websiteIds;
}

Updating Magento Order Status through an API call

I’ve written an integration between our backoffice system and magento – to update the status of orders in Magento.

I used the Microsoft MSXML2.ServerXMLHTTP object to send a post to the website – it’s basically requesting a URL and passing some parameters on the query string (ie order number, status etc).

The url might be something like:
http://www.mywebsite.co.uk/updateOrderStatus.php?orderId=[orderid]&orderStatus=[orderstatus]

On the server a php script at the URL requested handles the request and updates the order status – a very simple solution with no checks might be…
updateOrderStatus.php:

$mage_url = 'http://www.mywebsite.co.uk/api?wsdl';
$mage_user = 'apiuser';
$mage_api_key = 'apipassword';

// Initialize the SOAP client
$proxy = new SoapClient( $mage_url );

// Login to Magento
$session_id = $proxy->login( $mage_user, $mage_api_key );

//Get Parameters
$thisOrderId = $_GET['orderId'];
$thisStatus = $_GET['orderStatus'];

//Update Status
$proxy->call($session_id, 'sales_order.addComment', array($thisOrderId,$thisOrderStatus,'Updated through API', false));

Magento Category Caching

The website I administer has lots of configurable products, with many colour/size variations.  The category page load speed had been very slow, and I’d been looking to work on the caching for some time.  I put block caching in using the tutorial here on the product list and it’s made a remarkable difference, with categories loading in 1-2 seconds from a time of 10-12 seconds (worse categories).  I added the block cache to this code:

/app/code/core/Mage/Catalog/Block/Product/List.php

protected function _construct() {
  $this->addData(array('cache_lifetime' => 99999999, ));
}

public function getCacheTags()
{
  return array(Mage_Catalog_Model_Product::CACHE_TAG);
}

public function getCacheKey()
{
  $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
  return $this->getRequest()->getRequestUri();
}

I hope it helps others to speed up their sites too – ps you probably shouldn’t follow my bad example and update the core file, but the one in the local directory.