Magento: пользовательские итоги учитываются дважды?

Хорошо, я создал собственный класс Total для добавления специальной скидки, и все, кажется, работает нормально, за исключением того, что по какой-то причине я не могу найти, что моя сумма рассчитывается дважды! Это приводит к двойной сумме скидки и неправильной общей сумме. Теперь это происходит на странице корзины и на страницах оформления заказа ... НО ... когда я завершаю заказ, общая сумма в порядке, рассчитывается только один раз, и общая сумма в порядке.

Странно, как будто метод collect вызывается два раза для страниц корзины, но только один раз при завершении заказа, но я не могу отследить, где все это происходит и почему.

Чтобы пропустить ненужный код, я буду вставлять только важные

     <sales>
        <quote>
            <totals>
                <mydiscount>
                    <class>ucon_mydiscount/total_mydiscount</class>
                    <before>subtotal</before>
                </mydiscount>
            </totals>
        </quote>
    </sales>

и коллекционные методы

    public function collect(Mage_Sales_Model_Quote_Address $address)
{
    parent::collect($address);

    $quote = $address->getQuote();
    $quoteId = $quote->getEntityId();

    $items = $quote->getAllItems();
    if (!count($items)) {
        return $this;
    }       


    $discount = 0;
    $productId = 2556;  

    foreach($items as $item)
    {       
        if($item->getProduct()->getId() == $productId)
        {
            $qty = $item->getQty();
            $totalPrice = round(($item->getRowTotal()+$item->getTaxAmount()),2);

            //discount 10%              
            $discount = round($totalPrice * 0.1,2);     

            $discount = 0 - $discount;
        }
    }

    if($discount == 0)
        return $this;

    $this->_setAmount($discount);
    $this->_setBaseAmount($discount);


    return $this;
}

и сборщик

    public function fetch(Mage_Sales_Model_Quote_Address $address)
{
    $amount = $address->getMydiscountAmount();
    if ($amount != 0) {
        $title = Mage::helper('ucon_mydiscount')->__('My discount');
        $address->addTotal(array(
            'code' => $this->getCode(),
            'title' => $title,
            'value' => $amount
        ));
    }
    return $this;
}

редактировать: еще одна вещь, которую я нахожу очень странной - я делаю setValue в своем методе сбора, а не addValue, поэтому, даже если метод вызывается дважды, он не должен быть двойным значением, он должен просто дважды установить его в значение правильное значение.


person Relja    schedule 24.11.2011    source источник
comment
Я использовал комментарий Андрея в качестве отправной точки из здесь   -  person Relja    schedule 24.11.2011
comment
Я испытал это один раз, но теперь не могу найти, что я сделал, чтобы это исправить. Я полагаю, что скопировал один из классов магов, который явно проверял, не использовалась ли уже общая сумма. Попробуйте добавить точки останова или Mage::log(__METHOD__) в каждую из функций сбора и выборки, чтобы увидеть, что вызывается дважды - именно так я отлаживал это в прошлый раз.   -  person clockworkgeek    schedule 04.12.2011


Ответы (3)


Может ли проблема заключаться в том, что общий объект принадлежит объекту адреса, а заказы Magento обычно имеют ДВА адреса — один для доставки и один для выставления счетов?

Таким образом, общая сумма будет вызываться дважды: один раз с платежным адресом и один раз с адресом доставки, и сумма суммируется для каждого адреса. Вы можете попробовать проверить, какой адрес вы получили, и применить значение только к одному из них, как это;

public function collect(Mage_Sales_Model_Quote_Address $address) {

  $this->_setAddress($address);
  $this->_setAmount(0);
  $this->_setBaseAmount(0);

  if ($address->getAddressType() == 'shipping') { 
    //only apply an actual value to the shipping address

    //... Do your calculation here as above ...

  } 

  return $this;
}

Вам также придется сделать что-то подобное в методе выборки...

public function fetch(Mage_Sales_Model_Quote_Address $address) {

  $amount = $address->getMydiscountAmount();

  if ($amount != 0 && $address->getAddressType() == 'shipping') {

    $title = Mage::helper('ucon_mydiscount')->__('My discount');

    $address->addTotal(array(
        'code' => $this->getCode(),
        'title' => $title,
        'value' => $amount
    ));

  }

  return $this;
}

Я допускаю, что функция collect могла бы быть красивее, но, надеюсь, вы все равно поняли идею.

Попробуйте это и посмотрите, правильно ли складываются ваши итоги в интерфейсе и в административной области.

person Russ Wilde    schedule 03.12.2011
comment
не могу поверить, что за ***** спасибо, за миллион лет не нашел бы :) - person Relja; 13.12.2011
comment
Привет, я добавил if ($address->getAddressType() == 'shipping') { , общая сумма указана правильно на странице оформления заказа. Но неправильно после завершения заказа, кажется, моя пользовательская сумма не засчитывается. Кто-нибудь знает, что не так? - person Wakanina; 06.10.2014
comment
@Wakanina Я никогда не превращал общую сумму внешнего интерфейса, подобную этой, в общую сумму внутренней части; Мне нужно было преобразовать общую сумму в дополнительные продукты в серверной части, что я и сделал с наблюдателем события checkout_type_onepage_save_order, который собирал общую сумму, как это происходит, и добавлял продукты с этой стоимостью в заказ. Похоже, этот блог находится на правильном пути: classyllama.com/ блог/ - person Russ Wilde; 06.10.2014
comment
Да, я тоже следовал этому уроку. Я добавил свой ответ... спасибо :) - person Wakanina; 06.10.2014

После поиска, вот еще одно решение

public function collect(Mage_Sales_Model_Quote_Address $address) {
    parent::collect($address);

    //Pay attention to this code
    $items = $this->_getAddressItems($address);
    if (!count($items)) {
        return $this; //this makes only address type shipping to come through
    }

    //Do whatever you want here to add discount or fee...

    return $this;
}

При этом скидка или плата будут добавлены только к адресу доставки и будут учитываться один раз. Так что нам даже не нужно добавлять if ($address->getAddressType() == 'shipping') { в функцию fetch.

person Wakanina    schedule 06.10.2014

Возможно ли, что вы добавляете свой собственный XML-код макета для блока корзины? Если это так, есть большая вероятность, что блок вызывается дважды (один раз из базового кода и еще раз для вашего кода, даже если вы просто расширяете его), таким образом дублируя общую стоимость. Если это так, вам нужно будет удалить (деструктивно с помощью тега <remove>) XML-код базового макета для этого блока, и тогда все должно стать на свои места и работать.

person Mark Shust at M.academy    schedule 25.11.2011
comment
К сожалению, это не так. У меня есть два блока корзины в моих макетах: один для обычной страницы корзины и один для корзины/боковой панели. Но я попытался отключить все свои собственные макеты и использовать только базовые макеты, и проблема все еще существует. Возможно, есть способ увидеть, из каких методов/блоков вызывается мой метод сбора? Спасибо за ответ. - person Relja; 25.11.2011