I'm trying to override the Multishipping class to separate the orders (but keep payment a one step process), except I don't want the orders to be separated by item but by the custom attribute "vendor." "Vendor" is an attribute that we added to the system that is applicable for all simple products. So say in the cart there is a pink shirt with "vendor" value "1", a pencil with "vendor" value "1", and a blue shirt with "vendor" value "2". All items with "vendor" value "1" need to be one order, while the item with "vendor" value "2" need to be a different order.

I've been looking at the methods in the Mage_Checkout_Model_Type_Multishipping class and it seems like the items are separated out in the getQuoteShippingAddressesItems method below. Am I right? How could I implement separating them by an attribute value instead of by each item?

 * Get quote items assigned to different quote addresses populated per item qty.
 * Based on result array we can display each item separately
 * @return array
public function getQuoteShippingAddressesItems()
    if ($this->_quoteShippingAddressesItems !== null) {
        return $this->_quoteShippingAddressesItems;
        //Mage::log('In getQuoteShippingAddressesItems the "this->_quoteShippingAddressesItems" array is');
        //Mage::log(print_r($this->_quoteShippingAddressesItems, true));
    $items = array();
    $addresses = $this->getQuote()->getAllAddresses();

    foreach ($addresses as $address) {
        //Mage::log($address->debug()); //each customer address
        foreach ($address->getAllItems() as $item) {
            //Mage::log($item->debug()); //each quotable item
            if ($item->getParentItemId()) {
            if ($item->getProduct()->getIsVirtual()) {
                $items[] = $item;
            if ($item->getQty() > 1) {
                for ($i = 0, $n = $item->getQty(); $i < $n; $i++) {
                    if ($i == 0) {
                        $addressItem = $item;
                    } else {
                        $addressItem = clone $item;
                    $items[] = $addressItem;
            } else {
                $items[] = $item;
            //Mage::log($items->debug()); //wont show
    $this->_quoteShippingAddressesItems = $items;

    return $items;

1 Answer 1


This could be a tough this to do. What the template and other code is looking for is complete quote items, which are normally dealt with as one item links to a single product. That product could be a bundle, virtual or any other type of product.

<?php foreach ($this->getItems() as $_index => $_item): ?>
    <?php if ($_item->getQuoteItem()) :?>
        <td><?php echo $this->getItemHtml($_item->getQuoteItem())?></td>
        <td><input type="text" name="ship[<?php echo $_index ?>][<?php echo $_item->getQuoteItemId() ?>][qty]" value="<?php echo $this->escapeHtml($_item->getQty()) ?>" size="2" class="input-text qty" /></td>
        <td><?php if ($_item->getProduct()->getIsVirtual()): echo $this->__('Shipping selection is not applicable.'); else: echo $this->getAddressesHtmlSelect($_item, $_index); endif; ?></td>
        <td class="a-center"><a href="<?php echo $this->getItemDeleteUrl($_item) ?>" title="<?php echo $this->__('Remove Item') ?>" class="btn-remove2"><?php echo $this->__('Remove Item') ?></a></td>
    <?php endif; ?>
<?php endforeach; ?>

I am not sure it will work if you change getQuoteShippingAddressesItems to split the items by something other than single quote items. It may work on this page and display correctly but you may find that the checkout process later on will be missing some items or unable to display the correct prices.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.