Глава 9. Создание модуля доставки

[10 ноября 2016 г.]    Российская сборка Magento 2.49.12
Magento 2: модули и услуги
#1 Надежда А
  • Иконка
  • Группа: Администратор
  • Сообщений: 50
  • Регистрация: 12.12.2010

29.03.2011 13:18

В этой главе мы рассмотрим:
  • Инициализацию конфигурации модуля

  • Написание модели адаптера

  • Добавление модуля в бэкэнд

  • Добавление модуля в интерфейс



Введение

Доставка товара по назначению клиента является одной из жизненно важных частей транзакции (сделки) электронной торговли. По умолчанию Magento предоставляет следующих перевозчиков:
  • UPS

  • USPS

  • FedEx

  • DHL

Если нам нужно добавить дополнительного перевозчика, то все, что нам нужно, - это создать новый модуль доставки. Эта глава проведет вас через создание клиентского модуля доставки вашего собственного, который добавит дополнительные настройки в Magento административную часть для указания Почтовой службы Канады в качестве перевозчика доставки.


Инициализация конфигурации модуля

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


Подготовка

Запустите ваш редактор PHP и откройте проект Magento.


Как это сделать…

1. Создайте новую папку с именем Packt в каталоге app/code/local.
2. Создайте новую папку с именем "Myshipping" (разумеется, без кавычек) в app/code/local/Packt/.
3. Создайте еще две директории (каталога) внутри директории Myshipping и назовите их как
Model и etc соответственно. Окончательный результат должен быть следующим:
Прикрепленное изображение: 1.png

4. Давайте создадим файл config.xml в каталоге app/code/local/Packt/Myshipping/etc и вставим следующий код в него:
<?xml version="1.0"?>
<config>
<modules>
<Packt_Myshipping>
<version>1.0.0</version>
<depends>
<Mage_Shipping />
</depends>
</Packt_Myshipping>
</modules>
<global>
<models>
<myshipping>
<class>Packt_Myshipping_Model</class>
</myshipping>
</models>
<resources>
<myshipping_setup>
<setup>
<module>Packt_Myshipping</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</myshipping_setup>
</resources>
</global>
<default>
<carriers>
<myshipping>
<active>1</active>
<model>myshipping/carrier</model>
</myshipping>
</carriers>
</default>
</config>

5. Сохраните и закройте файл config.xml.
6. Нам нужен другой файл XML под названием System.xml в папке app/code/local/Packt/Myshipping/etc/. Создайте его!
7. Файл System.xml получил длинный фрагменты кода. Для нашего лучшего понимания мы должны разделить блоки кода, чтобы описать его, в то время как полный модуль в комплекте с этой книгой. Вы можете скачать его с www.packtpub.com.
8. Следующий блок кода имеет дело с конфигурациями модуля Myshipping, такими как лейбл в панели администратора, порядок сортировки и видимость в различных магазинах и сайтах.
<?xml version="1.0"?>
<config>
<sections>
<carriers>
<groups>
<myshipping translate="label" module="shipping">
<label>Canada Post</label>
<frontend_type>text</frontend_type>
<sort_order>13</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>

9. Блок fields содержит конфигурации всех полей, которые отображаются в админ-панели. Все поля содержат некоторую похожую информацию, такую как лейбл, тип интерфейса, порядок сортировки, видимость по умолчанию, видимость на веб-сайте и видимость в магазине.
<fields>
<account translate="label">
<label>Account number</label>
<frontend_type>text</frontend_type>
<sort_order>7</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</account>
<active translate="label">
<label>Enabled</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno
</source_model>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</active>
<contentdesc translate="label">
<label>Package Description</label>
<frontend_type>text</frontend_type>
<sort_order>12</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</contentdesc>

10. Если free_shipping_enable флаг включен, то система будет проверять free_shipping_subtotal, чтобы дать детали бесплатной доставки или же она будет использовать режим Shopping Cart Price Rule (ценовые правила корзины).
<free_shipping_enable translate="label">
<label>Free shipping with minimum order
amount</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_
enabledisable</source_model>
<sort_order>21</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</free_shipping_enable>

<free_shipping_subtotal translate="label">
<label>Minimum order amount for free
shipping</label>
<frontend_type>text</frontend_type>
<sort_order>22</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</free_shipping_subtotal>

<dutiable translate="label">
<label>Shipment Dutiable</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno
</source_model>
<sort_order>13</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</dutiable>

<gateway_url translate="label">
<label>Gateway URL</label>
<frontend_type>text</frontend_type>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</gateway_url>

<handling_type translate="label">
<label>Calculate Handling Fee</label>
<frontend_type>select</frontend_type>
<source_model>shipping/source_handlingType
</source_model>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</handling_type>

<handling_action translate="label">
<label>Handling Applied</label>
<frontend_type>select</frontend_type>
<source_model>shipping/source_handlingAction
</source_model>
<sort_order>11</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</handling_action>

<handling_fee translate="label">
<label>Handling fee</label>
<frontend_type>text</frontend_type>
<sort_order>12</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</handling_fee>

<max_package_weight translate="label">
<label>Maximum Package Weight (Please consult your
shipping carrier for maximum supported shipping
weight)</label>
<frontend_type>text</frontend_type>
<sort_order>13</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</max_package_weight>

<id translate="label">
<label>Access ID</label>
<frontend_type>text</frontend_type>
<backend_model>adminhtml/system_config_backend_
encrypted</backend_model>
<sort_order>5</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</id>

<password translate="label">
<label>Password</label>
<frontend_type>text</frontend_type>
<backend_model>adminhtml/system_config_backend_
encrypted</backend_model>
<sort_order>6</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</password>

<shipping_intlkey translate="label">
<label>Shipping key (International)</label>
<frontend_type>text</frontend_type>
<backend_model>adminhtml/system_config_backend_
encrypted</backend_model>
<sort_order>8</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</shipping_intlkey>

<shipping_key translate="label">
<label>Shipping key</label>
<frontend_type>text</frontend_type>
<backend_model>adminhtml/system_config_
backend_encrypted</backend_model>
<sort_order>8</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</shipping_key>

<sort_order translate="label">
<label>Sort order</label>
<frontend_type>text</frontend_type>
<sort_order>100</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</sort_order>

<title translate="label">
<label>Title</label>
<frontend_type>text</frontend_type>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</title>

<sallowspecific translate="label">
<label>Ship to applicable countries</label>
<frontend_type>select</frontend_type>
<sort_order>90</sort_order>
<frontend_class>shipping-applicablecountry</
frontend_class>
<source_model>adminhtml/system_config_source_
shipping_allspecificcountries</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</sallowspecific>

<specificcountry translate="label">
<label>Ship to Specific countries</label>
<frontend_type>multiselect</frontend_type>
<sort_order>91</sort_order>
<source_model>adminhtml/system_config_source_country
</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</specificcountry>

<showmethod translate="label">
<label>Show method if not applicable</label>
<frontend_type>select</frontend_type>
<sort_order>92</sort_order>
<source_model>adminhtml/system_config_source_yesno
</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</showmethod>

<specificerrmsg translate="label">
<label>Displayed Error Message</label>
<frontend_type>textarea</frontend_type>
<sort_order>80</sort_order>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</specificerrmsg>
</fields>
</myshipping>
</groups>
</carriers>
</sections>
</config>
<show_in_default>1</show_in_default>

11. Мы находимся на последнем этапе создания конфигурации для нашего нового модуля доставки. Давайте создадим новый app/etc/modules/Packt_Myshipping и напишем следующий код в нем:
<?xml version="1.0"?>
<config>
<modules>
<Packt_Myshipping>
<active>true</active>
<codePool>local</codePool>
</Packt_Myshipping>
</modules>
</config>

12. Нет шага 12.


Как это работает...

Мы уже знаем, что XML-файлы являются строительными блоками Magento CMS. Для любого модуля Magento файлы конфигурации XML являются обязательными. Таким образом, мы написали два файла конфигурации. Одним из них является config.xml и другой - System.Xml.
XML-файлы довольно самоописуемы. Мы просто следовали конвенциям от Magento, чтобы сделать наш модуль доставки рабочим.
В этом рецепте мы выложили необходимые файлы и папки для конфигурации нашего модуля доставки. Мы создали два XML-файла, config.xml и system.xml. Файл config.xml
содержит информацию о модуле, такую как версия, зависимость от модуля Mage_Shippin и ассоциация модели для этого модуля.
Файл system.xml содержит информацию о носителе, необходимых полях, и оказании (рендеринге) конфигурации для интерфейса администратора (admin UI) во время посещения страницы System | Configuration | Shipping Methods. Поля в аккордеоне Canada post также определены в system.xmlфайле. Имейте в виду, что имя поля будет выбрано из модели адаптера по его имени, как:

$this->getConfigData('handling_fee') in Carrier.php.

Последний файл, который мы создали, Packt_Myshipping.xml, отвечает за преобразование данного модуля в активное состояние в Magento. Этот файл имеет два важных тега: один из них active, а другой codePool. Активный тег имеет значение true, и localдля тега codePool, т.к. это наш собственный модуль.


Написание модели адаптера

Модели управляют всей бизнес-логикой в Magento, как и любое другое приложение MVC. В этом рецепте мы будем писать класс модели адаптера для нашего модуля доставки, который будет распространять Mage_Shipping_Model_Carrier_Abstract класс. Цель этого класса состоит в сборе тарифов для метода доставки, основываясь на информации, содержащейся в запросе.


Как это сделать…

1. Создайте новый файл с именем Carrier.php в каталоге app/code/local/Packt/Myshipping/Model/.
2. Вставьте следующий код:
<?php

class Packt_Myshipping_Model_Carrier extends Mage_Shipping_Model_
Carrier_Abstract
{

/**
* unique identifier for our shipping module
* @var string $_code
*/
protected $_code = 'myshipping';

/**
* Collect rates for this shipping method based on information
in $request
*
* @param Mage_Shipping_Model_Rate_Request $data
* @return Mage_Shipping_Model_Rate_Result
*/
public function collectRates(Mage_Shipping_Model_Rate_Request
$request)
{
if (!$this->getConfigData('active')) {
Mage::log('The ' . $this->_code . 'my shipping module is not
active.');
return false;
}

$handling = $this->getConfigData('handling_fee');
$result = Mage::getModel('shipping/rate_result');
foreach ($request as $method) {
$method = Mage::getModel('shipping/rate_result_method');

$method->setCarrier($this->_code);
$method->setCarrierTitle($this->getConfigData('title'));

$method->setMethod($method['code']);
$method->setMethodTitle($method['title']);

$method->setCost($method['amount']);

$method->setPrice($method['amount'] + $handling);

$result->append($method);
}

return $result;
}

}

3. Сохраните и закройте этот файл.


Как это работает...

Этот класс модели применяет бизнес-правила для метода доставки. В этом классе есть метод под именем collectRates (), который принимает Mage_Shipping_Model_Rate_Request объект в качестве параметра и передает его вдоль метода.
Мы «захватили» конфигурацию и вызвали shipping/rate_result_method модель для выборки необходимых данных и их обработки. Наконец, мы вернули его.
Этот файл имеет важное значение для расчета пошлины за обработку (handling fee) и возвращает ее в форму доставки. Метод collectRates () несет за это ответственность. Мы просто показали вам, как она работает. Пошлина за доставку (shipping handling fee) отличается по различным аспектам; установите ваши собственные поля, как мы делали в system.xmlи примените бизнес-логику в Carrier.php, это как она должна работать.


Добавление модуля в бэкэнд

В этом рецепте мы включим наш вновь созданный модуль доставки.


Как это сделать…

1. Войдите в бэкэнд вашего магазина Magento.
2. Укажите ваш браузер на System| Configuration Advanced| Advanced page.
3. Посмотрите на наш вновь созданный модуль с именем Packt_Myshipping и убедитесь, что он включен.
4. Теперь перейдите на страницу System | Configuration | Sales | Shipping methods. Найдите лейбл Canada Post, т.к. мы ввели его в нашем предыдущем рецепте.
5. Введите необходимые данные в форму, как это предлагается.
6. Ниже приведен пример скриншота:

Прикрепленное изображение: 2.png

7. Убедитесь, что вы установили его включенным.
8. Пожалуйста, обратитесь к поставщику доставки, чтобы убедиться, что конфигурации являются правильными. Сохранить конфигурацию.


Как это работает...

Мы сделали этот модуль, как и любой другой стандартный модуль доставки, например, UPS, USPS, FedEx и другие. Параметры любого стандартного метода доставки могут быть приняты здесь, и основной метод доставки Magento будет заботиться об этом.


Добавление модуля в интерфейс

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


Как это сделать…

Мы действительно должны сделать это в Magento бэкэнде. Тем не менее в нашем предыдущем рецепте мы описали его. Вот простой пример, как это сделать:
1. Войдите в ваш Magento бэкэнд / админ-панель.
2. Перейдите на страницы System | Configuration | Sales | Shipping Methods.
3. Введите соответствующую информацию в разделе Canada Post.
4. Сохраните эту конфигурацию.
5. Вернитесь к внешнему интерфейсу (frontend) и посмотрите его в действии при посещении страницы Checkout!
Прикрепленное изображение: 3.png


Как это работает...

Мы добавили соответствующую информацию в system.xml и применили логики в Carrier.php в предыдущем рецепте; он будет обрабатывать рабочий процесс (последовательность выполняемых действий) для интерфейса.


Смотрите также...

Вы можете также обратиться к рецепту Adding a module этой главы.

#2 selepok
  • Группа: Пользователь
  • Сообщений: 62
  • Регистрация: 13.10.2011

29.02.2012 15:05

Сделал все как в уроке. Даже скачал example с
http://www.packtpub.com/
. В админке работает, а в фронтэнде не переходит к шагу выбора метода доставки. В FireBug "Ответ" на POST
http://mysite/checkout/onepage/saveBilling
видает ошибку:

<br />
<b>Fatal error</b>:  Call to a member function setStore() on a non-object in <b>http://mysite\app\code\core\Mage\Shipping\Model\Shipping.php</b> on line <b>247</b><br />


Версия Magento 1.6.1.0. В чем может быть проблема? Спасибо.

#3 Дмитрий Федюк
  • Администратор
  • Иконка
  • Группа: Администратор
  • Сообщений: 8884
  • Регистрация: 20.02.2010

29.02.2012 15:33

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

Поделиться темой: