I haven't checked this in a while, but from what I remember, the guest cart should be automatically merged with the previous cart upon login.
The customer_login
event is observed in the checkout module by the method Mage_Checkout_Model_Observer::loadCustomerQuote
that calls Mage_Checkout_Model_Session::loadCustomerQuote
that looks like this:
public function loadCustomerQuote()
{
if (!Mage::getSingleton('customer/session')->getCustomerId()) {
return $this;
}
Mage::dispatchEvent('load_customer_quote_before', array('checkout_session' => $this));
$customerQuote = Mage::getModel('sales/quote')
->setStoreId(Mage::app()->getStore()->getId())
->loadByCustomer(Mage::getSingleton('customer/session')->getCustomerId());
if ($customerQuote->getId() && $this->getQuoteId() != $customerQuote->getId()) {
if ($this->getQuoteId()) {
$customerQuote->merge($this->getQuote())
->collectTotals()
->save();
}
$this->setQuoteId($customerQuote->getId());
if ($this->_quote) {
$this->_quote->delete();
}
$this->_quote = $customerQuote;
} else {
$this->getQuote()->getBillingAddress();
$this->getQuote()->getShippingAddress();
$this->getQuote()->setCustomer(Mage::getSingleton('customer/session')->getCustomer())
->setTotalsCollectedFlag(false)
->collectTotals()
->save();
}
return $this;
}
Notice the line if ($customerQuote->getId() && $this->getQuoteId() != $customerQuote->getId()) {
. This means that if there is a current quote object different from the customer quote the quotes should be merged $customerQuote->merge($this->getQuote())
.
Check if you don't have any extensions that might interfere with this merging process.
Or you can start debugging in this last method to see why the cart merging does not happen for you.