Где Magento устанавливает цену цены предложения?

Всякий раз, когда вы загружаете страницу корзины в Magento, выполняется следующий код

$cart->init();
$cart->save(); 

Одним из побочных эффектов этого является то, что цены на любые товары в корзине обновляются, если цена продукта обновлена. Это фактически обновляет запись в sales_flat_quote_item. Я пытаюсь отследить, где в коде цена обновляется по каждому элементу предложения, и где сохраняется каждый элемент цитаты.

Я знаю, где расположены мириды, в которых он может. Я надеюсь, кто-то знает, где он на самом деле установлен. Magento 1.7x специально, хотя информация из всех версий приветствуется.

Ответ 1

С высокого уровня код, который запускает весь процесс, это строки 464 и 465 Mage_Checkout_Model_Cart:

 $this->getQuote()->collectTotals();
 $this->getQuote()->save();

Цена нового продукта устанавливается против цитаты в Mage_Sales_Model_Quote_Address_Total_Subtotal в методе _initItem. Вы увидите $item->setPrice в инструкции if/else, начиная с строки 104

Ответ 2

Выкопал это сам. Итак, это

#File: app/code/core/Mage/Sales/Model/Quote.php
foreach ($this->getAllAddresses() as $address) {
    ...
    $address->collectTotals();
    ...
}    

что приводит к этому

#File: app/code/core/Mage/Sales/Model/Quote/Address.php
public function collectTotals()
{
    Mage::dispatchEvent($this->_eventPrefix . '_collect_totals_before', array($this->_eventObject => $this));
    foreach ($this->getTotalCollector()->getCollectors() as $model) {
        $model->collect($this);            
    }
    Mage::dispatchEvent($this->_eventPrefix . '_collect_totals_after', array($this->_eventObject => $this));
    return $this;
}

Объект getTotalCollector возвращает объект sales/quote_address_total_collector, который загружает серию моделей коллектора из global/sales/quote/totals и вызывает на них collect. Метод сумматора общего коллектора collect в конечном итоге вызывает это

#File: app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
protected function _initItem($address, $item)
{
    //...
    if ($quoteItem->getParentItem() && $quoteItem->isChildrenCalculated()) {
        $finalPrice = $quoteItem->getParentItem()->getProduct()->getPriceModel()->getChildFinalPrice(
           $quoteItem->getParentItem()->getProduct(),
           $quoteItem->getParentItem()->getQty(),
           $quoteItem->getProduct(),
           $quoteItem->getQty()
        );
        $item->setPrice($finalPrice)
            ->setBaseOriginalPrice($finalPrice);
        $item->calcRowTotal();
    } else if (!$quoteItem->getParentItem()) {
        $finalPrice = $product->getFinalPrice($quoteItem->getQty());
        $item->setPrice($finalPrice)
            ->setBaseOriginalPrice($finalPrice);
        $item->calcRowTotal();
        $this->_addAmount($item->getRowTotal());
        $this->_addBaseAmount($item->getBaseRowTotal());
        $address->setTotalQty($address->getTotalQty() + $item->getQty());
    }    
    //...
}

и именно здесь элемент котировки получает цену/отдых.

Ответ 3

Я не знаю, поможет ли это вам так много, но если вы пытаетесь выполнить пользовательские изменения цен на продукты в корзине, а не расширять и изменять основные классы, я использую наблюдателя sales_quote_save_before. Он отлично работает, если вы пытаетесь настроить цены (особенно когда у меня есть продукты, которые могут быть настраиваемой длиной). У меня есть примеры кода, если вы хотите их.

Но я говорю с The Alan Storm здесь, поэтому вы можете смеяться над моим слишком упрощенным ответом.