Пользовательский Перевозчик Доставки Не Отображается Для Метода getCarriers


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

$validCarriers = Mage::getModel('sales/order_shipment_api')->getCarriers($order->getIncrementId());

Я определяю свой пользовательский носитель с помощью следующего xml

<default>
    <carriers>
        <vmr_customrate>
            <active>1</active>
            <model>vmr_shipping/carrier_customrate</model>
            <title>Shipping Options</title>
            <name>Default Rate</name>
        </vmr_customrate>
    </carriers>
</default>

Есть идеи о том, что я могу делать неправильно?

Author: Jeffrey L. Roberts, 2013-02-18

2 answers

Ваш объект доставки перевозчика (Mage::getModel('vmr_shipping/carrier_customrate ');) либо возвращает false для метода isTrackingAvailable, либо не может быть создан. Остальная часть этого сообщения будет отслеживать ваш вызов метода выше и даст вам несколько точек отладки. Этого должно быть достаточно, чтобы решить проблему.

Если мы посмотрим на определение для getCarriers

#File: app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
public function getCarriers($orderIncrementId)
{
    $order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

    /**
      * Check order existing
      */
    if (!$order->getId()) {
        $this->_fault('order_not_exists');
    }

    return $this->_getCarriers($order);
}

И следуйте этому, чтобы _getCarriers

#File: app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
protected function _getCarriers($object)
{
    $carriers = array();
    $carrierInstances = Mage::getSingleton('shipping/config')->getAllCarriers(
        $object->getStoreId()
    );

    $carriers['custom'] = Mage::helper('sales')->__('Custom Value');
    foreach ($carrierInstances as $code => $carrier) {
        if ($carrier->isTrackingAvailable()) {
            $carriers[$code] = $carrier->getConfigData('title');
        }
    }

    return $carriers;
}

Вы можете видеть, как метод API вызывает Mage::getSingleton('shipping/config')->getAllCarriers($store_id);, чтобы получить список объектов-носителей, а затем возвращает только те, где isTrackingAvailable возвращает значение true. Поэтому шаг 1 должен состоять в том, чтобы убедиться, что ваш объект возвращает значение true для этого метода.

Конечно, может случиться так, что getAllCarriers никогда не вернет ваш метод и никогда не сможет его вызвать. Давайте взглянем на этот метод.

#File: app/code/core/Mage/Shipping/Model/Config.php
public function getAllCarriers($store = null)
{
    $carriers = array();
    $config = Mage::getStoreConfig('carriers', $store);
    foreach ($config as $code => $carrierConfig) {
        $model = $this->_getCarrier($code, $carrierConfig, $store);
        if ($model) {
            $carriers[$code] = $model;
        }
    }
    return $carriers;
}

Таким образом, это проходит через все узлы конфигурации верхнего уровня carriers. Похоже, что у вас все настроено правильно, но добавление

var_dump($code);
Mage::log($code);

К вышеупомянутому циклу и поиск vmr_customrate не повредит. Если вы перейдете к этому классу _getCarrier метод.

#File: app/code/core/Mage/Shipping/Model/Config.php
protected function _getCarrier($code, $config, $store = null)
{
    if (!isset($config['model'])) {
        return false;
    }
    $modelName = $config['model'];

    /**
     * Added protection from not existing models usage.
     * Related with module uninstall process
     */
    try {
        $carrier = Mage::getModel($modelName);
    } catch (Exception $e) {
        Mage::logException($e);
        return false;
    }
    $carrier->setId($code)->setStore($store);
    self::$_carriers[$code] = $carrier;
    return self::$_carriers[$code];
}

Вы увидите, что экземпляр носителя создается путем получения значения из узла <model/> и использования его в вызове getModel

$carrier = Mage::getModel('vmr_shipping/carrier_customrate');

Возможно, по какой-то причине Magento не может создать экземпляр вашей модели. Проверьте журнал исключений или попробуйте создать экземпляр модели самостоятельно в отдельном сценарии/действии контроллера.

 7
Author: Alan Storm, 2013-02-18 20:08:04

На всякий случай, если кто-нибудь получит раскрывающийся список носителей с пустым полем...

Помимо добавления

public function isTrackingAvailable()
    {
        return true;
    }

Для вашей модели убедитесь, что вы также объявили защищенный $_code = '{carrier_code}';

Значение там должно быть равно тому, что вы объявили в своем модуле config.xml в разделе

<default>
   <carriers>
       <{carrier_code}>
           ...
          <title>{carrier_title}</title>
           ...
       </{carrier_code}>
   </carriers>
</default>
 1
Author: diazwatson, 2015-01-25 01:22:06