1. бесплатный модуль “Новая почта” с открытым кодом для Magento;
2. статью в нескольких частях с подробным описанием процесса.
Статья ориентирована на новичков в Magento, но, возможно, будет интересна и опытным разработчикам. Все исходники можно найти на GitHub: github.com/alexkuk/Ak_NovaPoshta/, они дополняются по ходу разработки.
Итак, начнем с постановки задачи. Модуль должен выполнять следующие функции:
1. добавить новый метод доставки в Magento;
2. настройки метода должны позволять задавать различную стоимость доставки для различного суммарного веса посылки (как в методе доставки Table Rates);
3. хранить и синхронизировать с Новой Почтой базу складов;
4. выводить склады Новой Почты в удобном для выбора виде на шаге Shipping Method оформления заказа, по умолчанию выводить только склады в городе пользователя;
5. добавить возможность отслеживания посылки в панель пользователя.
В последнее время API Новой почты также позволяет создавать и распечатывать ТТН, но, с вашего позволения, эту функциональность я оставлю на потом. Кроме того, касательно пункта 2, API также предоставляет средства для расчета стоимости доставки. Пока я предпочту более простой и стабильный вариант, который позволит владельцу магазина самостоятельно определять стоимость доставки в зависимости от суммарного веса заказа. Это связано с тем, что продавцу не всегда удается точно определить вес каждого товара, и стоимость доставки, выставленная через API может играть не на пользу продавца. Оставим расчет стоимости через API на потом.
Добавим новый метод доставки
Итак, создадим новый модуль и добавим новый метод доставки. Я буду работать с Magento CE 1.7.0.2. Модуль назовем Ak_NovaPoshta. Про структуру модулей в Magento написано уже немало статей, так что этот момент я опущу.
Стоит отметить, что Magento оперирует двумя сущностями, когда мы говорим о способе доставки, — это shipping carrier (перевозчик) и shipping methods (методы доставки, которые предоставляются перевозчиком). В нашем случае перевозчик — Новая Почта, в качестве методов мы будем использовать склады Новой Почты.
Чтобы добавить carrier, необходимо сделать три вещи:
1. добавить поля настроек нашего перевозчика в system.xml модуля;
2. добавить значения настроек по-умолчанию, а также ссылку на класс модели перевозчика, в config.xml модуля:
<config> … <default> <carriers> <novaposhta> <!-- отключен по-умолчанию, чтобы не предлагать недоконфигурированный метод доставки пользователю --> <active>0</active> <!-- флаг, ограничивать ли метод доставки по стране, которая указана в shipping address при оформлении заказа --> <sallowspecific>1</sallowspecific> <!-- ограничим по Украине --> <specificcountry>UA</specificcountry> <!-- ссылка на класс модели перевозчика --> <model>novaposhta/carrier_novaPoshta</model> <!-- название перевозчика --> <title>Новая Почта</title> <!-- сообщение об ошибке --> <specificerrmsg>Этот способ доставки на текущий момент не доступен. Если вы желаете, чтобы мы доставили заказ Новой Почтой, обратитесь к менеджеру интернет-магазина.</specificerrmsg> </novaposhta> </carriers> </default> … </config>
3. добавить класс модели для нашего перевозчика.
Класс модели перевозчика наследуется от Mage_Shipping_Model_Carrier_Abstract и реализует Mage_Shipping_Model_Carrier_Interface. В Mage_Shipping_Model_Carrier_Abstract уже определены некоторые полезные методы, как, например, метод getConfigData($field) для извлечения конфигурационных значений. В своем классе определяем основной метод collectRates(Mage_Shipping_Model_Rate_Request $request), который будет возвращать доступные методы доставки:
public function collectRates(Mage_Shipping_Model_Rate_Request $request) { if (!$this->getConfigFlag('active')) { return false; } /** @var $result Mage_Shipping_Model_Rate_Result */ $result = Mage::getModel('shipping/rate_result'); $shippingPrice = 1.00; // dummy price $warehouseId = 1; // dummy warehouse ID $warehouseName = 'Склад №1'; // dummy warehouse name /** @var $method Mage_Shipping_Model_Rate_Result_Method */ $method = Mage::getModel('shipping/rate_result_method'); $method->setCarrier($this->_code) ->setCarrierTitle($this->getConfigData('name')) ->setMethod('warehouse_' . $warehouseId) ->setMethodTitle($warehouseName) ->setPrice($shippingPrice) ->setCost($shippingPrice); $result->append($method); return $result; }
Пока мы не реализовали синхронизацию складов, будем использовать один метод доставки для примера — Склад №1. Внутри метода collectRates() создаем экземпляр Mage_Shipping_Model_Rate_Result, и с помощью метода Mage_Shipping_Model_Rate_Result::append() добавляем в него экземпляры Mage_Shipping_Model_Rate_Result_Method.
Напоследок перепишем родительский метод isTrackingAvailable:
public function isTrackingAvailable() { return true; }
На этом этапе наш метод доставки уже может использоваться, но, как видите, стоимость доставки всегда будет равна 1.00.
Добавим конфигурирование стоимости доставки
Следующий шаг — добавить конфигурационную опцию для связи суммарного веса заказа и стоимости доставки. В итоге хочется получить такую форму:
Для этого добавим поле weight_price в system.xml нашего модуля:
… <weight_price translate="label"> <label>Shipping price</label> <frontend_model>novaposhta/config_field_weightPrice</frontend_model> <backend_model>adminhtml/system_config_backend_serialized_array</backend_model> <sort_order>110</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> </weight_price> …
Backend model — это модель, которая преобразует значение поля перед сохранением в базу. В данном случае мы будем использовать готовую модель Mage_Adminhtml_Model_System_Config_Backend_Serialized_Array. Frontend model — это вовсе не модель, а блок, отвечающий за представление поля. Мы добавим свой блок Ak_NovaPoshta_Block_Config_Field_WeightPrice:
class Ak_NovaPoshta_Block_Config_Field_WeightPrice extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract { public function __construct() { $this->addColumn('weight', array( 'label' => Mage::helper('novaposhta')->__('Weight upper limit'), 'style' => 'width:120px', )); $this->addColumn('price', array( 'label' => Mage::helper('novaposhta')->__('Price'), 'style' => 'width:120px', )); $this->_addAfter = false; $this->_addButtonLabel = Mage::helper('novaposhta')->__('Add rate'); parent::__construct(); } }
Как видите, абстрактный Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract делает за нас всю работу, нам остается настроить колонки и кнопки.
Поле конфигурации готово, теперь перейдем к его использованию, а именно нахождению стоимости доставки заказа. Для этого добавим следующие методы в класс перевозчика:
/** * @return array */ protected function _getWeightPriceMap() { $weightPriceMap = $this->getConfigData('weight_price'); if (empty($weightPriceMap)) { return array(); } return unserialize($weightPriceMap); } /** * @param $packageWeight * * @return float */ protected function _getDeliveryPriceByWeight($packageWeight) { $weightPriceMap = $this->_getWeightPriceMap(); $resultingPrice = 0.00; if (empty($weightPriceMap)) { return $resultingPrice; } $minimumWeight = 1000000000; foreach ($weightPriceMap as $weightPrice) { if ($packageWeight <= $weightPrice['weight'] && $weightPrice['weight'] <= $minimumWeight) { $minimumWeight = $weightPrice['weight']; $resultingPrice = $weightPrice['price']; } } return $resultingPrice; }
и в методе collectRates заменим
$shippingPrice = 1.00
на более реальное
$shippingPrice = $this->_getDeliveryPriceByWeight($request->getPackageWeight());
Готово
В следующей части займусь синхронизацией базы складов с API Новой Почты. Спасибо за внимание!
ссылка на оригинал статьи http://habrahabr.ru/post/157647/
Добавить комментарий