0

Is it possible to get a product's final cart price? The products in the store I'm working on calculate pricing in a myriad of different ways, and rather than try to replicate the logic that decides which pricing method it uses, I thought it would be easier to just pretend the product was in the cart and use that price.

I know about $product->getFinalPrice(), but that's just one of the methods already being used on the site to display the price on the page. I'm hoping there exists a way to simulate a product already being in the cart, whether that's by creating a second, temporary cart to add it to, or some function I haven't yet found.

I already tried adding a product to the cart, getting the price, then removing it, but couldn't get $cart->removeItem($itemId) to work properly. Plus, that seems like a sloppy, unstable way to do that - I don't want to actually mess with the visitor's cart if I can help it.

0

I'm assuming you ask this because you want the benefit of all the sales rules which can be applied, inluding coupon codes and third-party logic that might come into play.

I have not exactly tried this before (except to test for this answer), but it makes sense to me that you would clone the visitor's quote, purge all items except the target, and recollect totals.

A solution might look like this:

require_once '/path/to/app/Mage.php';
Mage::app()->setCurrentStore(1);

$quote  = Mage::getSingleton('checkout/cart')->getQuote();
// Or load a specific model
//$quote  = Mage::getModel('sales/quote')->load(35);

$clone  = clone $quote;
$target = $clone->getItemsCollection()->getItemByColumnValue('product_id', 1);
// Or mock an item from another product in the catalog
//$product = Mage::getModel('catalog/product')->load(258);
//$target  = new Varien_Object(array('product' => $product, 'buy_request' => '1'));

$clone->getBillingAddress();
$clone->getShippingAddress()
    ->unsCachedItemsNominal()
    ->unsCachedItemsNonnominal()
    ->unsCachedItemsAll();

$clone->unsEntityId()
    ->removeAllItems()
    ->unsItemsCollection()
    ->setIsSuperMode(true);

$target->isDeleted(false);

$result = $clone->addProduct($target->getProduct(), $target->getBuyRequest());

$clone->setTotalsCollectedFlag(false)
    ->collectTotals();

foreach ($clone->getAllVisibleItems() as $item) {
    var_dump(
        "{$item->getSku()} x {$item->getQty()} = $" . ($item->getRowTotal() - $item->getDiscountAmount())
    );
}

var_dump($clone->getGrandTotal());

I won't do too much to unpack this, as it seems like you're already advanced enough to trace these lines back into the core for details.

What I will give you are some general comments:

  • Goal is to clone current quote but sever all ties to DB representation
  • We clear all items and add the desired/replace one existing
  • We do any housekeeping required to reset quote state for totals collection
  • We check our item totals (note use of row_total and discount_amount)
  • Yes, that did it! I never knew about PHP's clone, and even if I did, I wouldn't have thought to sever the cloned quote's ties to the database. Thank you so much, I've been banging my head against this for days! – A Decker Sep 7 '17 at 20:24
  • Glad it helped! Welcome to the community. – Rick Buczynski Sep 7 '17 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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